Как проверить свойство «ЭтоГруппа» в тонком клиенте 1С?

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

При переходе с обычных форм на управляемые начинающие разработчики часто сталкиваются с проблемой: при попытке проверить, является ли элемент справочника группой непосредственно на клиенте, система выдает ошибку: «Поле объекта не обнаружено (ЭтоГруппа)». В этой статье мы подробно разберем, почему так происходит, как правильно организовать проверку и какими методами можно оптимизировать этот процесс для повышения производительности системы.

Почему возникает ошибка при обращении к реквизиту на клиенте?

Для начала проанализируем ситуацию с точки зрения архитектуры платформы 1С:Предприятие 8. В тонком клиенте переменная, содержащая ссылку на объект базы данных (например, СправочникСсылка.Контрагенты), является лишь идентификатором (GUID). Она не содержит в себе данных самого объекта — ни наименования, ни кода, ни тем более признака ЭтоГруппа.

В «толстом» клиенте обращение через точку от ссылки (например, Контрагент.ЭтоГруппа) приводило к неявному серверному вызову: платформа сама «ходила» в базу, считывала объект и возвращала значение. В тонком клиенте такие неявные вызовы запрещены для минимизации трафика и повышения стабильности работы в распределенных сетях. Поэтому любое обращение к данным через точку от ссылки на стороне клиента всегда будет приводить к исключению.

Решение 1: Использование серверной функции

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

Разберем пример кода:


&НаКлиенте
Процедура ПроверитьОбъект(Команда)
    СсылкаНаКонтрагента = Объект.Контрагент;
    Если ОбъектЯвляетсяГруппой(СсылкаНаКонтрагента) Тогда
        Сообщить("Выбранная позиция является группой!");
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ОбъектЯвляетсяГруппой(Ссылка)
    // На сервере нам доступны данные объекта через точку от ссылки
    Возврат Ссылка.ЭтоГруппа;
КонецФункции

В данном примере мы передаем ссылку на сервер, там платформа обращается к базе данных, считывает признак ЭтоГруппа и возвращает булево значение обратно на клиент.

Решение 2: Использование функций Библиотеки стандартных подсистем (БСП)

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

Рассмотрим вариант вызова:


&НаКлиенте
Процедура ПроверитьЧерезБСП(Команда)
    // Вызов серверной функции общего модуля напрямую с клиента
    ЭтоГруппа = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Объект.Контрагент, "ЭтоГруппа");
    
    Если ЭтоГруппа Тогда
        // Ваша логика
    КонецЕсли;
КонецПроцедуры

Преимущество этого метода: вам не нужно писать свои функции в каждом модуле формы. Однако помните, что под капотом всё равно происходит серверный вызов. Если вам нужно проверить сразу несколько объектов (например, в цикле), используйте функцию ОбщегоНазначения.ЗначенияРеквизитовОбъектов(), которая позволяет получить данные для массива ссылок за один «поход» на сервер.

Решение 3: Оптимизация через данные динамического списка

Часто проверка ЭтоГруппа требуется в формах списка или выбора. В этом случае мы можем избежать дополнительных запросов к серверу, проанализировав данные, которые уже загружены в элементы формы.

Если справочник иерархический, колонка ЭтоГруппа обычно присутствует в данных динамического списка по умолчанию. Мы можем обратиться к ней через свойство ТекущиеДанные:


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    ДанныеСтроки = Элементы.Список.ТекущиеДанные;
    
    Если ДанныеСтроки <> Неопределено Тогда
        Если ДанныеСтроки.ЭтоГруппа Тогда
            Сообщить("Выбрана группа, выбор запрещен!");
            СтандартнаяОбработка = Ложь;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Этот метод работает мгновенно, так как данные уже находятся в памяти клиента (в составе данных текущей строки списка).

Решение 4: Кэширование данных на клиенте

Если специфика вашей задачи предполагает частую проверку одних и тех же ссылок в рамках одной сессии работы формы, имеет смысл реализовать кэширование. Это позволит не «дергать» сервер каждый раз для одного и того же контрагента.

Разберем по шагам, как реализовать простейший кэш:

  1. Создадим переменную модуля формы для хранения кэша.
  2. Перед вызовом сервера проверим наличие значения в кэше.
  3. Если значения нет — сходим на сервер и сохраним результат.

&НаКлиенте
Перем КэшГрупп; // Переменная будет жить, пока открыта форма

&НаКлиенте
Процедура ПроверитьСКэшем(Ссылка)
    
    Если КэшГрупп = Неопределено Тогда
        КэшГрупп = Новый Соответствие;
    КонецЕсли;
    
    ЭтоГруппа = КэшГрупп.Получить(Ссылка);
    
    Если ЭтоГруппа = Неопределено Тогда
        // В кэше нет данных, идем на сервер
        ЭтоГруппа = ОбъектЯвляетсяГруппой(Ссылка);
        КэшГрупп.Вставить(Ссылка, ЭтоГруппа);
    КонецЕсли;
    
    // Используем результат
КонецПроцедуры

Важные нюансы иерархии

При работе со свойством ЭтоГруппа необходимо учитывать настройки метаданных конкретного справочника. Выясним возможные ситуации:

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

← На главную