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