Документ КорректировкаЗаписейРегистров (в современных конфигурациях на базе ERP — КорректировкаРегистров, а в БП 3.0 — ОперацияБух) используется для ручного исправления движений, ввода начальных остатков и выполнения сторнировочных операций. Особенность этого объекта заключается в том, что у него нет стандартных табличных частей с номенклатурой или суммами: его табличные части и закладки формы формируются динамически на основании выбранного состава регистров.
Если попытаться просто сформировать записи в регистрах или создать документ без предварительной подготовки его метаданных, при первом же открытии и пересохранении документа пользователем все внесенные движения будут безвозвратно удалены. Разберем по шагам внутреннюю архитектуру документа и выясним, как правильно создавать корректировки программно.
Проанализируем структуру документа перед написанием кода. Чтобы созданная корректировка корректно функционировала в системе, необходимо учитывать несколько критических правил платформы 1С:
ТаблицаРегистровНакопления, ТаблицаРегистровСведений, ТаблицаРегистровБухгалтерии). Прежде чем делать движения, мы обязаны добавить строки с именами регистров в эти таблицы. Если имя регистра не указано в табличной части, интерактивная форма документа не увидит движений и при ручной перезаписи сотрет их пустым набором.ДокументОбъект.Движения, необходимо явно взводить флаг Записывать = Истина для модифицируемого регистра. Без этого вызов Записать() сохранит лишь шапку документа, проигнорировав строки регистра.РежимЗаписиДокумента.Запись. Попытка вызвать проведение приведет к исключению платформы.ОбменДанными.Загрузка = Истина.Рассмотрим стандартный сценарий, при котором мы создаем новый документ и сразу наполняем коллекцию его движений. Этот метод наиболее нагляден и удобен, когда количество формируемых строк невелико (до нескольких тысяч).
Посмотрим на пример заполнения регистра накопления по упрощенной системе налогообложения:
// Создаем новый объект документа
ДокКорректировка = Документы.КорректировкаЗаписейРегистров.СоздатьДокумент();
ДокКорректировка.Дата = КонецДня(ТекущаяДата());
ДокКорректировка.Комментарий = "Корректировка остатков по регистрам УСН";
// Заполняем состав используемых регистров накопления
НоваяСтрока = ДокКорректировка.ТаблицаРегистровНакопления.Добавить();
НоваяСтрока.Имя = "ВзаиморасчетыУСН";
НоваяСтрока.Представление = "Взаиморасчеты УСН";
// Обращаемся к коллекции движений нужного регистра
НаборВзаиморасчеты = ДокКорректировка.Движения.ВзаиморасчетыУСН;
НаборВзаиморасчеты.Записывать = Истина; // Обязательный флаг для сохранения строк
// Добавляем движение расхода
Стр = НаборВзаиморасчеты.ДобавитьРасход();
Стр.Период = ДокКорректировка.Дата;
Стр.Организация = ОрганизацияСсылка;
Стр.ДоговорКонтрагента = СсылкаНаДоговор;
Стр.СуммаВзаиморасчетов = 15000;
// При необходимости исключить регистрацию документа в планах обмена:
// ДокКорректировка.ОбменДанными.Загрузка = Истина;
// Записываем документ вместе с движениями
Попытка
ДокКорректировка.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Документ успешно записан: " + Строка(ДокКорректировка.Ссылка));
Исключение
Сообщить("Ошибка записи документа: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
Разберем ситуацию, когда требуется скорректировать десятки тысяч записей или выполнить сложную операцию переоценки активов с проводками по бухгалтерскому учету. Если манипулировать миллионами строк через ДокументОбъект.Движения, весь объем данных загружается в оперативную память, вызывая зависания сервера и длительные блокировки таблиц базы данных.
Оптимальный алгоритм заключается в двухэтапной записи: сначала мы создаем документ-регистратор с заполненным перечнем регистров и сохраняем его, а затем записываем движения напрямую через СоздатьНаборЗаписей() с установленным отбором по регистратору.
Рассмотрим подробнее реализацию этого подхода на примере регистра бухгалтерии Хозрасчетный:
НачатьТранзакцию();
Попытка
// Шаг 1. Создаем и записываем документ-шапку
ДокКорректировка = Документы.КорректировкаЗаписейРегистров.СоздатьДокумент();
ДокКорректировка.Дата = ТекущаяДата();
ДокКорректировка.Комментарий = "Корректировка стоимости ОС";
// Регистрируем бухгалтерский регистр в табличной части
СтрокаБух = ДокКорректировка.ТаблицаРегистровБухгалтерии.Добавить();
СтрокаБух.Имя = "Хозрасчетный";
СтрокаБух.Представление = "Журнал проводок (бухгалтерский учет)";
// Сохраняем шапку, чтобы получить ссылку для регистратора
ДокКорректировка.Записать(РежимЗаписиДокумента.Запись);
СсылкаРегистратор = ДокКорректировка.Ссылка;
// Шаг 2. Создаем набор записей регистра бухгалтерии
НаборБух = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборБух.Отбор.Регистратор.Установить(СсылкаРегистратор);
// Заполняем проводку
Проводка = НаборБух.Добавить();
Проводка.Период = ДокКорректировка.Дата;
Проводка.Регистратор = СсылкаРегистратор;
Проводка.Организация = ОрганизацияСсылка;
Проводка.Содержание = "Увеличение первоначальной стоимости ОС";
Проводка.СчетДт = ПланыСчетов.Хозрасчетный.ОСвОрганизации;
Проводка.СчетКт = ПланыСчетов.Хозрасчетный.ПриростСтоимостиИмуществаПоПереоценке;
БухгалтерскийУчет.УстановитьСубконто(Проводка.СчетДт, Проводка.СубконтоДт, "ОсновныеСредства", ТекущееОС);
БухгалтерскийУчет.УстановитьСубконто(Проводка.СчетКт, Проводка.СубконтоКт, "ОсновныеСредства", ТекущееОС);
Проводка.Сумма = 50000;
// Записываем набор в базу данных
НаборБух.Записать();
ЗафиксироватьТранзакцию();
Сообщить("Записи успешно внесены в регистр бухгалтерии.");
Исключение
ОтменитьТранзакцию();
Сообщить("Ошибка: " + ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
КонецПопытки;
Выясним различия в зависимости от используемой конфигурации:
КорректировкаРегистров. Состав регистров хранится в единой табличной части ТаблицаРегистров, содержащей реквизиты Имя (строковое имя регистра) и ТипРегистра (строка с типом: "РегистрНакопления", "РегистрСведений", "РегистрБухгалтерии").ОперацияБух. В нем при программной настройке также требуется добавлять строки в служебные таблицы состава регистров, иначе вкладки с записями не появятся в пользовательском интерфейсе.Соблюдение правил заполнения служебных табличных частей и явной установки признака записи наборов гарантирует целостность данных и корректное отображение записей в пользовательском интерфейсе.