В практике разработки на платформе 1С:Предприятие 8.3 часто возникают задачи, требующие динамического изменения интерфейса. Одна из таких задач — программное добавление колонок в таблицу значений (реквизит формы) и отображение этих данных в таблице на форме. Однако здесь разработчики часто сталкиваются с неочевидными ограничениями платформы. Для решения этой задачи можно использовать руководство по программному выводу произвольной таблицы значений на управляемую форму.
В этой статье мы подробно разберем ситуацию, когда необходимо не просто добавить новые данные, но и перенаправить существующие элементы формы на эти новые источники. Рассмотрим, почему возникает ошибка при попытке изменить свойство ПутьКДанным, и предложим правильный алгоритм решения.
Представим сценарий: у нас есть таблица на форме, созданная в конфигураторе (дизайнере форм). В процессе работы (например, при нажатии кнопки) мы модифицируем запрос и получаем таблицу с новым набором колонок. Наша цель — отобразить эти новые данные в тех же колонках таблицы, которые уже есть на форме.
Логичным кажется следующий путь:
ПутьКДанным, указывая на новую добавленную колонку.Однако при попытке реализовать этот алгоритм, а именно на этапе присвоения Элемент.ПутьКДанным = "ТЗ.НоваяКолонка", платформа выдает ошибку или свойство просто не меняется (доступно только для чтения).
Разберемся, почему так происходит. В управляемых формах существует жесткое разделение между данными (Реквизиты формы) и интерфейсом (Элементы формы).
Важное ограничение платформы: Свойство ПутьКДанным (DataPath) доступно для записи только у тех элементов формы, которые были созданы программно. Если элемент был добавлен в форму в режиме Конфигуратора, его связь с данными жестко фиксируется при компиляции формы. В режиме Предприятия изменить привязку такого элемента к данным нельзя.
Поскольку мы выяснили, что переиспользовать старые "дизайнерские" элементы для отображения принципиально новых реквизитов нельзя, нам остается единственный надежный путь — создание новых элементов интерфейса. Старые элементы при этом необходимо скрыть или удалить (если они созданы программно). При необходимости можно использовать пример динамического добавления и удаления элементов формы.
Давайте пошагово разберем алгоритм реализации этой задачи.
Прежде чем что-то выводить на форму, нам нужно создать место для хранения данных. В управляемых формах нельзя просто добавить колонку в объект ТаблицаЗначений, нужно модифицировать структуру реквизитов формы.
Для этого используется массив объектов типа РеквизитФормы.
// Массив для добавляемых реквизитов
ДобавляемыеРеквизиты = Новый Массив;
// Предположим, наша таблица на форме называется "Товары"
// Создаем описание новой колонки "НоваяЦена"
НовыйРеквизит = Новый РеквизитФормы(
"НоваяЦена", // Имя реквизита
Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)), // Тип
"Товары", // Путь (имя родительского реквизита - нашей таблицы)
"Новая цена" // Заголовок
);
ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
Самый ресурсоемкий, но необходимый метод — ИзменитьРеквизиты. Он перестраивает структуру данных формы. Именно после его вызова форма "узнает" о существовании новых колонок в таблице "Товары".
// Применяем изменения. Второй параметр (удаляемые реквизиты) оставляем пустым, если ничего не удаляем.
ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
Теперь, когда данные (реквизиты) существуют, мы можем создать визуальные элементы для их отображения. Мы будем использовать метод Элементы.Добавить().
Здесь важно правильно указать родителя для нового элемента. Если мы добавляем колонку в таблицу, родителем будет сама таблица формы.
// Находим родителя - таблицу на форме
ЭлементТаблица = Элементы.Товары;
// Добавляем новое поле ввода в эту таблицу
НовыйЭлемент = Элементы.Добавить(
"ТоварыНоваяЦена", // Уникальное имя элемента интерфейса
Тип("ПолеФормы"), // Тип элемента
ЭлементТаблица // Родитель
);
// Устанавливаем вид поля (ПолеВвода, ПолеНадписи и т.д.)
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
Так как элемент НовыйЭлемент создан программно, свойство ПутьКДанным у него доступно для записи. Мы связываем его с реквизитом, который создали на Шаге 1.
// Привязываем элемент к реквизиту
НовыйЭлемент.ПутьКДанным = "Товары.НоваяЦена";
Теперь у нас на форме есть и старая колонка (созданная в конфигураторе), и новая (программная). Чтобы пользователь не заметил подмены, нам нужно:
// Находим старую колонку
СтараяКолонка = Элементы.ТоварыЦена; // Имя элемента в конфигураторе
// Перемещаем новую колонку перед старой
Элементы.Переместить(НовыйЭлемент, ЭлементТаблица, СтараяКолонка);
// Скрываем старую колонку (удалить её нельзя, так как она из конфигуратора)
СтараяКолонка.Видимость = Ложь;
// Настраиваем заголовок новой колонки, чтобы он совпадал со старым или был новым
НовыйЭлемент.Заголовок = "Цена (обновлено)";
При использовании такого подхода необходимо помнить о нескольких важных моментах, которые могут повлиять на работу формы.
Если у старой колонки были назначены обработчики событий (например, ПриИзменении), новая колонка их не унаследует. Вам придется назначать их программно, используя метод УстановитьДействие.
// Назначение обработчика события "ПриИзменении"
// "ТоварыНоваяЦенаПриИзменении" — это имя экспортной процедуры в модуле формы
НовыйЭлемент.УстановитьДействие("ПриИзменении", "ТоварыНоваяЦенаПриИзменении");
Если в форме настроено условное оформление (например, красить цены в красный цвет, если они меньше себестоимости), оно привязано к конкретным именам полей или элементов. Поскольку мы создали новые элементы и реквизиты, старое условное оформление на них действовать не будет. Необходимо программно добавлять новые элементы в коллекцию УсловноеОформление.
Когда пользователь меняет ширину колонок или их порядок, эти настройки сохраняются в привязке к именам элементов. Так как мы генерируем новые имена элементов (например, добавляя суффикс или счетчик), пользовательские настройки могут сбрасываться при каждом переоткрытии формы или генерации колонок. Рекомендуется использовать стабильные имена для программных элементов, если набор колонок предсказуем.
Подведем итог. Если перед вами стоит задача изменить источник данных для колонок таблицы на управляемой форме:
ПутьКДанным у элементов, созданных в Конфигураторе — это технически невозможно.ИзменитьРеквизиты для создания новых полей данных.Элементы.Добавить.Видимость.Такой подход обеспечивает стабильную работу механизма управляемых форм и позволяет реализовывать динамические интерфейсы любой сложности.