При разработке отчетов и обработок на базе Системы компоновки данных (СКД) разработчики периодически сталкиваются с неочевидным поведением платформы. Две классические проблемы — это пропадание результатов вызова внешних функций при программной выгрузке в коллекцию значений и некорректная работа условий по маске с диапазонами символов. Разберем детально каждую ситуацию, проанализируем внутренние механизмы платформы 1С и рассмотрим надежные способы решения.
Типичный сценарий: в схеме компоновки настроено поле (например, номер документа), для которого в выражении представления вызывается экспортная функция общего модуля для удаления префикса. При выводе в ТабличныйДокумент все работает корректно, однако при попытке получить результат в виде объекта ТаблицаЗначений колонка содержит исходные данные либо функция вовсе не выполняется.
Выясним причину такого поведения платформы:
Когда отчет выводится на экран, используется ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент. Он отвечает за визуальное оформление: форматирование чисел, дат, цвета, шрифты и вычисление поля Выражение представления. Однако при программной выгрузке в коллекцию значений задействуются ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений и ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений. Данный механизм полностью игнорирует блок визуализации и представлений, помещая в колонки таблицы значений исключительно типизированные фактические значения полей набора данных.
Способы решения:
Вместо использования выражения представления поля перейдем на вкладку Вычисляемые поля схемы компоновки. Добавим новое поле (например, НомерБезПрефикса) и укажем вызов функции там:
МойОбщийМодульКлиентСервер.ПолучитьНомерБезПрефикса(Номер)
Вычисляемые поля рассчитываются на этапе компоновки данных независимо от целевого приемника вывода, поэтому результат работы функции гарантированно попадет в результирующую таблицу значений. Общий модуль при этом должен быть доступен в контексте выполнения компоновщика (иметь флаг Сервер или Клиент-сервер).
Если префикс имеет фиксированную длину (например, 2 или 4 символа), оптимальнее выполнить обработку непосредственно в наборе данных запроса с помощью функции языка запросов ПОДСТРОКА. Это полностью исключит накладные расходы на вызовы встроенного языка для каждой строки выборки.
Убедимся, что при программной компоновке используется корректный конструктор генератора:
ГенераторМакета = Новый ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений;
МакетКомпоновки = ГенераторМакета.Выполнить(СхемаКомпоновки, Настройки, ДанныеРасшифровки);
При настройке отбора по строковому комментарию часто требуется найти подстроку с определенным шаблоном, например, CX[0-9]%. Если выполнить аналогичный запрос через консоль запросов 1С, записи успешно находятся. Однако при настройке пользовательского отбора в СКД результат оказывается пустым.
Проанализируем ограничения механизма отборов СКД:
Оператор ПОДОБНО в языке запросов 1С поддерживает полноценный набор служебных метасимволов: % (любая последовательность символов), _ (один произвольный символ), [...] (любой одиночный символ из указанного диапазона или списка) и [^...] (любой одиночный символ, не входящий в диапазон).
Однако механизм пользовательских настроек и отборов СКД устроен иначе:
Соответствует шаблону (ВидСравненияКомпоновкиДанных.Подобно) поддерживает только три спецсимвола: %, _ и символ экранирования /. Квадратные скобки [...] не воспринимаются парсером компоновки как регулярный диапазон, а обрабатываются буквально как символы строки, что приводит к отсечению записей.Содержит, платформа автоматически оборачивает строку знаками % и экранирует любые встреченные спецсимволы, поэтому использовать его для масок поиска недопустимо.[...] в запросах СУБД зависит от используемой базы данных. Например, в PostgreSQL стандартный оператор LIKE не поддерживает квадратные скобки без подключения специальных расширений, в отличие от Microsoft SQL Server.Способы обхода ограничения:
Если поиск с диапазоном обязателен, вынесем условие из настроек варианта отчета в текст запроса набора данных с помощью фигурных скобок расширения СКД:
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
Документ.Номер КАК Номер,
Документ.Комментарий КАК Комментарий
ИЗ
Документ.РеализацияТоваровУслуг КАК Документ
ГДЕ
{Документ.Комментарий ПОДОБНО &ШаблонПоиска}
В этом случае условие подставляется напрямую в тело формируемого SQL-запроса, обходя ограничения процессора компоновки данных.
Если поиск настраивается конечным пользователем в режиме предприятия через пользовательские настройки, диапазон цифр можно реализовать созданием группы условий с типом ИЛИ. Внутри группы создаются элементы с видом сравнения Соответствует шаблону для каждой цифры отдельно: CX0%, CX1%, CX2% и так далее до CX9%.
Для сложных строковых условий можно добавить в СКД вычисляемое поле типа Булево, значение которого формируется вызовом экспортной функции модуля (с использованием COM-объекта регулярных выражений или встроенных методов строкового разбора). После этого в отборе достаточно наложить простое условие: ЭтоСоответствие = Истина.