Существует ли в БСП стандартный интерфейс для программного добавления элементов формы?

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

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

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

Поиск стандартного инструмента в БСП

Часто возникает желание использовать код наподобие такого:


// Гипотетический пример, которого ищет разработчик
ГенерацияФорм.ДобавитьПолеВвода(ЭтаФорма, "НовоеПоле", "ПутьКДанным");

Мы проанализировали документацию БСП и структуру типовых конфигураций (ERP 2.5, УТ 11). Важно понимать следующий факт: в БСП отсутствует единый универсальный экспортный модуль-обертка для создания произвольных элементов формы.

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

Однако, существуют частные случаи, которые могут ввести в заблуждение:

  1. Подсистема "Варианты отчетов" (СКД): Модули вроде КомпоновкаДанныхКлиентСервер содержат методы для работы с настройками отчетов. Но они предназначены для работы с деревом настроек СКД, а не с элементами управляемой формы напрямую.
  2. Подсистема "Свойства": Механизм дополнительных реквизитов и сведений (БСП) имеет мощный движок динамического создания полей. Он находится в модулях типа УправлениеСвойствамиПереопределяемый. Использовать его для создания своих произвольных полей сложно и архитектурно неверно, если только вы не добавляете именно дополнительные реквизиты.

Метод поиска решения через исходный код конфигурации

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

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

Используйте глобальный поиск по строке: "#Область Формы" (в английской локализации #Region Forms).

В типовых конфигурациях (ERP, УТ) этот тег часто используется для группировки процедур, отвечающих за программную модификацию интерфейса. Обычно такие процедуры находятся в:

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

Правильный алгоритм программного добавления элементов

Разберем классический, "нативный" способ добавления элементов на форму, который является стандартом де-факто при отсутствии специализированных библиотек. Этот процесс состоит из двух этапов: изменение состава реквизитов (данных) и создание элементов интерфейса (визуализация).

Этап 1: Добавление реквизита формы

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


&НаСервере
Процедура ДобавитьРеквизитПрограммно()
    
    // Описываем тип будущего реквизита
    МассивТипов = Новый Массив;
    МассивТипов.Добавить(Тип("Строка"));
    
    // Создаем описание типа (Квалификаторы строки, числа и т.д.)
    ОписаниеТипаСтрока = Новый ОписаниеТипов(МассивТипов, , Новый КвалификаторыСтроки(100));
    
    // Создаем массив добавляемых реквизитов
    ДобавляемыеРеквизиты = Новый Массив;
    ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы("НашНовыйРеквизит", ОписаниеТипаСтрока, "", "Заголовок реквизита"));
    
    // Применяем изменения к форме
    ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
    
КонецПроцедуры

Этап 2: Создание элемента формы

После того как реквизит создан, мы можем вывести его на форму. Используем коллекцию ЭтаФорма.Элементы.


&НаСервере
Процедура СоздатьЭлементИнтерфейса()
    
    // Определяем родителя (куда добавить элемент). 
    // Если нужно добавить в корень, используем ЭтаФорма
    РодительскаяГруппа = Элементы.ГруппаТовары; // Пример существующей группы
    
    // Добавляем новый элемент
    // УникальноеИмя - должно быть уникальным в пределах формы
    // Тип("ПолеФормы") - указываем класс элемента UI
    НовыйЭлемент = Элементы.Добавить("НашеНовоеПолеUI", Тип("ПолеФормы"), РодительскаяГруппа);
    
    // Настраиваем свойства
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
    НовыйЭлемент.ПутьКДанным = "НашНовыйРеквизит"; // Связываем с созданным ранее реквизитом
    НовыйЭлемент.Заголовок = "Дополнительное примечание";
    НовыйЭлемент.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Лево;
    
КонецПроцедуры

Важные нюансы реализации

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

  1. Уникальность имен: При динамическом создании элементов всегда следите за уникальностью их имен. Если вы создаете элементы в цикле, добавляйте к имени индекс или используйте GUID. Попытка создать элемент с именем, которое уже существует, вызовет исключение.
  2. Момент вызова: Идеальное место для модификации структуры формы — событие ПриСозданииНаСервере.
    • Если менять форму в ПриСозданииНаСервере, платформа отрисует её сразу в целевом виде.
    • Если менять форму в ПриЧтенииНаСервере или позже, это может вызвать перестроение интерфейса и лишние затраты ресурсов.
    • Категорически не рекомендуется менять структуру реквизитов (метод ИзменитьРеквизиты) внутри обработчиков команд (нажатия кнопок) без крайней необходимости, так как это переинициализирует контекст формы.
  3. Обработчики событий: Если создаваемому программно элементу нужно назначить действие (например, ПриИзменении), используется метод УстановитьДействие. НовыйЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_ПриИзменении"); Важно: Процедура-обработчик (Подключаемый_ПриИзменении) должна существовать в модуле формы и быть экспортной (или доступной для вызова в данном контексте).

Современная альтернатива: Расширения конфигурации

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

Лучшей практикой является использование Расширений конфигурации:

  1. Добавьте форму в расширение.
  2. Визуально в редакторе добавьте нужные поля и группы.
  3. При необходимости управляйте их видимостью (Элементы.Поле.Видимость = Ложь) в коде, что гораздо проще и быстрее, чем создавать их с нуля программно.

Программное создание через код (как описано выше) оправдано только в высокодинамичных сценариях, например:

Резюме

Подведем итоги нашего анализа:

← На главную