Работа с динамически создаваемыми реквизитами в управляемом приложении 1С 8.3 — это мощный инструмент, который часто вызывает затруднения у разработчиков. Основная сложность заключается в том, что программно созданные реквизиты не видны компилятору на этапе написания кода, а их поведение отличается от статических объектов. В этой статье мы подробно разберем, как избежать ошибки «Переменная не определена», как правильно считывать данные из динамических таблиц и переносить их в объект базы данных.
Когда мы добавляем реквизит через метод ИзменитьРеквизиты(), система регистрирует его в памяти сервера, но в модуле формы вы не можете обратиться к нему просто по имени, например ТаблицаФормы. Для конфигуратора этого имени не существует, так как оно не прописано в метаданных формы.
Рассмотрим правильный способ обращения:
Для доступа к таким реквизитам следует использовать обращение через коллекцию ЭтаФорма или ЭтотОбъект с использованием квадратных скобок и строкового имени реквизита. Проанализируем пример:
// Вместо этого (вызовет ошибку):
Если ТаблицаФормы.Количество() > 0 Тогда ...
// Используем этот вариант:
ИмяРеквизита = "ТаблицаФормы";
Если ЭтаФорма[ИмяРеквизита].Количество() > 0 Тогда
// Логика обработки
КонецЕсли;
Этот метод позволяет системе найти реквизит по его текстовому идентификатору непосредственно во время выполнения программного кода.
Вторая частая проблема — попытка получить доступ к колонкам через строку таблицы. В обычной ТаблицаЗначений у строки нет свойства Колонки, а в управляемых формах мы имеем дело с типом ДанныеФормыЭлементКоллекции. Этот объект хранит значения, но не хранит структуру (метаданные) колонок.
Чтобы перебрать данные по колонкам в динамической таблице, нам нужно заранее знать их имена. Рассмотрим ситуацию, когда имена колонок хранятся в отдельном массиве или вспомогательном реквизите.
Наиболее надежный и «чистый» способ работы с динамическими данными — это их временная конвертация в полноценный объект 1С. Для таблиц это ТаблицаЗначений. Выясним, как это реализовать на практике в серверной процедуре.
Разберем по шагам алгоритм сохранения данных из программной таблицы в табличную часть Объекта:
Объект.Показатели.
&НаСервере
Процедура СохранитьДинамическуюТЗвОбъект()
// Преобразуем программный реквизит в обычную ТаблицуЗначений
// "ТаблицаФормы" — это имя, которое вы указали при ИзменитьРеквизиты
Попытка
ТЗ = РеквизитФормыВЗначение("ТаблицаФормы");
Исключение
Сообщить("Не удалось получить данные таблицы. Возможно, она еще не создана.");
Возврат;
КонецПопытки;
// Очищаем целевую табличную часть в Объекте (если это необходимо по логике)
Объект.Показатели.Очистить();
// Переносим данные
Для Каждого СтрокаТЗ Из ТЗ Цикл
НоваяСтрока = Объект.Показатели.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЗ);
// Если нужны специфические вычисления или отборы по колонкам:
Для Каждого Колонка Из ТЗ.Колонки Цикл
ИмяКолонки = Колонка.Имя;
Если ИмяКолонки <> "Показатель" Тогда
// Ваша логика обработки конкретных колонок
НоваяСтрока.Значение = СтрокаТЗ[ИмяКолонки];
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Важно помнить, что программные реквизиты существуют только в контексте формы. Проанализируем важный нюанс: при нажатии кнопки «Записать» управление передается на сервер. Если вы не перенесли данные из ЭтаФорма["ТаблицаФормы"] в Объект до момента фактической записи, данные, введенные пользователем в динамическую таблицу, не попадут в базу данных.
Где вызывать код сохранения?
Оптимальное место для вызова процедуры переноса данных — обработчик ПередЗаписьюНаСервере в модуле формы. В этот момент Объект уже доступен на сервере, но еще не записан в базу.
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Вызываем нашу функцию переноса данных
СохранитьДинамическуюТЗвОбъект();
КонецПроцедуры
При работе с методами ИзменитьРеквизиты() следуйте этим правилам, чтобы избежать нестабильной работы формы:
ИзменитьРеквизиты инициирует полную пересборку контекста формы. Старайтесь добавлять и удалять реквизиты одним вызовом, передавая заполненные массивы добавления и удаления одновременно.Новый РеквизитФормы всегда указывайте точный тип данных. Для колонок таблицы это критично для корректного отображения элементов управления (флажки, поля ввода дат и т.д.).Подведем итог: секрет успешной работы с программными реквизитами заключается в использовании динамического обращения через квадратные скобки для получения доступа и метода РеквизитФормыВЗначение для обработки данных привычными инструментами платформы 1С.