При работе в 1С:Предприятие программисты часто сталкиваются с ситуацией, когда встроенная функция ПРЕДСТАВЛЕНИЕ() в запросе возвращает синоним значения перечисления (человекочитаемое название), а для логики обмена данными или интеграции со сторонними системами требуется получить именно имя (идентификатор), заданный в конфигураторе. Например, вместо "Договор на ответственное хранение" нам нужно получить строку "ОтвХранение".
В этой статье мы подробно разберем, почему стандартные средства запросов не всегда справляются с этой задачей напрямую, и проанализируем несколько эффективных способов получения идентификатора значения перечисления.
Разберем типичную ситуацию. Попытка использовать функцию ЗНАЧЕНИЕ() с обращением к свойству Имя внутри запроса приведет к ошибке, так как язык запросов 1С не поддерживает получение метаданных объектов таким способом. Рассмотрим пример ошибочного кода:
ВЫБРАТЬ
ДоговорыКлиентов.Наименование КАК Наименование,
// Эта конструкция вызовет ошибку:
ЗНАЧЕНИЕ(ДоговорыКлиентов.ТипДоговора.Имя) КАК ИмяИдентификатор
ИЗ
Справочник.ДоговорыКлиентов КАК ДоговорыКлиентов
Функция ПРЕДСТАВЛЕНИЕ(ТипДоговора) также не поможет, так как она всегда возвращает синоним, который может меняться или содержать пробелы и спецсимволы, недопустимые для программной логики. Выясним, какие существуют рабочие альтернативы.
Одним из самых быстрых и эффективных способов получения программного имени перечисления является использование функции XMLСтрока(). Важно понимать, что эта функция работает не внутри самого текста запроса, а при обработке его результатов в коде 1С или при обращении через COM-соединение.
Почему это работает: Платформа 1С при преобразовании значения перечисления в формат XML использует именно его внутренний идентификатор. Рассмотрим, как применить это на практике при обходе выборки:
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Получаем программное имя значения перечисления
ИмяИдентификатора = XMLСтрока(Выборка.ТипДоговора);
// Теперь в переменной ИмяИдентификатора лежит строка типа "ОтвХранение"
КонецЦикла;
Если работа ведется через внешнее соединение (например, при выгрузке данных в 1С 7.7), обращение будет выглядеть так: V8.XMLString(ТипДоговора). Это позволяет избежать написания громоздких конструкций ВЫБОР КОГДА.... При необходимости выполнения операций во внешних базах можно использовать инструмент для выполнения запросов через COM-подключение.
Если идентификаторы имен критически важны именно внутри самого запроса (например, для сложной группировки или условий соединения), мы можем заранее подготовить таблицу соответствий «Ссылка – Имя» и передать её в запрос. Проанализируем, как реализовать этот алгоритм:
Ссылка и ИмяЗначения.Посмотрим на пример реализации кода:
ТЗ_Имена = Новый ТаблицаЗначений;
ТЗ_Имена.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("ПеречислениеСсылка.ТипыДоговоров"));
ТЗ_Имена.Колонки.Добавить("ИмяЗначения", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(100)));
Для Каждого ЗначениеИзМетаданных Из Метаданные.Перечисления.ТипыДоговоров.ЗначенияПеречисления Цикл
НоваяСтрока = ТЗ_Имена.Добавить();
НоваяСтрока.Ссылка = Перечисления.ТипыДоговоров[ЗначениеИзМетаданных.Имя];
НоваяСтрока.ИмяЗначения = ЗначениеИзМетаданных.Имя;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТзИмен.ИмяЗначения КАК ИмяИдентификатор,
| Договоры.Наименование
|ИЗ
| Справочник.ДоговорыКлиентов КАК Договоры
| ЛЕВОЕ СОЕДИНЕНИЕ &ТзИмен КАК ТзИмен
| ПО Договоры.ТипДоговора = ТзИмен.Ссылка";
Запрос.УстановитьПараметр("ТзИмен", ТЗ_Имена);
Этот метод является наиболее универсальным, так как он позволяет оперировать именами перечислений непосредственно в теле запроса, не прибегая к постобработке каждого рекорда выборки.
В случае, если ваша задача решается в рамках построения отчета, можно воспользоваться мощным функционалом выражений СКД. В схеме компоновки данных функции работы со строками шире, чем в обычном запросе. Для освоения сложной логики компоновки подойдут примеры программной работы с СКД.
Разберем шаги настройки:
Пример функции в общем модуле:
Функция ПолучитьИмяПеречисления(Ссылка) Экспорт
Если Ссылка = Неопределено Тогда
Возврат "";
КонецЕсли;
МетаданныеОбъекта = Ссылка.Метаданные();
Индекс = Перечисления[МетаданныеОбъекта.Имя].Индекс(Ссылка);
Возврат МетаданныеОбъекта.ЗначенияПеречисления[Индекс].Имя;
КонецФункции
В СКД выражение поля будет выглядеть так: ИмяОбщегоМодуля.ПолучитьИмяПеречисления(ТипДоговора). Это позволяет выводить идентификатор напрямую в отчет или использовать его для группировки.
Подведем итог и проанализируем, когда какой метод лучше использовать:
Используя предложенные методики, вы сможете эффективно манипулировать данными перечислений, получая их программные идентификаторы для любых технических нужд, обеспечивая стабильность и высокую скорость работы ваших решений на платформе 1С.