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

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

В практике разработчика 1С часто возникает задача: необходимо открыть форму нового, еще не записанного в базу данных документа, предварительно заполнив его реквизиты и табличную часть (ТЧ). При этом критически важно предоставить пользователю выбор — записать этот документ, провести или просто закрыть форму без сохранения изменений.

Особую сложность эта задача вызывает в современных комплексных конфигурациях, таких как 1С:ERP Управление предприятием, 1С:Комплексная автоматизация или 1С:Управление торговлей. Разработчики часто сталкиваются с тем, что при программном открытии формы и заполнении её реквизитов строки табличной части визуально остаются пустыми. Данные внутри объекта вроде бы присутствуют (это видно в отладчике), но на форме они не отображаются до тех пор, пока документ не будет записан или проведен.

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

---

Выясняем причину: почему строки табличной части отображаются пустыми?

Для того чтобы понять, почему строки ТЧ «исчезают» или отображаются пустыми при стандартном открытии формы, нам нужно заглянуть во внутреннее устройство управляемого приложения.

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

В крупных типовых конфигурациях (ERP, КА, УТ) разработчики фирмы «1С» часто связывают элементы интерфейса формы не напрямую с физическими табличными частями документа. Для реализации сложного функционала (такого как автоматический расчет скидок, распределение НДС, работа со статусами строк, упаковками и ключами связи) на форме выводятся виртуальные таблицы или специальные реквизиты формы.

Когда мы пытаемся заполнить ТЧ напрямую на клиенте с помощью простого добавления строк:


// Такой подход часто приводит к пустым строкам на форме:
НоваяСтрока = Форма.Объект.Товары.Добавить();
НоваяСтрока.Номенклатура = ВыбраннаяНоменклатура;

Мы обходим стандартные механизмы инициализации документа. Форма открывается, но встроенные в нее алгоритмы пересчета и визуализации (которые обычно отрабатывают при создании формы на сервере) не запускаются. В результате данные в коллекции формы есть, но визуальные элементы управления не синхронизированы с ними. При записи или проведении документа срабатывает принудительный пересчет, и данные «внезапно» появляются.

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

---

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

Этот способ является наиболее чистым с точки зрения стандартов разработки фирмы «1С». Платформа предоставляет штатный механизм заполнения документов при создании. Мы можем передать структуру параметров в форму нового документа при ее открытии.

Поскольку напрямую передать объект типа ТаблицаЗначений с клиента на сервер мы не можем, мы преобразуем табличную часть в Массив Структур. Каждая структура в массиве будет представлять собой строку будущей табличной части.

Проанализируем пример кода, выполняемый на клиенте:


&НаКлиенте
Процедура ОткрытьФормуНовогоДокумента()

    // 1. Создаем общую структуру для параметров заполнения
    ПараметрыЗаполнения = Новый Структура;
    
    // Заполняем реквизиты шапки документа
    ПараметрыЗаполнения.Вставить("Организация", СсылкаНаОрганизацию);
    ПараметрыЗаполнения.Вставить("Контрагент", СсылкаНаКонтрагента);
    ПараметрыЗаполнения.Вставить("Валюта", СсылкаНаВалюту);
    
    // 2. Формируем массив структур для табличной части "Товары"
    МассивСтрокТовары = Новый Массив;
    
    // Пример заполнения одной строки (в реальном коде здесь будет цикл)
    СтрокаТовара = Новый Структура;
    СтрокаТовара.Вставить("Номенклатура", СсылкаНаНоменклатуру);
    СтрокаТовара.Вставить("Количество", 10);
    СтрокаТовара.Вставить("Цена", 150);
    СтрокаТовара.Вставить("СтавкаНДС", ПредопределенноеЗначение("Перечисление.СтавкиНДС.НДС20"));
    
    МассивСтрокТовары.Добавить(СтрокаТовара);
    
    // Добавляем массив табличной части в общую структуру параметров
    ПараметрыЗаполнения.Вставить("Товары", МассивСтрокТовары);
    
    // 3. Помещаем структуру в специальный параметр формы "ЗначенияЗаполнения"
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ЗначенияЗаполнения", ПараметрыЗаполнения);
    
    // 4. Открываем форму нового документа
    ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыФормы);

КонецПроцедуры

При таком подходе платформа автоматически инициализирует создание нового документа и передаст структуру ПараметрыЗаполнения в обработчик модуля объекта ОбработкаЗаполнения.

Важный нюанс для конфигураций на поддержке: если в типовом документе логика заполнения ТЧ через входящие параметры не описана или конфигурация полностью закрыта от изменений, мы можем использовать **Расширение конфигурации**. Достаточно заимствовать в расширение модуль объекта документа и добавить метод &После("ОбработкаЗаполнения"), в котором выполнить чтение переданного массива структур и заполнить ТЧ стандартным способом.

---

Способ 2. Правильное использование ПолучитьФорму и преобразование данных формы

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

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

Разберем детальный шаблон реализации этого метода:


&НаКлиенте
Процедура ОткрытьИЗаполнитьФормуДокумента()

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

КонецПроцедуры

&НаСервереБезКонтекста
Процедура ЗаполнитьДокументНаСервере(ДанныеФормы)

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

КонецПроцедуры

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

---

Способ 3. Использование временного хранилища (для больших объемов данных)

В случае, когда необходимо передать большой объем данных (например, когда ТЧ содержит сотни строк с характеристиками, сериями или ценами), передача тяжелых массивов структур через параметры клиента может замедлить работу интерфейса. В таких ситуациях идеальным решением выступает **Временное хранилище**.

Давайте проанализируем алгоритм этого подхода:

  1. На сервере в текущем сеансе формируется ТаблицаЗначений с нужной структурой колонок.
  2. Таблица заполняется необходимыми данными (например, полученными через COM-соединение или HTTP-сервис).
  3. Таблица помещается во временное хранилище методом ПоместитьВоВременноеХранилище(ТаблицаДанных, УникальныйИдентификаторФормы). Полученный адрес передается на клиент.
  4. На клиенте открывается форма нового документа, в параметры которой передается этот АдресХранилища.
  5. В модуле формы нового документа (или в расширении формы) в обработчике ПриСозданииНаСервере данные извлекаются из хранилища и загружаются в ТЧ документа с помощью метода Объект.Товары.Загрузить(ПолучитьИзВременногоХранилища(Параметры.АдресХранилища)).

Этот способ работает максимально быстро и экономит сетевой трафик между клиентом и сервером приложения.

---

Несколько слов об отказе от устаревшего COMConnector

В ходе обсуждения на форуме коллеги справедливо заметили, что использование технологии COMConnector для связи баз в современном ландшафте 1С является устаревшим и несет в себе множество рисков:

Вместо COM-соединений для задач интеграции и получения данных «на лету» для заполнения форм рекомендуется использовать современные **HTTP-сервисы (REST API)** или **Web-сервисы (SOAP)**. База-источник публикует простой HTTP-сервис, а база-приемник отправляет быстрый запрос и получает легкий JSON-пакет, который затем легко парсится и преобразуется в структуру заполнения документа.

← На главную