При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает необходимость программно установить значения параметров. Например, когда нужно автоматически отфильтровать данные по текущему пользователю или заполнить список разрешенных объектов при открытии отчета. Однако разработчики нередко сталкиваются с ошибкой «Поле объекта недоступно для записи». В этой статье мы подробно разберем, почему возникает эта ошибка, как правильно работать с переменными и какими методами лучше всего устанавливать параметры в СКД.
Рассмотрим ситуацию, когда в модуле объекта отчета в процедуре ПриКомпоновкеРезультата вы пытаетесь написать следующий код:
РезультатЗапроса = Запрос.Выполнить();
Сотрудники = РезультатЗапроса.Выгрузить();
Если в вашей конфигурации существует общий модуль с именем Сотрудники, или на форме отчета расположен элемент с таким же именем, платформа выдаст ошибку «Поле объекта недоступно для записи». Это происходит потому, что имя Сотрудники уже зарезервировано в глобальном контексте 1С:Предприятия. Платформа воспринимает это слово как ссылку на объект метаданных (общий модуль), который, разумеется, нельзя перезаписать значением таблицы значений или массива.
Рекомендация: Для локальных переменных всегда используйте префиксы или более описательные названия. Вместо Сотрудники лучше использовать СписокСотрудников, л_Сотрудники или ТаблицаСотрудников. Это гарантированно защитит ваш код от конфликтов с именами общих модулей, реквизитов отчета или системных функций.
Одной из частых ошибок является попытка записать значение напрямую в схему компоновки данных. Рассмотрим, почему так делать не стоит, и как сделать правильно. Проанализируем пример ошибочного кода:
// ОШИБОЧНЫЙ ПОДХОД
СхемаКомпоновкиДанных.Параметры.Сотрудники.Значение = Сотрудники;
Почему это ошибка: СхемаКомпоновкиДанных — это статичное описание отчета («чертеж»). Изменение параметров непосредственно в схеме влияет на структуру самого отчета в рамках текущего сеанса и часто блокируется платформой. Для работы с конкретными значениями в текущем сеансе пользователя предназначен КомпоновщикНастроек.
Правильный и наиболее универсальный способ установки параметра выглядит так:
ПараметрыДанных = КомпоновщикНастроек.Настройки.ПараметрыДанных;
ПараметрыДанных.УстановитьЗначениеПараметра("Сотрудники", СписокСотрудников);
Метод УстановитьЗначениеПараметра() самостоятельно находит параметр по его строковому имени и присваивает ему переданное значение, одновременно устанавливая флаг использования (Использование = Истина).
В современных конфигурациях (например, на базе БСП) параметры часто выносятся в область пользовательских настроек. Если параметр включен в этот список, то прямая установка через КомпоновщикНастроек.Настройки может быть проигнорирована, так как настройки пользователя имеют более высокий приоритет и «перекрывают» основные настройки при компоновке.
Для корректной работы в таких случаях рекомендуется использовать механизмы БСП. Выясним, как это сделать программно:
// Использование стандартной функции БСП
КомпоновкаДанныхКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "Сотрудники", СписокСотрудников);
Этот метод удобен тем, что он автоматически проверяет, где находится параметр: в основных настройках или в пользовательских, и обновляет его в нужном месте. Если вы не используете БСП, вам придется вручную искать идентификатор пользовательской настройки:
КомпоновщикНастроек.Настройки.ПараметрыДанных.ИдентификаторПользовательскойНастройки.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы и установить значение там.Проанализируем еще один важный нюанс — соответствие типов данных. Если в тексте запроса СКД вы используете условие сравнения со списком, например:
ГДЕ СотрудникиПользователя.Сотрудник В (&Сотрудники)
В этом случае в параметр &Сотрудники нельзя передавать ТаблицуЗначений. Платформа 1С не поддерживает тип «Таблица значений» внутри условий SQL-запроса (за исключением передачи во временные таблицы). Для корректной работы условия «В» или «В списке» необходимо передавать:
Если вы получили результат запроса, выгрузите нужную колонку в массив перед установкой параметра:
РезультатЗапроса = Запрос.Выполнить();
// Выгружаем только одну колонку в массив
МассивСотрудников = РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("Сотрудник");
// Устанавливаем массив в параметр
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Сотрудники", МассивСотрудников);
Когда мы переопределяем процедуру ПриКомпоновкеРезультата в модуле объекта отчета, важно правильно управлять параметром СтандартнаяОбработка.
Если ваша задача — только подменить значения параметров, но при этом вы хотите, чтобы платформа сама вывела отчет в документ результат (с учетом всех группировок и оформлений), то установите значения параметров и оставьте СтандартнаяОбработка = Истина.
Посмотрим на пример структуры процедуры:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// 1. Получаем данные для параметра
ТекущийПользователь = Пользователи.ТекущийПользователь();
// ... логика получения списка сотрудников через запрос ...
// 2. Устанавливаем параметр
КомпоновкаДанныхКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "Сотрудники", СписокСотрудников);
// 3. Разрешаем платформе продолжить стандартный вывод
СтандартнаяОбработка = Истина;
КонецПроцедуры
Если же вы планируете самостоятельно выводить данные (например, в разные таблицы или с использованием собственного процессора вывода), необходимо установить СтандартнаяОбработка = Ложь и полностью описать процесс компоновки программно через ПроцессорКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений (или в табличный документ).
Иногда требуется установить параметр так, чтобы пользователь не мог его изменить через форму настроек отчета. В этом случае параметры следует устанавливать в КомпоновщикНастроек.ФиксированныеНастройки. Эти настройки накладываются поверх всех остальных «жестко» и не редактируются в стандартном интерфейсе. Это полезно для реализации разграничения прав доступа на уровне отчета, когда список доступных данных определяется программно и не подлежит корректировке пользователем.
Для успешной программной работы с параметрами СКД придерживайтесь следующих правил:
л_ или Список...).Массив.КомпоновкаДанныхКлиентСервер.УстановитьПараметр для корректной обработки пользовательских настроек.