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

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

При работе в 1С:Предприятие программисты часто сталкиваются с ситуацией, когда встроенная функция ПРЕДСТАВЛЕНИЕ() в запросе возвращает синоним значения перечисления (человекочитаемое название), а для логики обмена данными или интеграции со сторонними системами требуется получить именно имя (идентификатор), заданный в конфигураторе. Например, вместо "Договор на ответственное хранение" нам нужно получить строку "ОтвХранение".

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

Проблема стандартного представления в запросах

Разберем типичную ситуацию. Попытка использовать функцию ЗНАЧЕНИЕ() с обращением к свойству Имя внутри запроса приведет к ошибке, так как язык запросов 1С не поддерживает получение метаданных объектов таким способом. Рассмотрим пример ошибочного кода:


ВЫБРАТЬ
    ДоговорыКлиентов.Наименование КАК Наименование,
    // Эта конструкция вызовет ошибку:
    ЗНАЧЕНИЕ(ДоговорыКлиентов.ТипДоговора.Имя) КАК ИмяИдентификатор
ИЗ
    Справочник.ДоговорыКлиентов КАК ДоговорыКлиентов

Функция ПРЕДСТАВЛЕНИЕ(ТипДоговора) также не поможет, так как она всегда возвращает синоним, который может меняться или содержать пробелы и спецсимволы, недопустимые для программной логики. Выясним, какие существуют рабочие альтернативы.

Метод 1: Использование функции XMLСтрока (XMLString)

Одним из самых быстрых и эффективных способов получения программного имени перечисления является использование функции XMLСтрока(). Важно понимать, что эта функция работает не внутри самого текста запроса, а при обработке его результатов в коде 1С или при обращении через COM-соединение.

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


Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    // Получаем программное имя значения перечисления
    ИмяИдентификатора = XMLСтрока(Выборка.ТипДоговора);
    // Теперь в переменной ИмяИдентификатора лежит строка типа "ОтвХранение"
КонецЦикла;

Если работа ведется через внешнее соединение (например, при выгрузке данных в 1С 7.7), обращение будет выглядеть так: V8.XMLString(ТипДоговора). Это позволяет избежать написания громоздких конструкций ВЫБОР КОГДА.... При необходимости выполнения операций во внешних базах можно использовать инструмент для выполнения запросов через COM-подключение.

Метод 2: Подготовка временной таблицы через метаданные

Если идентификаторы имен критически важны именно внутри самого запроса (например, для сложной группировки или условий соединения), мы можем заранее подготовить таблицу соответствий «Ссылка – Имя» и передать её в запрос. Проанализируем, как реализовать этот алгоритм:

  1. Программно переберем все значения нужного перечисления в метаданных.
  2. Сформируем таблицу значений с двумя колонками: Ссылка и ИмяЗначения.
  3. Передадим эту таблицу в запрос как параметр и поместим во временную таблицу.
  4. Соединим основную таблицу данных с этой временной таблицей по полю ссылки.

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


ТЗ_Имена = Новый ТаблицаЗначений;
ТЗ_Имена.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("ПеречислениеСсылка.ТипыДоговоров"));
ТЗ_Имена.Колонки.Добавить("ИмяЗначения", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(100)));

Для Каждого ЗначениеИзМетаданных Из Метаданные.Перечисления.ТипыДоговоров.ЗначенияПеречисления Цикл
    НоваяСтрока = ТЗ_Имена.Добавить();
    НоваяСтрока.Ссылка = Перечисления.ТипыДоговоров[ЗначениеИзМетаданных.Имя];
    НоваяСтрока.ИмяЗначения = ЗначениеИзМетаданных.Имя;
КонецЦикла;

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|    ТзИмен.ИмяЗначения КАК ИмяИдентификатор,
|    Договоры.Наименование
|ИЗ
|    Справочник.ДоговорыКлиентов КАК Договоры
|    ЛЕВОЕ СОЕДИНЕНИЕ &ТзИмен КАК ТзИмен
|    ПО Договоры.ТипДоговора = ТзИмен.Ссылка";

Запрос.УстановитьПараметр("ТзИмен", ТЗ_Имена);

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

Метод 3: Использование Системы компоновки данных (СКД)

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

Разберем шаги настройки:

  1. В поле набора данных оставьте ссылку на перечисление.
  2. На закладке "Вычисляемые поля" или непосредственно в поле выражения можно использовать обращение к методам общих модулей.
  3. Создайте в общем модуле (с флагом "Сервер", "Вызов сервера") функцию, которая возвращает имя перечисления через метаданные.

Пример функции в общем модуле:


Функция ПолучитьИмяПеречисления(Ссылка) Экспорт
    Если Ссылка = Неопределено Тогда
        Возврат "";
    КонецЕсли;
    МетаданныеОбъекта = Ссылка.Метаданные();
    Индекс = Перечисления[МетаданныеОбъекта.Имя].Индекс(Ссылка);
    Возврат МетаданныеОбъекта.ЗначенияПеречисления[Индекс].Имя;
КонецФункции

В СКД выражение поля будет выглядеть так: ИмяОбщегоМодуля.ПолучитьИмяПеречисления(ТипДоговора). Это позволяет выводить идентификатор напрямую в отчет или использовать его для группировки.

Сравнение подходов

Подведем итог и проанализируем, когда какой метод лучше использовать:

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

← На главную