Почему в СКД не работает внешняя функция при выгрузке в таблицу значений и отбор по шаблону с диапазоном символов?

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

При разработке отчетов и обработок на базе Системы компоновки данных (СКД) разработчики периодически сталкиваются с неочевидным поведением платформы. Две классические проблемы — это пропадание результатов вызова внешних функций при программной выгрузке в коллекцию значений и некорректная работа условий по маске с диапазонами символов. Разберем детально каждую ситуацию, проанализируем внутренние механизмы платформы 1С и рассмотрим надежные способы решения.

Проблема 1. Вызов внешней функции не срабатывает при выводе в таблицу значений

Типичный сценарий: в схеме компоновки настроено поле (например, номер документа), для которого в выражении представления вызывается экспортная функция общего модуля для удаления префикса. При выводе в ТабличныйДокумент все работает корректно, однако при попытке получить результат в виде объекта ТаблицаЗначений колонка содержит исходные данные либо функция вовсе не выполняется.

Выясним причину такого поведения платформы:

Когда отчет выводится на экран, используется ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент. Он отвечает за визуальное оформление: форматирование чисел, дат, цвета, шрифты и вычисление поля Выражение представления. Однако при программной выгрузке в коллекцию значений задействуются ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений и ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений. Данный механизм полностью игнорирует блок визуализации и представлений, помещая в колонки таблицы значений исключительно типизированные фактические значения полей набора данных.

Способы решения:

  1. Перенос вызова функции в вычисляемые поля.

    Вместо использования выражения представления поля перейдем на вкладку Вычисляемые поля схемы компоновки. Добавим новое поле (например, НомерБезПрефикса) и укажем вызов функции там:

    МойОбщийМодульКлиентСервер.ПолучитьНомерБезПрефикса(Номер)

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

  2. Перенос логики обрезки префикса в текст запроса.

    Если префикс имеет фиксированную длину (например, 2 или 4 символа), оптимальнее выполнить обработку непосредственно в наборе данных запроса с помощью функции языка запросов ПОДСТРОКА. Это полностью исключит накладные расходы на вызовы встроенного языка для каждой строки выборки.

  3. Проверка инициализации генератора макета.

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

    
    ГенераторМакета = Новый ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений;
    МакетКомпоновки = ГенераторМакета.Выполнить(СхемаКомпоновки, Настройки, ДанныеРасшифровки);
    

Проблема 2. Отбор по шаблону «ПОДОБНО» с диапазоном [0-9] не находит данные в СКД

При настройке отбора по строковому комментарию часто требуется найти подстроку с определенным шаблоном, например, CX[0-9]%. Если выполнить аналогичный запрос через консоль запросов 1С, записи успешно находятся. Однако при настройке пользовательского отбора в СКД результат оказывается пустым.

Проанализируем ограничения механизма отборов СКД:

Оператор ПОДОБНО в языке запросов 1С поддерживает полноценный набор служебных метасимволов: % (любая последовательность символов), _ (один произвольный символ), [...] (любой одиночный символ из указанного диапазона или списка) и [^...] (любой одиночный символ, не входящий в диапазон).

Однако механизм пользовательских настроек и отборов СКД устроен иначе:

  1. Движок фильтрации СКД в виде сравнения Соответствует шаблону (ВидСравненияКомпоновкиДанных.Подобно) поддерживает только три спецсимвола: %, _ и символ экранирования /. Квадратные скобки [...] не воспринимаются парсером компоновки как регулярный диапазон, а обрабатываются буквально как символы строки, что приводит к отсечению записей.
  2. Если выбран вид сравнения Содержит, платформа автоматически оборачивает строку знаками % и экранирует любые встреченные спецсимволы, поэтому использовать его для масок поиска недопустимо.
  3. Полноценная работа диапазонов [...] в запросах СУБД зависит от используемой базы данных. Например, в PostgreSQL стандартный оператор LIKE не поддерживает квадратные скобки без подключения специальных расширений, в отличие от Microsoft SQL Server.

Способы обхода ограничения:

  1. Использование расширения языка запросов СКД.

    Если поиск с диапазоном обязателен, вынесем условие из настроек варианта отчета в текст запроса набора данных с помощью фигурных скобок расширения СКД:

    
    ВЫБРАТЬ
        Документ.Ссылка КАК Ссылка,
        Документ.Номер КАК Номер,
        Документ.Комментарий КАК Комментарий
    ИЗ
        Документ.РеализацияТоваровУслуг КАК Документ
    ГДЕ
        {Документ.Комментарий ПОДОБНО &ШаблонПоиска}
    

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

  2. Построение группы условий «ИЛИ».

    Если поиск настраивается конечным пользователем в режиме предприятия через пользовательские настройки, диапазон цифр можно реализовать созданием группы условий с типом ИЛИ. Внутри группы создаются элементы с видом сравнения Соответствует шаблону для каждой цифры отдельно: CX0%, CX1%, CX2% и так далее до CX9%.

  3. Использование вычисляемого поля с регулярным выражением.

    Для сложных строковых условий можно добавить в СКД вычисляемое поле типа Булево, значение которого формируется вызовом экспортной функции модуля (с использованием COM-объекта регулярных выражений или встроенных методов строкового разбора). После этого в отборе достаточно наложить простое условие: ЭтоСоответствие = Истина.

← На главную