При написании внешних обработок и алгоритмов групповой корректировки данных часто возникает задача программного изменения проводок ручных операций. Начинающие разработчики нередко сталкиваются с вопросом, как правильно получить доступ к движениям документа ОперацияБух, прочитать их, модифицировать нужные реквизиты или субконто и корректно сохранить изменения в информационной базе.
Разберем основные подходы к решению этой задачи, рассмотрим нюансы взаимодействия со специализированными коллекциями аналитики и выясним, какие ошибки чаще всего допускаются при работе с регистром бухгалтерии.
Рассмотрим классический способ, когда у нас уже есть ссылка на документ ОперацияБух и мы работаем через объект документа. Этот вариант часто применяется во внешних обработках, если наряду с проводками требуется обновить реквизиты самой шапки документа (например, реквизит СуммаОперации).
Разберем по шагам логику работы:
ПолучитьОбъект().Операция.Движения.Хозрасчетный.Прочитать().Записать() у самого набора.Посмотрим на пример программного кода, в котором выполняется замена склада в аналитике проводок:
ОперацияОбъект = СсылкаНаОперацию.ПолучитьОбъект();
НаборХозрасчетный = ОперацияОбъект.Движения.Хозрасчетный;
// Считываем актуальные проводки из базы данных
НаборХозрасчетный.Прочитать();
БылИзменен = Ложь;
ВидСубконтоСклады = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады;
Для Каждого Проводка Из НаборХозрасчетный Цикл
// Проверяем субконто дебета
Если Проводка.СубконтоДт[ВидСубконтоСклады] = СтарыйСклад Тогда
Проводка.СубконтоДт[ВидСубконтоСклады] = НовыйСклад;
БылИзменен = Истина;
КонецЕсли;
// Проверяем субконто кредита
Если Проводка.СубконтоКт[ВидСубконтоСклады] = СтарыйСклад Тогда
Проводка.СубконтоКт[ВидСубконтоСклады] = НовыйСклад;
БылИзменен = Истина;
КонецЕсли;
КонецЦикла;
Если БылИзменен Тогда
// Записываем набор напрямую
НаборХозрасчетный.Записать(Истина);
КонецЕсли;
Важный момент: если сохранение выполняется через вызов ОперацияОбъект.Записать(), необходимо убедиться, что свойство НаборХозрасчетный.Записывать установлено в значение Истина. В противном случае платформа 1С не сохранит изменения проводок при записи документа.
Проанализируем ситуацию, когда требуется изменить исключительно проводки, не затрагивая реквизиты документа. Вызов метода ПолучитьОбъект() является ресурсоемким: он считывает все табличные части, реквизиты шапки документа и накладывает объектную блокировку. В массовых обработках это приводит к снижению производительности.
Оптимальнее создать независимый набор записей непосредственно через менеджер регистра бухгалтерии:
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаОперацию);
// Считываем записи регистра по отбору
НаборЗаписей.Прочитать();
Для Каждого Проводка Из НаборЗаписей Цикл
// Выполняем требуемую модификацию полей проводки
Если Проводка.СчетДт = СтарыйСчет Тогда
Проводка.СчетДт = НовыйСчет;
КонецЕсли;
КонецЦикла;
// Записываем набор записей с замещением
НаборЗаписей.Записать(Истина);
Такой подход выполняется быстрее, расходует меньше оперативной памяти и минимизирует блокировки транзакций при обработке больших массивов документов.
Рассмотрим подробнее ошибки, которые часто возникают при попытке перебрать субконто как обычные колонки таблицы значений. В регистре бухгалтерии субконто не являются фиксированными полями базы данных, а представлены коллекциями СубконтоДт и СубконтоКт.
При модификации субконто учитываем следующие правила:
Проводка.СубконтоДт[ВидСубконто]) или через метод Вставить(): Проводка.СубконтоДт.Вставить(ВидСубконто, Значение).СчетДт или СчетКт, состав доступных субконто меняется автоматически. В этом случае необходимо заново проверить корректность установленных видов аналитики, очистив неподходящие и заполнив обязательные.Выясним причину возможных расхождений между журналом операций и проводками. В типовых конфигурациях документ ОперацияБух содержит реквизит СуммаОперации, значение которого отображается в форме списка.
Если в процессе обработки изменяются суммы по строкам проводок (ресурс Сумма), обязательно следует обновить значение реквизита СуммаОперации в самом объекте документа, чтобы суммы в журнале соответствовали проводкам.
Также при изменении стоимостных и количественных показателей проводки требуется контролировать зависимые ресурсы:
КоличествоДт и КоличествоКт.ВалютаДт, СуммаВалДт и соответствующие кредитовые поля.СуммаНУДт, СуммаНУКт, а также постоянные (СуммаПРДт, СуммаПРКт) и временные разницы (СуммаВРДт, СуммаВРКт) по формуле БУ = НУ + ПР + ВР, чтобы исключить ошибки при выполнении регламентных операций закрытия месяца.