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

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

Работа с динамически создаваемыми реквизитами в управляемом приложении 1С 8.3 — это мощный инструмент, который часто вызывает затруднения у разработчиков. Основная сложность заключается в том, что программно созданные реквизиты не видны компилятору на этапе написания кода, а их поведение отличается от статических объектов. В этой статье мы подробно разберем, как избежать ошибки «Переменная не определена», как правильно считывать данные из динамических таблиц и переносить их в объект базы данных.

Почему возникает ошибка «Переменная не определена»?

Когда мы добавляем реквизит через метод ИзменитьРеквизиты(), система регистрирует его в памяти сервера, но в модуле формы вы не можете обратиться к нему просто по имени, например ТаблицаФормы. Для конфигуратора этого имени не существует, так как оно не прописано в метаданных формы.

Рассмотрим правильный способ обращения:

Для доступа к таким реквизитам следует использовать обращение через коллекцию ЭтаФорма или ЭтотОбъект с использованием квадратных скобок и строкового имени реквизита. Проанализируем пример:


// Вместо этого (вызовет ошибку):
Если ТаблицаФормы.Количество() > 0 Тогда ...

// Используем этот вариант:
ИмяРеквизита = "ТаблицаФормы";
Если ЭтаФорма[ИмяРеквизита].Количество() > 0 Тогда
    // Логика обработки
КонецЕсли;

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

Различие между строкой таблицы значений и ДанныеФормыЭлементКоллекции

Вторая частая проблема — попытка получить доступ к колонкам через строку таблицы. В обычной ТаблицаЗначений у строки нет свойства Колонки, а в управляемых формах мы имеем дело с типом ДанныеФормыЭлементКоллекции. Этот объект хранит значения, но не хранит структуру (метаданные) колонок.

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

Эффективный метод: Использование РеквизитФормыВЗначение

Наиболее надежный и «чистый» способ работы с динамическими данными — это их временная конвертация в полноценный объект 1С. Для таблиц это ТаблицаЗначений. Выясним, как это реализовать на практике в серверной процедуре.

Разберем по шагам алгоритм сохранения данных из программной таблицы в табличную часть Объекта:

  1. Выполняем конвертацию данных формы в реальную таблицу значений.
  2. Перебираем полученную таблицу циклом.
  3. Заполняем соответствующие строки и колонки в табличной части Объект.Показатели.

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

Особенности жизненного цикла программных реквизитов

Важно помнить, что программные реквизиты существуют только в контексте формы. Проанализируем важный нюанс: при нажатии кнопки «Записать» управление передается на сервер. Если вы не перенесли данные из ЭтаФорма["ТаблицаФормы"] в Объект до момента фактической записи, данные, введенные пользователем в динамическую таблицу, не попадут в базу данных.

Где вызывать код сохранения?

Оптимальное место для вызова процедуры переноса данных — обработчик ПередЗаписьюНаСервере в модуле формы. В этот момент Объект уже доступен на сервере, но еще не записан в базу.


&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    // Вызываем нашу функцию переноса данных
    СохранитьДинамическуюТЗвОбъект();
КонецПроцедуры

Советы по управлению динамическими реквизитами

При работе с методами ИзменитьРеквизиты() следуйте этим правилам, чтобы избежать нестабильной работы формы:

Подведем итог: секрет успешной работы с программными реквизитами заключается в использовании динамического обращения через квадратные скобки для получения доступа и метода РеквизитФормыВЗначение для обработки данных привычными инструментами платформы 1С.

← На главную