Как заполнить проводки нового документа ОперацияБух и показать его пользователю без записи?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При разработке различных интеграций, обработок закрытия периода или инструментов автоматизации в конфигурации «1С:Бухгалтерия предприятия 3.0» (БП 3) часто возникает задача: создать новый документ «Операция (бухгалтерский и налоговый учет)» (ОперацияБух), заполнить в нем проводки и показать форму пользователю, не записывая сам документ в базу данных. Это позволяет пользователю визуально оценить корректность сформированных проводок, при необходимости отредактировать их вручную и самостоятельно нажать кнопку «Записать».

На первый взгляд задача кажется простой, однако разработчики часто сталкиваются с трудностями. Проводки в документе ОперацияБух хранятся не в табличной части самого документа, а в регистре бухгалтерии Хозрасчетный, для которого документ выступает регистратором. Поскольку у нового незаписанного документа еще нет ссылки (уникального идентификатора в базе данных), стандартные методы работы с наборами записей регистра бухгалтерии напрямую применить не удастся. В этой статье мы подробно разберем, как правильно решить данную задачу с использованием штатных механизмов управляемых форм и типовых процедур конфигурации.

Выясняем причину: анализ типового механизма БП 3.0

Для начала проанализируем, как устроена форма документа ОперацияБух в типовой конфигурации. Откроем модуль формы документа и обратим внимание на обработчик события ПриСозданииНаСервере. В нем содержится следующий примечательный фрагмент кода:


Если Параметры.Ключ.Пустая() Тогда
    УстановитьСостояниеДокумента("НезаписанныйДокумент");
    ПодготовитьФормуНаСервере(Параметры.ЗначениеКопирования);
    ЗаполнитьДвижения(Параметры.ЗначенияЗаполнения);
КонецЕсли;

Как мы видим, если открывается форма нового (еще не записанного) документа, система вызывает процедуру ЗаполнитьДвижения, передавая в нее структуру Параметры.ЗначенияЗаполнения. Рассмотрим процедуру ЗаполнитьДвижения подробнее:


Процедура ЗаполнитьДвижения(ЗначенияЗаполнения)
    Если НЕ ЗначенияЗаполнения.Свойство("Хозрасчетный") Тогда
        Возврат;
    КонецЕсли;
    
    Для Каждого СтруктураПроводки Из ЗначенияЗаполнения.Хозрасчетный Цикл
        НоваяПроводка = ХозрасчетныйНаборЗаписей.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяПроводка, СтруктураПроводки);
        // Дополнительная обработка субконто и других реквизитов...
    КонецЦикла;
КонецПроцедуры 

Этот код дает нам прямую и очень удобную подсказку: разработчики фирмы «1С» уже заложили штатную возможность заполнения движений нового документа при его открытии. Для этого достаточно передать в параметрах формы структуру ЗначенияЗаполнения, внутри которой под ключом "Хозрасчетный" будет находиться массив структур с описанием наших проводок.

Давайте разберем по шагам, как реализовать этот механизм на практике.

Способ 1. Использование штатного параметра ЗначенияЗаполнения (Рекомендуемый)

Этот способ является наиболее чистым и корректным, так как он полностью опирается на типовую логику конфигурации и не требует внесения изменений в форму документа (например, через расширения). Все действия выполняются в вашей внешней обработке или программном модуле.

Рассмотрим пример реализации. Предположим, у нас есть внешняя обработка, из которой мы хотим открыть новую операцию с заранее рассчитанными проводками:


&НаКлиенте
Процедура СформироватьИОткрытьОперацию(Команда)
    
    // Шаг 1. Формируем массив проводок на сервере
    ТаблицаПроводок = СформироватьПроводкиНаСервере();
    
    // Шаг 2. Подготавливаем параметры для открытия формы
    ПараметрыЗаполнения = Новый Структура;
    ПараметрыЗаполнения.Вставить("Организация", Объект.Организация);
    ПараметрыЗаполнения.Вставить("Содержание", "Программное распределение расходов");
    
    // Передаем массив структур в ключ "Хозрасчетный"
    ПараметрыЗаполнения.Вставить("Хозрасчетный", ТаблицаПроводок);
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);
    
    // Шаг 3. Открываем форму нового документа
    ОткрытьФорму("Документ.ОперацияБух.Форма.ФормаДокумента", ПараметрыФормы);
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция СформироватьПроводкиНаСервере()
    
    МассивПроводок = Новый Массив;
    
    // Первая проводка: Дт 20.01 - Кт 26
    Проводка1 = Новый Структура;
    Проводка1.Вставить("Активность", Истина);
    Проводка1.Вставить("СчетДт", ПланыСчетов.Хозрасчетный.НайтиПоКоду("20.01"));
    Проводка1.Вставить("СчетКт", ПланыСчетов.Хозрасчетный.НайтиПоКоду("26"));
    Проводка1.Вставить("Сумма", 15000);
    
    // Заполнение аналитики (субконто) Дт
    // Для этого используем имена свойств СубконтоДт1, СубконтоДт2 и т.д.
    Проводка1.Вставить("СубконтоДт1", Справочники.НоменклатурныеГруппы.НайтиПоНаименованию("Основная номенклатурная группа"));
    Проводка1.Вставить("СубконтоДт2", Справочники.СтатьиЗатрат.НайтиПоНаименованию("Амортизация"));
    
    МассивПроводок.Добавить(Проводка1);
    
    // Вторая проводка: Дт 20.01 - Кт 26 (по другой статье)
    Проводка2 = Новый Структура;
    Проводка2.Вставить("Активность", Истина);
    Проводка2.Вставить("СчетДт", ПланыСчетов.Хозрасчетный.НайтиПоКоду("20.01"));
    Проводка2.Вставить("СчетКт", ПланыСчетов.Хозрасчетный.НайтиПоКоду("26"));
    Проводка2.Вставить("Сумма", 8500);
    Проводка2.Вставить("СубконтоДт1", Справочники.НоменклатурныеГруппы.НайтиПоНаименованию("Основная номенклатурная группа"));
    Проводка2.Вставить("СубконтоДт2", Справочники.СтатьиЗатрат.НайтиПоНаименованию("Материальные расходы"));
    
    МассивПроводок.Добавить(Проводка2);
    
    Возврат МассивПроводок;
    
КонецФункции

Важное примечание относительно типов данных: Некоторые участники форума ошибочно полагают, что массив структур нельзя передавать в параметры открытия формы с клиента на сервер из-за ограничений сериализации. Это заблуждение. Массив и Структура — это универсальные коллекции платформы 1С, которые прекрасно сериализуются и передаются между клиентом и сервером. Главное условие — элементы внутри структуры должны быть примитивными типами (Строка, Число, Дата, Булево) или ссылочными типами данных (такими как СправочникСсылка, ПланСчетовСсылка). Передавать прикладные объекты (например, ТаблицаЗначений или ДокументОбъект) действительно нельзя.

Способ 2. Прямое заполнение данных формы

Рассмотрим альтернативную ситуацию. Допустим, вам по какой-то причине неудобно готовить массив структур заранее или вы хотите выполнить сложную постобработку данных уже непосредственно в объекте формы перед ее показом. В этом случае мы можем сначала получить форму в переменную на клиенте, затем передать её коллекцию данных на сервер, заполнить её там программно и после этого открыть.

Для реализации этого сценария проанализируем следующий код:


&НаКлиенте
Процедура СоздатьИЗаполнитьНапрямую(Команда)
    
    // Получаем форму нового документа, но не открываем ее сразу
    ФормаДок = ПолучитьФорму("Документ.ОперацияБух.Форма.ФормаДокумента");
    
    // Передаем реквизиты формы на сервер для заполнения
    ЗаполнитьДанныеФормыНаСервере(ФормаДок.Объект, ФормаДок.ХозрасчетныйНаборЗаписей);
    
    // Показываем пользователю уже заполненную форму
    ФормаДок.Открыть();
    
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ЗаполнитьДанныеФормыНаСервере(ДанныеФормыОбъект, ДанныеФормыКоллекцияПроводок)
    
    // Заполняем реквизиты шапки документа
    ДанныеФормыОбъект.Дата = ТекущаяДата();
    ДанныеФормыОбъект.Содержание = "Распределение общехозяйственных затрат";
    
    // Заполняем проводки напрямую в коллекцию данных формы
    НоваяСтрока = ДанныеФормыКоллекцияПроводок.Добавить();
    НоваяСтрока.Активность = Истина;
    НоваяСтрока.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("20.01");
    НоваяСтрока.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("26");
    НоваяСтрока.Сумма = 50000;
    
    // Для корректного отображения субконто на форме используем свойства СубконтоДт и СубконтоКт
    НоваяСтрока.СубконтоДт1 = Справочники.НоменклатурныеГруппы.НайтиПоНаименованию("Основная номенклатурная группа");
    НоваяСтрока.СубконтоДт2 = Справочники.СтатьиЗатрат.НайтиПоНаименованию("Оплата труда");
    
КонецПроцедуры

В этом примере переменная ФормаДок.ХозрасчетныйНаборЗаписей на сервере представляет собой объект типа ДанныеФормыКоллекция. Мы можем манипулировать им точно так же, как обычной табличной частью формы: добавлять строки, заполнять колонки и изменять значения. При открытии формы все внесенные изменения сразу же отобразятся на экране у пользователя.

Важные нюансы и подводные камни

При программном заполнении проводок документа ОперацияБух обязательно обратите внимание на следующие ключевые моменты, несоблюдение которых может привести к ошибкам в учете:

  1. Флаг «Активность»: У каждой добавляемой проводки (строки) обязательно устанавливайте свойство Активность = Истина. По умолчанию при программном добавлении строк в коллекцию это свойство может принимать значение Ложь. В таком случае проводки отобразятся на форме блеклым шрифтом (как выключенные) и при проведении документа не сделают никаких движений по регистрам.
  2. Заполнение субконто: Обратите внимание, что счета бухгалтерского учета имеют разное количество субконто (от 0 до 3). Заполняйте только те поля СубконтоДтX / СубконтоКтX, виды субконто которых назначены выбранному счету в плане счетов. Если попытаться записать значение в СубконтоДт3 для счета, у которого настроено только два субконто, платформа проигнорирует это значение или вызовет ошибку при записи.
  3. Организация в проводках: Начиная со второго способа, если вы заполняете проводки вручную, следите за тем, чтобы реквизит Организация в шапке документа совпадал с организацией, по которой делаются проводки (если балансовые счета предполагают ведение учета по организациям). В первом способе типовой механизм заполнения делает это автоматически.

Мы подробно проанализировали два надежных и проверенных способа заполнения движений для нового незаписанного документа ОперацияБух. Выбирайте первый вариант с параметром ЗначенияЗаполнения как наиболее изящный и соответствующий стандартам разработки «1С», или же используйте второй вариант для более гибкого управления процессом заполнения непосредственно через реквизиты формы.

← На главную