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

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

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

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

Для начала проанализируем ситуацию. В управляемом приложении данные на форме представлены типом ДанныеФормыКоллекция (если речь идет о табличной части). В отличие от серверного объекта ТаблицаЗначений или объекта метаданных ТабличнаяЧасть, у типа ДанныеФормыКоллекция нет свойства Колонки. Именно поэтому при попытке выполнить код Объект.ИмяТЧ.Колонки.Найти() система выдает ошибку: "Метод объекта не обнаружен".

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

Способ 1. Проверка через метаданные (самый надежный)

Если наша задача — выяснить, существует ли реквизит в структуре табличной части объекта (документа, справочника или обработки), лучше всего обратиться к метаданным. Этот метод работает на сервере и является самым быстрым, так как не требует перебора данных.

Разберем пример кода для проверки в модуле формы:


// Проверяем наличие реквизита "Участок" в табличной части "ОПРиСМП"
ИмяТЧ = "ОПРиСМП";
ИмяКолонки = "Участок";

Если Метаданные().ТабличныеЧасти[ИмяТЧ].Реквизиты.Найти(ИмяКолонки) <> Неопределено Тогда
    // Колонка существует, можем выполнять логику
    Сообщить("Колонка найдена в метаданных.");
КонецЕсли;

Если же мы работаем с произвольным объектом, можно использовать полный путь:


ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени("Документ.РеализацияТоваровУслуг");
Если ОбъектМетаданных.ТабличныеЧасти.Товары.Реквизиты.Найти("Склад") <> Неопределено Тогда
    // Логика обработки
КонецЕсли;

Способ 2. Использование метода «Свойство» для строки таблицы

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

Проанализируем ситуацию на примере кода:


Для Каждого СтрокаТЧ Из Объект.ОПРиСМП Цикл
    // Проверяем, есть ли у строки свойство (колонка) с нужным именем
    ИмяКолонки = ВыборкаДетали.Участок; // Предположим, имя колонки приходит динамически
    
    Если СтрокаТЧ.Свойство(ИмяКолонки) Тогда
        // Заполняем данные только если колонка существует
        СтрокаТЧ[ИмяКолонки] = ВыборкаДетали.Допуск;
    Иначе
        // Обработка ситуации, когда колонки нет
    КонецЕсли;
КонецЦикла;

Важный момент: метод Свойство() позволяет избежать фатальных ошибок при обращении к несуществующим реквизитам и делает код более устойчивым.

Способ 3. Получение списка всех реквизитов формы

Иногда нам нужно получить полный список всех доступных колонок для программного анализа. В управляемых формах для этого существует встроенный метод ПолучитьРеквизиты(). Он возвращает массив объектов типа РеквизитФормы.

Рассмотрим, как это реализовать:


// Получаем массив реквизитов конкретной табличной части
МассивРеквизитов = ПолучитьРеквизиты("Объект.ОПРиСМП");

Для Каждого ТекущийРеквизит Из МассивРеквизитов Цикл
    Если ТекущийРеквизит.Имя = "Участок" Тогда
        Сообщить("Колонка присутствует в коллекции данных формы.");
    КонецЕсли;
КонецЦикла;

Этот метод особенно полезен, если на форме создаются программные реквизиты, которых нет в метаданных самого объекта базы данных.

Способ 4. Проверка видимости через элементы формы

Бывают случаи, когда колонка в данных (в объекте) есть, но нам нужно понять, выведена ли она пользователю на экран. В этом случае мы должны искать не в данных, а в коллекции Элементы.

Выясним причину возможной путаницы: имя элемента на форме может не совпадать с именем реквизита в табличной части (например, элемент может называться ОПРиСМПУчасток). Проверим наличие элемента так:


ИмяЭлемента = "ОПРиСМП" + "Участок"; // Типовое именование при создании формой
Если Элементы.Найти(ИмяЭлемента) <> Неопределено Тогда
    // Элемент (колонка) отображается на форме
    Элементы[ИмяЭлемента].Видимость = Истина;
КонецЕсли;

Способ 5. Универсальный метод с использованием БСП

Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), рекомендуется использовать готовые функции из общего модуля ОбщегоНазначения. Это "золотой стандарт" разработки, который обеспечивает максимальную совместимость.

Посмотрим на пример использования функции:


Если ОбщегоНазначения.ЕстьРеквизитИлиСвойствоОбъекта(Объект.ОПРиСМП, "Участок") Тогда
    // Выполняем действия
КонецЕсли;

Эта функция универсальна: она корректно обрабатывает и структуры, и объекты метаданных, и коллекции данных формы, скрывая внутри себя все сложности проверок на типы данных.

Резюме и рекомендации

Подводя итог, выберем оптимальный путь для вашей ситуации:

  1. Если вы пишете серверный код заполнения — используйте Метаданные().
  2. Если вы работаете внутри цикла по строкам — используйте метод Строка.Свойство("ИмяКолонки").
  3. Если нужно проверить наличие элемента в интерфейсе — используйте Элементы.Найти().
  4. Если используется БСП — всегда отдавайте предпочтение функции ЕстьРеквизитИлиСвойствоОбъекта().

Помните, что прямая выгрузка табличной части в Таблицу Значений (метод Выгрузить()) только ради проверки колонок — это ресурсоемкая операция, которой следует избегать, если вы заботитесь о производительности вашей системы.

← На главную