Работая над сложными отчетами или печатными формами в платформе 1С:Предприятие 8.3, разработчики часто сталкиваются с необходимостью вывода справочной информации на язык, понятный конечному пользователю. Стандартные типы данных, такие как ПеречислениеСсылка, при прямой выгрузке в макеты часто отображаются в виде технических идентификаторов или англоязычных имен, что недопустимо для финальной документации.
Для решения этой проблемы в языке запросов 1С предусмотрен механизм псевдополей, позволяющий получить человеко-читаемое представление значения. Использование конструкции КакСтрока является наиболее эффективным способом получить текстовое описание элемента перечисления непосредственно на уровне СУБД, не прибегая к циклам обработки в коде 1С.
В данной статье мы детально разберем синтаксис преобразования, особенности сравнения значений перечислений внутри запроса и нюансы передачи параметров. Понимание этих механизмов позволит вам оптимизировать код отчетов и избежать распространенных ошибок производительности при работе с большими выборками данных.
Синтаксис преобразования перечисления в строку
Ключевой метод получения текстового значения заключается в использовании псевдополя КакСтрока. Это свойство доступно для всех ссылочных типов и типов перечислений. При добавлении этого поля в список выбора запроса, СУБД автоматически подставляет синоним объекта, определенный в метаданных конфигурации.
Рассмотрим базовый пример выборки из регистра сведений или документа, где присутствует поле типа ПеречислениеСсылка. Допустим, у нас есть справочник "Контрагенты" с полем "ТипКонтрагента", которое является перечислением. Чтобы вывести не имя элемента, а его полное наименование, запрос должен выглядеть следующим образом:
ВЫБРАТЬ
Контрагенты.Наименование,
Контрагенты.ТипКонтрагента КАК ТипКонтрагентаСсылка,
Контрагенты.ТипКонтрагента.КакСтрока КАК ТипКонтрагентаТекст
ИЗ
Справочник.Контрагенты КАК Контрагенты
Обратите внимание на конструкцию .КакСтрока. Она применяется непосредственно к полю выборки. Результатом выполнения такого запроса будет таблица, где в колонке ТипКонтрагентаТекст будут находиться строковые значения, например, "Юридическое лицо" или "Физическое лицо", вместо внутренних имен вроде ЮридическоеЛицо.
Это позволяет напрямую передавать данные в макеты компоновки данных (СКД) без необходимости создания дополнительных вычисляемых полей на уровне макета, что упрощает поддержку отчета.
Используйте алиасы (КАК..) для полей.КакСтрока, чтобы имена колонок в результирующей таблице были понятными и не содержали точек, что может вызвать ошибки в СКД.
Сравнение значений перечислений в условиях отбора
Одной из частых задач является фильтрация данных по конкретному значению перечисления. Здесь разработчики допускают ошибку, пытаясь сравнивать ссылку на перечисление со строкой. В запросах 1С строгая типизация требует сравнения однотипных данных.
Если вы используете параметр в запросе, тип которого определен как ПеречислениеСсылка.ВидыНоменклатуры, то в условии ГДЕ вы должны сравнивать поле перечисления именно с этим параметром. Преобразование в строку для целей фильтрации обычно не требуется и даже вредно с точки зрения производительности индексов.
Однако, если ваш параметр по каким-то причинам передается как строка (например, из внешней системы или веб-сервиса), вам потребуется обратное преобразование. В этом случае используется функция ЗНАЧЕНИЕ или явное приведение типов, но правильнее все же передавать параметры типизированными.
☑️ Правила сравнения перечислений
Рассмотрим корректный пример условия отбора, где мы выбираем только товары определенного вида:
ГДЕ
Номенклатура.ВидНоменклатуры = &ВидНоменклатурыПараметр
В данном случае &ВидНоменклатурыПараметр должен быть заполнен ссылкой на элемент перечисления. Если попытаться написать Номенклатура.ВидНоменклатура.КакСтрока = "Товар", запрос может сработать, но он будет выполняться медленнее, так как не сможет эффективно использовать индекс по полю ВидНоменклатуры.
Работа с составными типами и NULL значениями
Ситуация усложняется, когда поле в базе данных имеет составной тип, например, ПеречислениеСсылка.Статусы или Неопределено. В таких случаях прямое обращение к свойству КакСтрока может привести к ошибке выполнения запроса, если в выборке попадется значение NULL.
Чтобы избежать сбоев, необходимо использовать функцию ЕСТЬNULL или конструкцию ВЫБОР. Это позволит обработать пустые значения отдельно, подставив прочерк или текст "Не указано", прежде чем пытаться получить строковое представление перечисления.
Пример безопасной обработки составного типа:
ВЫБОР
КОГДА Документы.Статус.КакСтрока ЕСТЬ NULL ТОГДА "Не задан"
ИНАЧЕ Документы.Статус.КакСтрока
КОНЕЦ КАК СтатусТекст
Такой подход гарантирует, что ваш отчет не "упадет" с ошибкой "Неверное использование поля" при наличии пустых записей в выборке. Это особенно критично при формировании сводных отчетов за большие периоды, где данные могли быть введены не полностью.
Почему возникает ошибка при NULL?
Свойство.КакСтрока является методом объекта. Если сам объект равен NULL (не определен), у него нет методов, и попытка обращения к свойству вызывает исключение во время выполнения запроса.
Оптимизация производительности при больших выборках
Использование псевдополей, таких как КакСтрока, перекладывает работу по преобразованию данных на сторону сервера баз данных. В большинстве современных СУБД (PostgreSQL, MS SQL Server), используемых с 1С, эта операция оптимизирована и выполняется достаточно быстро.
Тем не менее, при выборке миллионов записей каждое лишнее вычисление имеет значение. Если вам нужно только количество элементов определенного типа, не выбирайте поле КакСтрока в списке полей, если оно не используется для группировки или вывода. Оставьте его только в условиях отбора, если это необходимо.
Главное правило оптимизации: не используйте преобразование типов в полях, по которым происходит группировка (СГРУППИРОВАТЬ ПО), если это можно сделать по ссылке. Группировка по ссылке (ПеречислениеСсылка) всегда быстрее и корректнее, чем группировка по строковому представлению, так как исключает потери данных из-за возможных дублей имен.
| Метод получения данных | Тип результата | Производительность | Рекомендация |
|---|---|---|---|
| Прямая выборка ссылки | ПеречислениеСсылка | Высокая | Для внутренних расчетов и группировок |
| Псевдополе.КакСтрока | Строка | Средняя | Для вывода в печатные формы и отчеты |
| Функция ПОЛУЧИТЬНАИМЕНОВАНИЕ | Строка | Низкая (в цикле) | Только если запрос невозможен |
| Обработка в коде 1С | Строка | Низкая | Избегать для больших объемов |
Интеграция с Системой Компоновки Данных (СКД)
При разработке отчетов с использованием СКД, правильное использование перечислений в запросе позволяет значительно упростить настройки макета. Если вы вернули поле КакСтрока из запроса, система компоновки данных автоматически определит его как строку и не будет предлагать пользователю настройки группировки по этому полю как по справочнику.
Это может быть как преимуществом, так и недостатком. С одной стороны, вы фиксируете отображение. С другой стороны, пользователь теряет возможность группировать данные по видам номенклатуры, если вы не добавили в выборку само поле ссылки. Оптимальным решением является выборка обоих полей.
В настройках СКД вы можете скрыть техническое поле ссылки (ПеречислениеСсылка) от пользователя, оставив видимым только поле КакСтрока для отображения, но при этом сохранить возможность использовать скрытое поле для сортировки или связывания с другими наборами данных.
⚠️ Внимание: Если вы планируете использовать отчет в режиме предприятия с возможностью изменения настроек пользователем, убедитесь, что поля для группировки имеют тип Справочник или Перечисление, а не Строка. Иначе функционал иерархической группировки будет недоступен.
Частые ошибки и способы их устранения
Разработчики часто путают имя элемента перечисления и его синоним. В метаданных у элемента есть имя (используется в коде, например, Розница) и синоним (выводится пользователю, например, Розничная продажа). Псевдополе КакСтрока возвращает именно синоним.
Еще одной распространенной ошибкой является попытка использовать КакСтрока в выражениях математического типа или конкатенации без явного приведения. Хотя результат уже строка, некоторые операции могут требовать явного указания типа в сложных вложенных запросах.
Также стоит учитывать локализацию. Синонимы перечислений зависят от языка интерфейса пользователя. Если ваш отчет формируется в фоновом задании или веб-сервисе, убедитесь, что контекст выполнения имеет правильный язык, иначе КакСтрока может вернуть наименование на языке по умолчанию сервера.
Всегда проверяйте, что синонимы перечислений заполнены в конфигураторе. Если синоним пуст.КакСтрока вернет имя элемента, что может нарушить логику отображения.
Для отладки таких ситуаций полезно использовать консоль запросов. Выполните запрос там и посмотрите на тип колонки и ее содержимое. Это сэкономит время при поиске причин некорректного вывода данных в печатной форме.
⚠️ Внимание: Интерфейсы и названия функций могут незначительно отличаться в зависимости от версии платформы 1С:Предприятие (8.2, 8.3) и режима совместимости. Всегда сверяйтесь с синтаксическим помощником вашей конкретной версии конфигурации.
FAQ: Часто задаваемые вопросы
Можно ли использовать.КакСтрока в условии СОЕДИНЕНИЕ?
Технически это возможно, но крайне не рекомендуется. Соединение таблиц должно происходить по ключевым полям (ссылкам). Соединение по строковому представлению приведет к полному сканированию таблиц и резкому падению производительности запроса.
Почему.КакСтрока возвращает пустую строку?
Это может произойти, если у элемента перечисления в метаданных не задан синоним, либо если само значение ссылки равно NULL, а обработка нулей не предусмотрена конструкцией ВЫБОР.
Как получить имя элемента (код), а не синоним?
Псевдополе КакСтрока возвращает синоним. Для получения имени (идентификатора) обычно используется свойство Имя (если доступно в контексте запроса конкретной версии) или выборка самого значения ссылки и последующее получение имени в коде 1С через свойство Имя объекта.
Влияет ли использование.КакСтрока на блокировки записей?
Нет, чтение псевдополей является операцией чтения и не устанавливает блокировок на изменение данных. Однако сам запрос, в зависимости от уровня изоляции транзакций, может блокировать строки от изменения другими пользователями на время выполнения.
Можно ли группировать по.КакСтрока?
Да, можно. Но это считается плохой практикой. Группировка должна выполняться по уникальному идентификатору (ссылке), а текстовое представление должно получаться агрегированием (например, МАКСИМУМ(Поле.КакСтрока)) после группировки.