Как правильно использовать выражения в параметрах СКД для поиска данных по коду

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

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

Механизм выражений на вкладке Параметры

В конструкторе схемы компоновки данных существует вкладка Параметры. В колонке Выражение мы можем писать конструкции на языке выражений СКД, которые будут вычисляться перед выполнением запроса. Типичный пример, который мы рассмотрим — получение ссылки на элемент справочника:

Справочники.СтатьиЗатрат.НайтиПоКоду("00-000001")

На первый взгляд кажется, что это обычный встроенный язык 1С, но это не совсем так. Рассмотрим нюансы, из-за которых данные могут "не вставать в компоновку", то есть параметр остается пустым.

Анализ причин, по которым НайтиПоКоду возвращает пустую ссылку

Проанализируем ситуацию: выражение написано, синтаксических ошибок нет, но отчет не выводит данные. Выясним основные причины:

  1. Несоответствие типа кода: В конфигурации тип кода справочника может быть как Строка, так и Число. Если код числовой, а вы передаете в функцию строку в кавычках (например, "101"), поиск вернет пустую ссылку. Для числового кода выражение должно выглядеть так: Справочники.СтатьиЗатрат.НайтиПоКоду(101).
  2. Префиксы и лидирующие нули: Это самая частая причина ошибок. В пользовательском интерфейсе код может отображаться как "1", но в базе данных он хранится с учетом длины и префиксов, например, "000000001" или "УТ-000001". Если вы скопировали код, проверьте, нет ли в нем скрытых символов или невидимых нулей.
  3. Порядок параметров: СКД вычисляет параметры строго сверху вниз. Если ваше выражение для одного параметра зависит от значения другого параметра, убедитесь, что зависимый параметр находится в списке ниже.

Использование функций общих модулей в СКД

Иногда логика получения параметра сложнее, чем простой поиск. В этом случае мы можем вызвать функцию общего модуля. Разберем, как это сделать правильно, чтобы избежать блокировок системы безопасности.

Во-первых, функция в общем модуле должна быть объявлена с ключевым словом Экспорт. Сам модуль должен иметь установленные флаги Сервер и Вызов сервера. Пример функции в модуле РаботаСОтчетами:


Функция ПолучитьОсновнуюСтатьюЗатрат() Экспорт
    Возврат Справочники.СтатьиЗатрат.НайтиПоКоду("000000001");
КонецФункции

В поле выражения параметра СКД мы прописываем вызов:

РаботаСОтчетами.ПолучитьОсновнуюСтатьюЗатрат()

Важный момент: начиная с версии платформы 8.3.15, по умолчанию может быть запрещено выполнение функций встроенного языка в выражениях СКД. Чтобы это работало, при программном выводе отчета необходимо устанавливать настройки расшифровки и проверять права доступа, либо использовать безопасный режим с разрешением вызова конкретных модулей.

Использование предопределенных данных как альтернатива

Если элемент справочника, который мы ищем, является предопределенным, крайне не рекомендуется использовать НайтиПоКоду. Поиск по коду — это "хрупкое" решение: пользователь может изменить код в режиме предприятия, и отчет сломается. Проанализируем более надежный способ — использование функции ПредопределенноеЗначение.

Это специальная функция языка выражений СКД, которая работает быстрее и надежнее:

ПредопределенноеЗначение("Справочник.СтатьиЗатрат.ПрочиеРасходы")

Такой подход гарантирует, что даже при изменении кода или наименования элемента в базе, отчет продолжит работать корректно, так как привязка идет к внутреннему имени метаданных.

Методика отладки параметров СКД

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

  1. В схеме компоновки перейдем на вкладку Вычисляемые поля.
  2. Создадим новое поле, назовем его ТестПараметра.
  3. В колонку Выражение этого поля скопируем текст из нашего параметра, например: Справочники.СтатьиЗатрат.НайтиПоКоду("00001").
  4. На вкладке Настройки добавим это поле в Детальные записи отчета.

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

Программная установка параметров как финальное решение

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


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Получаем настройки отчета
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Ищем параметр по имени
    ПараметрСсылка = Настройки.ПараметрыДанных.Элементы.Найти("СтатьяЗатрат");
    
    Если ПараметрСсылка <> Неопределено Тогда
        СсылкаНаОбъект = Справочники.СтатьиЗатрат.НайтиПоКоду("00-000001");
        Если СсылкаНаОбъект.Пустая() Тогда
            Сообщить("Внимание: Статья затрат с кодом 00-000001 не найдена!");
        КонецЕсли;
        ПараметрСсылка.Значение = СсылкаНаОбъект;
        ПараметрСсылка.Использование = Истина;
    КонецЕсли;
    
    // Выполняем компоновку
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
КонецПроцедуры

Этот метод более трудоемкий, но он дает полный контроль над процессом. Однако в большинстве случаев достаточно правильно настроенного выражения на вкладке параметров и внимательной проверки кодов справочников. Для сокращения рутинного кода при таком подходе можно использовать модуль-обёртку СКДБилдер для программного управления компоновкой данных.

← На главную