Как программно передать список значений в параметры и отборы отчета СКД в 1С 8.3?

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

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

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

Выясняем причину ошибки: почему нельзя обращаться к параметрам по индексу?

В Сообщении 15 пользователю был предложен следующий код для заполнения списка должностей:


ЭлементНастроек = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы[0];
ЭлементНастроек.Значение = Список;

Этот подход привел к ошибке Поле объекта не обнаружено (Значение) в Сообщении 16. Давайте проанализируем ситуацию и поймем, почему так происходит.

Коллекция ПараметрыДанных.Элементы содержит параметры компоновки данных. Обращение по индексу [0] крайне небезопасно и приводит к сбоям по трем основным причинам:

  1. Динамический порядок элементов: Порядок параметров в СКД зависит от структуры вашего запроса и настроек схемы. Если вы добавите новый параметр в запрос или измените порядок в конфигураторе, под индексом 0 окажется совершенно другой параметр (например, «НачалоПериода» вместо «Должность»).
  2. Отсутствие инициализации: Если параметр не был предварительно инициализирован в настройках компоновщика или список параметров пуст, обращение по индексу вернет значение Неопределено, у которого нет свойства Значение.
  3. Сложные типы данных: В зависимости от структуры настроек, элемент коллекции может быть не простым параметром, а группой или другим объектом компоновки.

Правильный способ №1: Использование метода УстановитьЗначениеПараметра

Чтобы избежать ошибок, связанных с индексацией элементов, в платформе 1С предусмотрен стандартный, надежный и лаконичный метод УстановитьЗначениеПараметра. Он самостоятельно находит параметр по его строковому имени и корректно присваивает ему переданное значение.

Рассмотрим пример правильной установки списка должностей в модуле формы отчета:


&НаСервере
Процедура ЗаполнитьПараметрыНаСервере()

    // Создаем список значений и наполняем его нужными элементами
    СписокДолжностей = Новый СписокЗначений;
    СписокДолжностей.Добавить(Справочники.Должности.НайтиПоНаименованию("Программисты"));
    СписокДолжностей.Добавить(Справочники.Должности.НайтиПоНаименованию("Дизайнеры"));

    // Безопасно устанавливаем параметр по его имени
    Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Должность", СписокДолжностей);

КонецПроцедуры

При таком подходе платформа сама найдет нужный параметр по имени "Должность", даже если он находится на десятой позиции в списке параметров. Это исключает возникновение непредвиденных ошибок при модификации схемы отчета.

Правильный способ №2: Метод НайтиЗначениеПараметра с проверкой

Если вам требуется не просто установить значение, но и выполнить дополнительные действия (например, включить или выключить использование параметра, проверить его доступность), рекомендуется использовать метод НайтиЗначениеПараметра. Он возвращает элемент настроек, который мы можем предварительно проверить.

Разберем этот способ на примере:


&НаСервере
Процедура УстановитьПараметрСПроверкой()

    СписокДолжностей = Новый СписокЗначений;
    СписокДолжностей.Добавить(Справочники.Должности.НайтиПоНаименованию("Генеральный директор"));

    // Создаем объект параметра по его имени в СКД
    ИмяПараметра = Новый ПараметрКомпоновкиДанных("Должность");
    ЭлементПараметра = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(ИмяПараметра);

    Если ЭлементПараметра <> Неопределено Тогда
        ЭлементПараметра.Значение = СписокДолжностей;
        ЭлементПараметра.Использование = Истина;
    КонецЕсли;

КонецПроцедуры

Критически важный нюанс: Конфликт с пользовательскими настройками

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

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

Для решения этой проблемы существует три основных варианта:

  1. Отключение пользовательской настройки в схеме: В конфигураторе на вкладке «Параметры» выберите нужный параметр и снимите флаг «Включать в пользовательские настройки». После этого параметр скроется с формы, и программный код будет работать без конфликтов.
  2. Программное изменение пользовательских настроек: Если параметр должен присутствовать на форме, но его нужно заполнить программно по умолчанию, изменять значение нужно непосредственно в коллекции пользовательских настроек. Для этого находят идентификатор настройки:

&НаСервере
Процедура ЗаполнитьПользовательскиеНастройки()

    Список = Новый СписокЗначений;
    Список.Добавить(Справочники.Должности.НайтиПоНаименованию("Бухгалтер"));

    ПараметрДанных = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(New ПараметрКомпоновкиДанных("Должность"));
    Если ПараметрДанных <> Неопределено Тогда
        // Ищем элемент в пользовательских настройках по его уникальному идентификатору
        ЭлементПН = Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(ПараметрДанных.ИдентификаторПользовательскойНастройки);
        Если ЭлементПН <> Неопределено Тогда
            ЭлементПН.Значение = Список;
            ЭлементПН.Использование = Истина;
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

3. Использование модуля объекта отчета: Еще один надежный способ — осуществлять заполнение параметров не в форме, а в модуле самого отчета в предопределенном обработчике ПриКомпоновкеРезультата. В этой точке настройки формы уже применились к отчету, и мы можем гарантированно перезаписать параметры перед непосредственным выводом данных в отчет.

Обязательные настройки схемы компоновки данных (СКД) в конфигураторе

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


ВЫБРАТЬ
    Сотрудники.Ссылка КАК Сотрудник,
    Сотрудники.Должность КАК Должность
ИЗ
    Справочник.Сотрудники КАК Сотрудники
ГДЕ
    Сотрудники.Должность В (&Должность)

Если параметр является необязательным, рекомендуется обернуть условие в фигурные скобки. В таком случае, если список должностей окажется пустым, СКД просто проигнорирует это условие в итоговом SQL-запросе к СУБД:

{ГДЕ Сотрудники.Должность В (&Должность)}

Альтернативный вариант: Использование Отборов вместо Параметров

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

Этот подход имеет ряд весомых преимуществ:

Давайте разберем пример программного добавления скрытого отбора по списку должностей в модуле формы отчета:


&НаСервере
Процедура УстановитьСкрытыйОтбор()

    // Создаем список значений для отбора
    СписокДолжностей = Новый СписокЗначений;
    СписокДолжностей.Добавить(Справочники.Должности.НайтиПоНаименованию("Программисты"));
    СписокДолжностей.Добавить(Справочники.Должности.НайтиПоНаименованию("Дизайнеры"));

    // Добавляем новый элемент отбора в компоновщик настроек
    НовыйОтбор = Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    НовыйОтбор.ЛевоеЗначение  = Новый ПолеКомпоновкиДанных("Должность"); // Имя поля из схемы компоновки
    НовыйОтбор.ВидСравнения   = ВидСравненияКомпоновкиДанных.ВСписке;
    НовыйОтбор.ПравоеЗначение = СписокДолжностей;
    НовыйОтбор.Использование  = Истина;

    // Скрываем отбор, чтобы пользователь не мог его отключить на форме
    НовыйОтбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;

КонецПроцедуры

Использование свойства РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный гарантирует, что пользователь даже не увидит данный отбор в настройках отчета, а отчет всегда будет формироваться строго по заданному списку должностей.

Резюме

Мы подробно проанализировали особенности работы со списками значений в СКД. Для успешного решения задачи всегда проверяйте соответствие типов в схеме (флаг «Доступен список значений»), используйте безопасные методы обращения к параметрам по их имени (УстановитьЗначениеПараметра) и помните о приоритете пользовательских настроек на управляемой форме. Если жесткие ограничения не требуют сложной логики в самом запросе, отдавайте предпочтение механизму скрытых программных отборов.

← На главную