Как получить доступ к нереквизиту (колонке формы) табличной части в управляемой форме 1С для сравнения с реквизитом?

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

При разработке управляемых форм в 1С мы часто сталкиваемся с необходимостью отображать и обрабатывать данные, которые не являются прямыми реквизитами объекта базы данных, но при этом добавлены в табличную часть формы. Такие колонки в конфигураторе иногда называют "красными реквизитами" из-за их визуального отличия. Возникает вопрос: как получить доступ к значению такого нереквизита для каждой строки табличной части, чтобы, например, сравнить его с обычным реквизитом объекта?

Прямой доступ к нереквизиту через ДанныеФормыКоллекция

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

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

Рассмотрим пример кода, который демонстрирует, как мы можем получить доступ к нереквизиту:


&НаКлиенте
Процедура ПриЗагрузкеДанныхНаСервере(Отказ)
    // Предположим, Объект.ТЧ - это табличная часть формы,
    // связанная с данными типа ДанныеФормыКоллекция.
    // Поле1 - реквизит объекта, Поле2 - нереквизит формы.

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

Важное предостережение: Особенности "красных реквизитов"

Хотя доступ к нереквизитам прост, очень важно понимать их ключевую особенность: несохраняемость. Эти "красные реквизиты" существуют только в контексте самой формы и не хранятся в базе данных как часть объекта. Тем не менее, существует способ реализовать программное создание колонок и сохранение значений в этом же документе.

  1. Сброс значений: При записи объекта на сервере или при любом другом серверном вызове, который приводит к повторному считыванию данных объекта с сервера, значения "красных реквизитов" будут сброшены. Они либо обнулятся, либо будут затерты, поскольку они не являются частью постоянных данных объекта.
  2. Необходимость перезаполнения: Если нам необходимо, чтобы значения этих реквизитов сохранялись между серверными вызовами или после записи объекта, нам потребуется самостоятельно реализовать механизм их перезаполнения. Это может быть довольно трудоемко и требует внимательного подхода к архитектуре формы, включая реализацию сохранения настроек формы.

Альтернативы и лучшие практики для временного хранения данных

Если данные, которые мы храним в "красных реквизитах" (например, когда реализуется флажок в динамическом списке), должны переживать серверные вызовы или быть доступными за пределами текущего клиентского контекста, рассмотрим следующие альтернативы:

  1. Временное хранилище: Для передачи данных между клиентом и сервером или для временного хранения данных, не предназначенных для базы данных, мы можем использовать механизм (ссылка на документацию ITS). Данные помещаются во временное хранилище на сервере с помощью функции ПоместитьВоВременноеХранилище() и могут быть получены по адресу хранилища. Время жизни данных во временном хранилище можно привязать к форме.
  2. Реквизиты объекта: Если Поле2 должно сохраняться вместе с документом или справочником, то самым правильным решением будет создать его как обычный реквизит табличной части соответствующего объекта метаданных в конфигураторе. Это обеспечит его автоматическое сохранение и доступность.
  3. Таблица значений на сервере: Для работы с временными данными в серверном контексте мы можем использовать обычную ТаблицуЗначений. При необходимости выполнить программный вывод произвольной таблицы значений на управляемую форму, мы можем загрузить ее в ДанныеФормыКоллекция.

Взаимодействие клиента и сервера

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

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

← На главную