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