Как программно создать, заполнить табличную часть и открыть незаписанный документ в управляемых формах 1С?

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

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

Разберем подробнее, как правильно через внешнюю обработку создать документ, заполнить его табличную часть (ТЧ) данными (например, из запроса) и показать пользователю перед записью, чтобы он мог проверить данные.

Способ 1: Получение формы и копирование данных формы на сервере

Этот метод является классическим решением для управляемых форм. Проанализируем по шагам, как это работает. Сначала мы должны получить пустую форму нужного документа на клиенте, затем передать ее данные на сервер, заполнить там, вернуть обратно и открыть.

Посмотрим на пример базового каркаса:


// Выполняется на клиенте
Форма = ПолучитьФорму("Документ.ПланПродажПоСтилям.Форма.ФормаИкс");
ДанныеФормы = Форма.Объект;
ЗаполнитьДаннымиНаСервере(ДанныеФормы);
КопироватьДанныеФормы(ДанныеФормы, Форма.Объект);
Форма.Открыть();

Здесь используется метод КопироватьДанныеФормы. Поскольку мы не можем напрямую модифицировать открываемую форму с сервера, мы берем структуру Форма.Объект, передаем ее на сервер, модифицируем и затем копируем обновленные данные обратно в форму.

Рассмотрим подробнее, как правильно реализовать процедуру ЗаполнитьДаннымиНаСервере. Если мы будем просто добавлять строки в переданную структуру, мы будем лишены возможности использовать экспортные методы модуля объекта документа (например, пересчет сумм). Поэтому рекомендуется временно конвертировать данные в полноценный объект:


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

Способ 2: Использование параметров заполнения (ЗначенияЗаполнения)

Существует более изящный и стандартизированный способ открыть заполненный, но незаписанный документ. Разберем использование параметра ЗначенияЗаполнения.

Метод ОткрытьФорму позволяет передавать структуру параметров. Платформа 1С устроена так, что если передать структуру с ключом ЗначенияЗаполнения, эти данные будут автоматически проброшены в обработчик события ОбработкаЗаполнения в модуле самого документа.

В этом случае внешняя обработка только собирает исходные данные (выполняет запрос) и отдает их документу. Документ сам разбирает переданную структуру и заполняет свои реквизиты и табличные части.


// На клиенте в обработке
ПараметрыЗаполнения = Новый Структура;
ПараметрыЗаполнения.Вставить("ДанныеДляТЧ", ПодготовитьДанныеНаСервере()); // Передаем массив или таблицу

ПараметрыФормы = Новый Структура("ЗначенияЗаполнения", ПараметрыЗаполнения);
ОткрытьФорму("Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента", ПараметрыФормы);

Этот подход делает код намного более универсальным и переносимым, так как логика заполнения документа хранится в самом документе, а не размазана по внешним обработкам.

Особый случай: Заполнение документа "Операция, введенная вручную"

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

Таблица проводки, которую видит пользователь на форме — это напрямую выведенный набор записей регистра бухгалтерии (как правило, регистра Хозрасчетный). Из-за этой архитектуры программно создать и открыть такую операцию незаписанной, но уже с готовыми проводками штатными средствами практически невозможно. Записям регистра обязательно нужен регистратор (ссылка на существующий в базе документ).

Выясним правильный алгоритм работы с ручными операциями:

  1. Сначала мы программно создаем сам документ "Операция" и обязательно записываем его в базу. Это даст нам ссылку-регистратор.
  2. Создаем набор записей регистра бухгалтерии.
  3. Устанавливаем отбор набора записей по регистратору (ссылка на нашу записанную операцию).
  4. В цикле добавляем и заполняем проводки. Критически важное условие: реквизит Период в каждой добавляемой записи должен строго совпадать с датой самого документа, иначе платформа выдаст ошибку и записи не привяжутся!
  5. Записываем набор записей.
  6. Только после этого открываем форму уже записанного документа, используя метод ОткрытьЗначение или ПоказатьЗначение.

Посмотрим на пример кода для этого алгоритма:


&НаСервере
Функция СоздатьИЗаполнитьОперациюНаСервере()
    
    // 1. Создаем и записываем документ
    ДокОперация = Документы.ОперацияБух.СоздатьДокумент();
    ДокОперация.Дата = ТекущаяДата();
    ДокОперация.Организация = Справочники.Организации.НайтиПоНаименованию("Наша Организация");
    ДокОперация.Содержание = "Загружено из внешней обработки";
    ДокОперация.Записать();
    
    // 2. Работаем с регистром бухгалтерии
    НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Регистратор.Установить(ДокОперация.Ссылка);
    
    // 3. Добавляем проводку
    Движение = НаборЗаписей.Добавить();
    Движение.Регистратор = ДокОперация.Ссылка;
    Движение.Период = ДокОперация.Дата; // Обязательно равно дате документа!
    
    // Указываем счета и аналитику
    Движение.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("26");
    Движение.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("70");
    Движение.Сумма = 15000;
    Движение.Содержание = "Тестовая проводка";
    
    // 4. Записываем набор
    НаборЗаписей.Записать();
    
    Возврат ДокОперация.Ссылка;
    
КонецФункции

&НаКлиенте
Процедура СоздатьРучнуюОперацию(Команда)
    
    СсылкаНаДокумент = СоздатьИЗаполнитьОперациюНаСервере();
    ПоказатьЗначение(, СсылкаНаДокумент);
    
КонецПроцедуры

Применяя данные подходы, вы сможете корректно манипулировать данными форм и регистров в среде управляемого приложения 1С, обеспечивая стабильную работу ваших внешних обработок.

← На главную