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