При разработке на платформе 1С:Предприятие мы часто используем объект ПостроительЗапроса для гибкой фильтрации данных, полученных программным путем. Однако при работе с ТаблицаЗначений, созданной «на лету», программисты нередко сталкиваются с неприятной ошибкой: «Недопустимое значение параметра (параметр номер '1')» в момент выполнения метода Добавить() коллекции Отбор. Давайте разберем, почему это происходит и как гарантированно решить эту задачу.
Главная причина кроется в том, как 1С обрабатывает колонки ТаблицаЗначений. Когда мы добавляем колонку простым вызовом ТЗнч.Колонки.Добавить("ИмяКолонки"), платформа не присваивает ей конкретный тип данных. Колонка получает статус «Произвольный тип».
ПостроительЗапроса — это инструмент, который опирается на строгую структуру метаданных. Он анализирует ИсточникДанных и формирует список ДоступныеПоля. Если колонка имеет неопределенный тип, построитель просто «не видит» возможности применить к ней математические или логические операции (например, ВидСравнения.Содержит). В итоге попытка обратиться к такой колонке через коллекцию отбора приводит к ошибке, так как поле фактически отсутствует в списке доступных для фильтрации.
Чтобы ПостроительЗапроса корректно распознал поле и позволил накладывать на него условия, необходимо при создании таблицы значений явно указать ОписаниеТипов. Рассмотрим пошагово, как это сделать правильно.
ОписаниеТипов с нужным нам типом (в большинстве случаев, если мы работаем со строковыми данными, это Строка).Колонки.Добавить().Посмотрим на пример правильной инициализации:
// Создаем описание типа для строковых данных
ОписаниеТипаСтрока = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(100));
ТЗнч = Новый ТаблицаЗначений;
// Теперь колонка типизирована, и Построитель запроса ее «увидит»
ТЗнч.Колонки.Добавить("ЗначениеМассива", ОписаниеТипаСтрока);
После того как мы подготовили таблицу с типизированными колонками, процесс настройки построителя должен выглядеть следующим образом:
// Инициализируем источник данных
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТЗнч);
// Принудительно обновляем настройки, чтобы построитель перечитал структуру таблицы
Построитель.ЗаполнитьНастройки();
// Теперь мы можем безопасно добавлять отбор
ТабОтбор = Построитель.Отбор.Добавить("ЗначениеМассива");
ТабОтбор.ВидСравнения = ВидСравнения.Содержит;
ТабОтбор.Значение = "Контрагент";
ТабОтбор.Использование = Истина;
Построитель.Выполнить();
Часто возникает вопрос: «Почему мой старый код работал с таблицей из Excel без явной типизации?». Ответ прост: когда вы загружаете данные из внешних источников (Excel, XML, внешние базы), платформа 1С часто выполняет автоматическое приведение типов на основе содержимого ячеек. Если в колонке Excel везде текст, 1С при создании таблицы может сама назначить тип Строка. Но при ручном заполнении ТаблицаЗначений через цикл Добавить(), эта «магия» не происходит, поэтому типизация — это ваша зона ответственности.
Рассмотрим еще несколько нюансов, которые помогут избежать ошибок в будущем:
ВидСравнения.Содержит корректно работает только со строковыми типами. Если вы планируете фильтровать числа, используйте соответствующие виды сравнения (Больше, Меньше) и типизируйте колонку через КвалификаторыЧисла.Построитель.ЗаполнитьНастройки() является ключевым. Если вы меняете структуру источника или добавляете новые колонки после создания построителя, всегда вызывайте этот метод, чтобы синхронизировать внутреннюю коллекцию доступных полей.Добавить() коллекции Отбор невозможно использовать для динамических списков (например, СправочникСписок или ДокументСписок), так как у них механизм отбора реализован через другие механизмы платформы, недоступные для прямого вмешательства построителя.Применяя этот подход, вы обеспечите стабильную работу алгоритмов фильтрации и избежите ошибок типизации в ваших отчетах и обработках.