К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как создать форму программно в 1С

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

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

Важно понимать ограничение платформы: создать «с нуля» форму, которой нет в конфигурации, напрямую нельзя. Практический приём — использовать пустую форму общей формы или форму обработки как каркас и наполнять её реквизитами и элементами программно. Либо генерировать форму внешней обработки, где вся структура строится кодом.

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

Способы программной работы с формами

В управляемом приложении есть три принципиально разных задачи, которые часто путают. Первая — открыть уже описанную в конфигураторе форму справочника, документа или обработки с нужными параметрами. Вторая — получить объект формы в переменную без отображения, чтобы обратиться к её данным. Третья — динамически достроить форму: добавить поля, таблицы, кнопки, которых нет в статическом описании.

Для открытия формы используется ОткрытьФорму() — асинхронный по логике интерфейса метод, который показывает форму пользователю. Для получения объекта без показа — ПолучитьФорму(). Динамическое построение выполняется только на сервере в обработчике ПриСозданииНаСервере(), потому что именно там доступно изменение состава реквизитов формы.

Сравнение подходов

ОткрытьФорму()

Подходит для показа формы пользователю с параметрами. Не возвращает управление в вызывающий код до закрытия, если открыта модально.

ПолучитьФорму()

Возвращает объект формы в переменную для программного доступа к данным. Форма не показывается, пока не вызван Открыть().

Динамическое построение

Полный контроль над составом элементов из кода. Требует пустой формы-каркаса и больше труда на сопровождение.

Открытие существующей формы с параметрами

Самая частая задача — открыть форму элемента справочника или документа и передать туда значения. Параметры формируются структурой, где ключи соответствуют именам параметров формы или стандартным ключам: Ключ (ссылка на объект), ЗначенияЗаполнения, Отбор для форм списка.

&НаКлиенте

Процедура ОткрытьКарточкуКлиента(Команда)

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("Ключ", ТекущийКлиент);

ОткрытьФорму("Справочник.Контрагенты.Форма.ФормаЭлемента", ПараметрыФормы);

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

Для формы списка с отбором по владельцу или периоду используется параметр Отбор — структура, где ключи совпадают с именами полей динамического списка:

&НаКлиенте

Процедура ПоказатьДокументыКонтрагента(Команда)

Отбор = Новый Структура("Контрагент", ТекущийКонтрагент);

ПараметрыФормы = Новый Структура("Отбор", Отбор);

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

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

Если нужно получить результат выбора из открываемой формы, используйте ОткрытьФорму() с описанием оповещения — модальный вызов с возвратом значения через обработчик. Это стандартный механизм вместо устаревшего ОткрытьФормуМодально(), который не поддерживается в веб-клиенте и блокируется современными браузерными ограничениями.

Создание формы обработки программно: каркас

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

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

// 1. Добавляем реквизиты

ДобавляемыеРеквизиты = Новый Массив;

ДобавляемыеРеквизиты.Добавить(

Новый РеквизитФормы("Комментарий",

Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200))));

ДобавляемыеРеквизиты.Добавить(

Новый РеквизитФормы("Количество",

Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 2))));

ИзменитьРеквизиты(ДобавляемыеРеквизиты);

// 2. Добавляем элементы и связываем с реквизитами

ЭлементКомментарий = Элементы.Добавить("Комментарий", Тип("ПолеФормы"));

ЭлементКомментарий.Вид = ВидПоляФормы.ПолеВвода;

ЭлементКомментарий.ПутьКДанным = "Комментарий";

ЭлементКомментарий.Заголовок = "Комментарий";

ЭлементКоличество = Элементы.Добавить("Количество", Тип("ПолеФормы"));

ЭлементКоличество.Вид = ВидПоляФормы.ПолеВвода;

ЭлементКоличество.ПутьКДанным = "Количество";

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

Ключевой момент — метод ИзменитьРеквизиты(). Он принимает два массива: добавляемые и удаляемые реквизиты, и вызывается только на сервере до обращения к элементам. Если попытаться создать элемент с ПутьКДанным, указывающим на несуществующий реквизит, платформа выдаст ошибку при открытии формы.

Порядок построения формы из кода
  1. 1
    Создайте обработку и добавьте ей пустую форму в конфигураторе
  2. 2
    В ПриСозданииНаСервере() сформируйте массив объектов РеквизитФормы с именами и типами
  3. 3
    Вызовите ИзменитьРеквизиты() для добавления реквизитов в форму
  4. 4
    Добавьте элементы через Элементы.Добавить() и задайте Вид и ПутьКДанным
  5. 5
    Назначьте команды и обработчики через УстановитьДействие()
  6. 6
    Откройте форму и проверьте ввод, сохранение и отсутствие ошибок в журнале регистрации

Динамическое добавление таблицы и команд

Табличная часть строится по той же логике: сначала реквизит типа ТаблицаЗначений, затем его колонки как подчинённые реквизиты, затем элемент ТаблицаФормы и поля колонок.

&НаСервере

Процедура ДобавитьТаблицуТоваров()

Реквизиты = Новый Массив;

Реквизиты.Добавить(Новый РеквизитФормы("Товары",

Новый ОписаниеТипов("ТаблицаЗначений")));

Реквизиты.Добавить(Новый РеквизитФормы("Номенклатура",

Новый ОписаниеТипов("СправочникСсылка.Номенклатура"), "Товары"));

Реквизиты.Добавить(Новый РеквизитФормы("Цена",

Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)), "Товары"));

ИзменитьРеквизиты(Реквизиты);

Таблица = Элементы.Добавить("Товары", Тип("ТаблицаФормы"));

Таблица.ПутьКДанным = "Товары";

КолонкаНоменклатура = Элементы.Добавить("ТоварыНоменклатура", Тип("ПолеФормы"), Таблица);

КолонкаНоменклатура.Вид = ВидПоляФормы.ПолеВвода;

КолонкаНоменклатура.ПутьКДанным = "Товары.Номенклатура";

КолонкаЦена = Элементы.Добавить("ТоварыЦена", Тип("ПолеФормы"), Таблица);

КолонкаЦена.Вид = ВидПоляФормы.ПолеВвода;

КолонкаЦена.ПутьКДанным = "Товары.Цена";

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

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

Команда = Команды.Добавить("ЗаполнитьЦены");

Команда.Действие = "ЗаполнитьЦены";

Команда.Заголовок = "Заполнить цены";

Кнопка = Элементы.Добавить("КнопкаЗаполнить", Тип("КнопкаФормы"), Таблица.КоманднаяПанель);

Кнопка.ИмяКоманды = "ЗаполнитьЦены";

Обычные формы: чем отличается подход

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

Процедура ПриОткрытии()

НовоеПоле = ЭлементыФормы.Добавить(Тип("ПолеВвода"), "ПолеКомментарий", Истина);

НовоеПоле.Верх = 10;

НовоеПоле.Лево = 10;

НовоеПоле.Ширина = 300;

НовоеПоле.Данные = "Комментарий";

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

Координатная привязка (Верх, Лево, Ширина) вместо компоновки — главное внешнее отличие. Если конфигурация работает в обычном режиме, учитывайте, что динамически добавленные элементы не сохраняются между сеансами и должны пересоздаваться при каждом открытии формы.

Типичные ошибки и как их избежать

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

Типичные ошибки
01
Вызов ИзменитьРеквизиты() в клиентском контексте — метод доступен только на сервере, код падает с ошибкой о несуществующем методе
02
Создание элемента до добавления реквизита — ошибка «Поле не найдено» при открытии формы
03
Установка ПутьКДанным с опечаткой в имени реквизита — поле отображается, но не связано с данными и не сохраняет ввод
04
Добавление обработчика через УстановитьДействие() на несуществующую процедуру — ошибка возникает только при нажатии кнопки
05
Использование ОткрытьФормуМодально() в веб-клиенте — метод не поддерживается, логика выбора ломается

Отдельная группа ошибок — работа с данными после закрытия формы. Объект управляемой формы нельзя хранить в переменных между серверными вызовами: форма сериализуется, и ссылки на её элементы теряют актуальность. Передавайте между вызовами примитивные данные и ссылки на объекты базы, а не объекты формы.

Проверка результата

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

Контрольные точки

Как проверить результат

Открытие формы
Норма

Форма открывается без сообщений об ошибках, все элементы видны

Тревожный признак

Ошибка «Поле не найдено» или пустая форма — нарушен порядок создания реквизитов и элементов

Ввод в поля
Норма

Введённые значения доступны в серверных процедурах через ЭтаФорма.ИмяРеквизита

Тревожный признак

Поле визуально заполняется, но на сервере значение пустое — не задан или неверен ПутьКДанным

Работа команд
Норма

Нажатие кнопки вызывает назначенную процедуру

Тревожный признак

Ошибка «Процедура не обнаружена» — имя в УстановитьДействие() не совпадает с процедурой модуля

Повторное открытие
Норма

Форма пересоздаётся корректно, без дублирования элементов

Тревожный признак

Ошибка о существующем реквизите — динамическое построение вызывается повторно для той же формы

Полезный приём отладки — временно выводить состав реквизитов и элементов в сообщения внутри ПриСозданииНаСервере(), чтобы убедиться, что структура построена именно в том виде, который ожидается. После отладки такой вывод удаляют, чтобы не засорять интерфейс пользователя.

Частые вопросы

Можно ли создать форму вообще без конфигуратора, только кодом?

Напрямую — нет: платформа требует наличия объекта формы в конфигурации. Практическое решение — пустая форма обработки или общая форма, которая наполняется реквизитами и элементами в ПриСозданииНаСервере(). Для внешних инструментов используют внешнюю обработку с аналогичным каркасом.

Как передать данные из открываемой формы обратно в вызывающую?

Используйте ОткрытьФорму() с параметром ОписаниеОповещенияОЗакрытии — процедура-обработчик получит значение, переданное через Закрыть(Результат) в открываемой форме. Альтернатива — Оповестить() и обработчик ОбработкаОповещения() в вызывающей форме.

Почему динамически добавленные поля не сохраняют введённые значения?

Чаще всего свойство ПутьКДанным не задано или указывает на несуществующий реквизит. Проверьте, что реквизит добавлен через ИзменитьРеквизиты() до создания элемента и что имена совпадают посимвольно, включая регистр букв в длинных составных именах.

Можно ли изменить состав элементов формы после её открытия?

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

Чем ПолучитьФорму() отличается от ОткрытьФорму()?

ПолучитьФорму() возвращает объект формы в переменную без отображения — для программного доступа к данным и экспортным процедурам формы. ОткрытьФорму() сразу показывает форму пользователю и не возвращает сам объект. Для показа полученной формы вызывают её метод Открыть().

Работает ли динамическое построение форм в веб-клиенте?

Да, управляемые формы с программно добавленными реквизитами и элементами корректно работают в веб-клиенте. Ограничения касаются модальных вызовов и некоторых методов тонкого клиента — используйте асинхронные аналоги с описаниями оповещений.

Итог

Что важно запомнить

Существующие формы открывают через ОткрытьФорму() с параметрами, программные формы строят на пустом каркасе: сначала ИзменитьРеквизиты() на сервере, затем Элементы.Добавить() с корректным ПутьКДанным. Проверяйте ввод данных, работу команд и повторное открытие — большинство ошибок проявляется именно там.