При разработке аналитических отчетов в системе компоновки данных (СКД) разработчики прикладных решений на платформе 1С:Предприятие нередко сталкиваются с необходимостью вывода уникального идентификатора (GUID / UUID) ссылочных объектов. Подобная потребность возникает при подготовке данных для интеграции со сторонними информационными системами, сверке справочников между базами данных, аудите системных записей или выгрузке сведений во внешние хранилища. Начиная с версии платформы 8.3.22, в язык запросов и язык выражений СКД была добавлена встроенная функция УникальныйИдентификатор(), позволяющая получать идентификатор непосредственно при выполнении запроса к базе данных без применения ресурсоемких процедур объектной модели встроенного языка.
Однако на практике разработчик может обнаружить, что вместо привычной шестнадцатеричной строки формата 00000000-0000-0000-0000-000000000000 отчет выводит искаженные знаки, внутренние шестнадцатеричные байты, бинарный код или вовсе пустое значение. Чаще всего эта неполадка проявляется в тяжелых отчетах, где текст запроса содержит множество блоков ОБЪЕДИНИТЬ или ОБЪЕДИНИТЬ ВСЕ и насчитывает сотни или тысячи строк. Ниже подробно рассмотрены механизмы платформы, порождающие такое поведение, а также пошаговые способы диагностики и исправления ошибки.
Чтобы понять первопричину искажения данных, необходимо учитывать внутреннюю структуру и правила обработки идентификаторов в платформе 1С:Предприятие:
УникальныйИдентификатор представляет собой 128-битное двоичное число (16 байт). Оно служит уникальным системным ключом объекта в таблицах СУБД. По самому значению идентификатора невозможно определить, к какой именно таблице метаданных относится объект.УникальныйИдентификатор(Ссылка) возвращает объект системного типа УникальныйИдентификатор, а не готовую текстовую строку.ВЫРАЗИТЬ в языке запросов 1С служит исключительно для сужения поля составного типа (выделения одного конкретного типа из группы допустимых). Он не осуществляет динамическое преобразование данных одного типа в другой. Попытка применить выражение ВЫРАЗИТЬ(УникальныйИдентификатор(Ссылка) КАК Строка) приводит к ошибке выполнения запроса, так как системный тип УникальныйИдентификатор не преобразуется напрямую в строку через данный оператор.Основным фактором сбоя является механизм вычисления результирующего типа колонок при использовании операторов ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ. Когда итоговая выборка формируется из нескольких секций, тип результирующего поля определяется совокупностью типов данных этого поля во всех объединяемых выборках.
В процессе выполнения сложных многоуровневых запросов возникают следующие коллизии:
УникальныйИдентификатор(Ссылка), а во второй или третьей ветке для этой же колонки передается литерал пустой строки "", число 0, ссылка на другой объект или значение NULL, результирующая колонка получает составной или неопределенный тип.NULL КАК ПолеИдентификатора без явного приведения типа. В результате СУБД и платформа 1С не могут жестко зафиксировать системный тип колонки.УникальныйИдентификатор в строковый GUID отключается, и процессор вывода отдает внутреннее представление структуры в памяти.Для выявления конкретного места потери типизации рекомендуется выполнить следующую последовательность действий:
ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ.NULL, строковых констант или числовых нулей указывает на источник проблемы.В зависимости от требований к архитектуре отчета и допустимости изменения текста запроса применяются несколько практических решений.
Наиболее надежный подход, исключающий конфликты системных типов данных при любых объединениях, заключается в преобразовании уникального идентификатора в строку непосредственно в тексте запроса. Для этого применяется встроенная функция ПРЕДСТАВЛЕНИЕ().
ВЫБРАТЬ
ПРЕДСТАВЛЕНИЕ(УникальныйИдентификатор(Номенклатура.Ссылка)) КАК ИдентификаторСтрока
ИЗ
Справочник.Номенклатура КАК Номенклатура
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
"" КАК ИдентификаторСтрока
ИЗ
Справочник.Контрагенты КАК Контрагенты
Условия применения и ограничения: функция ПРЕДСТАВЛЕНИЕ() формирует стандартную 36-символьную строку GUID. В тех ветках объединения, где объект отсутствует, безопасно передается пустая строка "". Поскольку во всех объединяемых выборках колонка имеет строковый тип, СКД корректно отображает значение в отчете. Ограничением метода является то, что результирующее значение становится чистой строкой: его нельзя напрямую использовать в механизмах платформы, ожидающих системный объект УникальныйИдентификатор.
Если в схеме компоновки данных требуется сохранить именно системный тип объекта (например, для программной постобработки или фильтрации), можно жестко зафиксировать тип поля в свойствах набора данных без изменения логики запроса.
Условия применения и ограничения: способ эффективен, когда в запросе во всех выборках возвращается либо сам идентификатор, либо NULL. Однако если хотя бы одна из веток объединения вернет значение несовместимого типа (например, число или текст), при формировании отчета произойдет системная ошибка приведения типов.
Если текст запроса генерируется динамически или заблокирован от редактирования, исправить визуализацию можно с помощью языка выражений СКД.
Строка(ПолеИдентификатора). Процессор компоновки данных сохранит тип объекта для вычислений, но в визуальный макет выведет результат штатной функции приведения к строке.Строка(ПолеИдентификатора) и добавьте в структуру отчета именно это вычисляемое поле.Условия применения и ограничения: способ универсален и не требует модификации SQL-подобного текста запроса. Небольшим ограничением выступает незначительное увеличение нагрузки на процессор компоновки при обработке сотен тысяч строк.
Когда запрос насчитывает несколько тысяч строк и содержит десятки операторов ОБЪЕДИНИТЬ ВСЕ, поиск нетипизированных колонок вручную крайне трудоемок. Оптимальным инженерным решением является рефакторинг монолитного запроса с использованием временных таблиц.
Порядок рефакторинга:
Выбор оптимального способа устранения ошибки зависит от конкретных задач отчета:
Некорректный вид уникального идентификатора в СКД обусловлен потерей строгой типизации данных при объединении разнородных запросов. Преобразование значения к строке через ПРЕДСТАВЛЕНИЕ() либо корректное указание типа поля в наборе данных СКД полностью решает данную проблему и восстанавливает штатный вид идентификатора в отчете.