Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не правильно записывает движения по регистру накопления
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 8.2 > Программирование обычных форм 1С 8.2 и не интерфейсной логики
Yevhenii
1С Предприятие 8.2 обычное приложение, обычная форма
Конфигурация "Управление торговым предприятием для Украины", редакция 1.2.

День добрый, уважаемые.

решаю следующую задачу: есть документ "ПродажаМатериала" коим собственно и продается материал. Есть документ "Оплата" который может оплатить как конкретный документ продажи
так и произвольно внести оплату.
Часть которая оплачивает конкретный документ работает нормально.
А вот часть по произвольно оплате не очень.
Алгоритм следующий: Делаю выборку документов продажи по выбранному контрагенту и с реквизитом Оплата=Ложь (т.е. все не оплаченые документы по этому контрагенту).
беру сумму к оплате (СуммаОплатыТмп) и сумму к оплате по выбранному документу из выборки (СуммаПоДокПродажи) и определю сколько "отрезать" для оплаты текущего документа(ВсяСуммаКОплате-СуммаУжеОплочено), если сумма к оплате больше то оплачиваю документ "в ноль" и ставлю реквизит Оплата=Истина и минусую первоначальную сумму на сумму оплаты (СуммаОплатыТмп=СуммаОплатыТмп-ПлатимТЕМП;) или если не хватает закрыть "в ноль" то оплачиваю на ту сумму что имею и оставляю Оплата=Ложь
все это дело пишу в регистр но в итоге получаю приход по регистру только на последний кусочек суммы, т.е. последнюю итерацию. Хотя цифры оплаты по документам расчитываются и записываются верно.
где делаю не так?

//{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
    // Данный фрагмент построен конструктором.
    // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
    СуммаОплатыТмп=СуммаДолл;
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    ПродажаМатериала.Ссылка КАК СсылкаДокПродажи,
        |    ПродажаМатериала.ОплатаПоДок КАК ОплатаПоДокПродажи,
        |    ПродажаМатериала.Курс КАК КурсДокПродажи,
        |    ПродажаМатериала.СуммаПоДок КАК СуммаПоДокПродажи
        |ИЗ
        |    Документ.ПродажаМатериала КАК ПродажаМатериала
        |ГДЕ
        |    ПродажаМатериала.Оплата = &Оплата
        |    И ПродажаМатериала.Контрагент = &Контрагент
        |
        |УПОРЯДОЧИТЬ ПО
        |    ПродажаМатериала.Дата";
    
    Запрос.УстановитьПараметр("Оплата", Ложь);
    Запрос.УстановитьПараметр("Контрагент", Контрагент);
    
    РезультатЗапроса = Запрос.Выполнить();
    
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    
    Движения.ПродажаМатериала.Записывать = Истина;
    Движения.ПродажаМатериала.Очистить();

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        ПлатимТЕМП= (ВыборкаДетальныеЗаписи.СуммаПоДокПродажи - ВыборкаДетальныеЗаписи.ОплатаПоДокПродажи);
        Если (СуммаОплатыТмп>=ПлатимТЕМП и СуммаОплатыТмп>0) Тогда
            ДокОбъект = ВыборкаДетальныеЗаписи.СсылкаДокПродажи.ПолучитьОбъект();
            ДокОбъект.ОплатаПоДок =ПлатимТЕМП;
            ДокОбъект.Оплата = Истина;
            ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
            
            // регистр ПродажаМатериала Приход
            Движение = Движения.ПродажаМатериала.Добавить();
            Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
            Движение.Период = Дата;
            Движение.Контрагент = Контрагент;
            Движение.Дата = Дата;
            Движение.СтоимостьДолл = ПлатимТЕМП;
            Движение.СтоимостьГрн = (ПлатимТЕМП*ВыборкаДетальныеЗаписи.КурсДокПродажи);
                    
            //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
            СуммаОплатыТмп=СуммаОплатыТмп-ПлатимТЕМП;
            ОбновитьДопИнфоВсех();
        ИначеЕсли (СуммаОплатыТмп<ПлатимТЕМП и СуммаОплатыТмп>0) Тогда
            ДокОбъект = ВыборкаДетальныеЗаписи.СсылкаДокПродажи.ПолучитьОбъект();
            ДокОбъект.ОплатаПоДок =СуммаОплатыТмп;
            ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
            
            // регистр ПродажаМатериала Приход
            
            Движение = Движения.ПродажаМатериала.Добавить();
            Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
            Движение.Период = Дата;
            Движение.Контрагент = Контрагент;
            Движение.Дата = Дата;
            Движение.СтоимостьДолл = СуммаОплатыТмп;
            Движение.СтоимостьГрн = (СуммаОплатыТмп*ВыборкаДетальныеЗаписи.КурсДокПродажи);
            Движения.Записать();

            //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
            
            СуммаОплатыТмп=0;
            ОбновитьДопИнфоВсех();
            
        КонецЕсли;
         // Движения.Записать();
        
    КонецЦикла;
    
    //}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
podcast
Yevhenii @ Сегодня, 14:38 необходимо зарегистрироваться для просмотра ссылки ,
 Если (СуммаОплатыТмп>=ПлатимТЕМП и СуммаОплатыТмп>0) Тогда
            ДокОбъект = ВыборкаДетальныеЗаписи.СсылкаДокПродажи.ПолучитьОбъект();
            ДокОбъект.ОплатаПоДок =ПлатимТЕМП;
            ДокОбъект.Оплата = Истина;
            ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
            
            // регистр ПродажаМатериала Приход
            Движение = Движения.ПродажаМатериала.Добавить();
            Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
            Движение.Период = Дата;
            Движение.Контрагент = Контрагент;
            Движение.Дата = Дата;
            Движение.СтоимостьДолл = ПлатимТЕМП;
            Движение.СтоимостьГрн = (ПлатимТЕМП*ВыборкаДетальныеЗаписи.КурсДокПродажи);
            
                Движения.Записать(); // !!!Вроде ж нужно записать.

        
            //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
            СуммаОплатыТмп=СуммаОплатыТмп-ПлатимТЕМП;
            ОбновитьДопИнфоВсех();
        ИначеЕсли (СуммаОплатыТмп<ПлатимТЕМП и СуммаОплатыТмп>0) Тогда
            ДокОбъект = ВыборкаДетальныеЗаписи.СсылкаДокПродажи.ПолучитьОбъект();
            ДокОбъект.ОплатаПоДок =СуммаОплатыТмп;
            ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
            
            // регистр ПродажаМатериала Приход
            
            Движение = Движения.ПродажаМатериала.Добавить();
            Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
            Движение.Период = Дата;
            Движение.Контрагент = Контрагент;
            Движение.Дата = Дата;
            Движение.СтоимостьДолл = СуммаОплатыТмп;
            Движение.СтоимостьГрн = (СуммаОплатыТмп*ВыборкаДетальныеЗаписи.КурсДокПродажи);
            Движения.Записать();

            //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
            
            СуммаОплатыТмп=0;
            ОбновитьДопИнфоВсех();
            
        КонецЕсли;
logist
Цитата(Yevhenii @ 16.03.17, 14:38) необходимо зарегистрироваться для просмотра ссылки
приход по регистру только на последний кусочек суммы, т.е. последнюю итерацию.

У вас же условие Если и ИначеЕсли, возможно остальные записи из запроса не попадают в эти условия, а попадает только одна.

Пройдитесь отладчиком - поймете сразу

Цитата(podcast @ 16.03.17, 14:57) необходимо зарегистрироваться для просмотра ссылки
 Движения.Записать(); // !!!Вроде ж нужно записать.

Зачем? Вот кстати, потому что в последнем условии есть запись - поэтому там остается только она.
Если объявляете Движения.ПродажаМатериала.Записывать = Истина; то записывать уже не надо, это сделает сама платформа.
Yevhenii
podcast @ Сегодня, 14:57 необходимо зарегистрироваться для просмотра ссылки ,
да, писал в каждом блоке "Если" ситуация та же. Спецом вынес за цикл.
Движения.ПродажаМатериала.Записывать = Истина;
        Движения.ПродажаМатериала.Очистить();

результат тот же

logist @ Сегодня, 15:03 необходимо зарегистрироваться для просмотра ссылки ,
я тоже сначала так подумал, но ведь в реквизиты перебираемых документов всю сумму исправно расписывает. плюс отладчиком проверял, по всем строкам проходит так как надо, значения рассчитывает верно, но в регистр почему пишет только последнюю сумму
logist
Цитата(Yevhenii @ 16.03.17, 15:07) необходимо зарегистрироваться для просмотра ссылки
но ведь в реквизиты перебираемых документов всю сумму исправно расписывает

Причем тут ваши документы. Записи в регистр это совсем другой механизм.

Цитата(Yevhenii @ 16.03.17, 15:07) необходимо зарегистрироваться для просмотра ссылки
но в регистр почему пишет только последнюю сумму

отладчиком вам видно, что в конце цикла в таблице движений все строки?
Yevhenii
Цитата(logist @ 16.03.17, 15:13) необходимо зарегистрироваться для просмотра ссылки
Цитата(Yevhenii @ 16.03.17, 15:07)
но ведь в реквизиты перебираемых документов всю сумму исправно расписывает
Причем тут ваши документы. Записи в регистр это совсем другой механизм.


алгоритм таков:
берем первый документ- Вычисляем сумму к оплате- пишем реквизиты в выбранный документ-пишем движения-берем следующий документ и т.д.
т.е. движения в регистр должны писаться сразу после записи реквизитов в документ и отладчик проходит по всем строкам, каждого документа который берётся

вот поэтому и написал сюда, так как не могу самостоятельно понять как в таком случае работает механизм записи в регистр. ведь по логике должно записать в каждой итерации при обходе выборки.

P.S. Добавил Движения.Записать(); в каждый блок Если (изначально так и делал), перепроверил, результат тот же.
logist
Цитата(Yevhenii @ 16.03.17, 15:22) необходимо зарегистрироваться для просмотра ссылки
P.S. Добавил Движения.Записать();

Уберите, и посмотрите на результат.
Yevhenii
Всё, разобрался))) Всем спасибо, за подсказки))

//{{КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
    // Данный фрагмент построен конструктором.
    // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
    СуммаОплатыТмп=СуммаДолл;
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    ПродажаМатериала.Ссылка КАК СсылкаДокПродажи,
        |    ПродажаМатериала.ОплатаПоДок КАК ОплатаПоДокПродажи,
        |    ПродажаМатериала.Курс КАК КурсДокПродажи,
        |    ПродажаМатериала.СуммаПоДок КАК СуммаПоДокПродажи
        |ИЗ
        |    Документ.ПродажаМатериала КАК ПродажаМатериала
        |ГДЕ
        |    ПродажаМатериала.Оплата = &Оплата
        |    И ПродажаМатериала.Контрагент = &Контрагент
        |
        |УПОРЯДОЧИТЬ ПО
        |    ПродажаМатериала.Дата";
    
    Запрос.УстановитьПараметр("Оплата", Ложь);
    Запрос.УстановитьПараметр("Контрагент", Контрагент);
    
    РезультатЗапроса = Запрос.Выполнить();
    
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    
    Движения.ПродажаМатериала.Записывать = Истина;
    Движения.ПродажаМатериала.Очистить();

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        ПлатимТЕМП= (ВыборкаДетальныеЗаписи.СуммаПоДокПродажи - ВыборкаДетальныеЗаписи.ОплатаПоДокПродажи);
        Если (СуммаОплатыТмп>=ПлатимТЕМП и СуммаОплатыТмп>0) Тогда
            ДокОбъект = ВыборкаДетальныеЗаписи.СсылкаДокПродажи.ПолучитьОбъект();
            
            //*************мои движения
            
        ИначеЕсли (СуммаОплатыТмп<ПлатимТЕМП и СуммаОплатыТмп>0) Тогда
              //*************мои движения
            
        КонецЕсли;
         // Движения.Записать(); (!!Этому тут не место)
        
    КонецЦикла;
    
    //}}КОНСТРУКТОР_ЗАПРОСА_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
      Движения.Записать(); //*************
//************* вот она мать всех зол(ну и конечно моя не внимательность!)  надо было просто написать это после цикла с движениями, а не в самом цикле после каждого набора  движений или в каждом "Если"
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.