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