При работе с регистрами сведений разработчики 1С часто сталкиваются с ошибкой: «Ошибка при вызове метода контекста (Выбрать): Недопустимое значение параметра (параметр номер '1')». Проанализируем исходный код, который приводит к вызову этой ошибки, разберем причины поведения платформы и рассмотрим оптимальные варианты решения задачи.
Рассмотрим пример кода, в котором возникает эта проблема:
Отбор = Новый Структура;
Отбор.Вставить("Объект", Подразделение);
Отбор.Вставить("Свойство", ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Date_special"));
Выборка = РегистрыСведений.ЗначенияСвойствОбъектов.Выбрать(Отбор);
Выясним, почему платформа 1С возвращает ошибку при исполнении такого кода. Обратимся к Синтаксис-помощнику. Для метода Выбрать() непериодического регистра сведений предусмотрено следующее синтаксическое правило:
Выбрать(<Отбор>, <Порядок>)
В параметре Отбор передается объект типа Структура, где ключом выступает имя поля, а значением — искомое значение. Однако на этот параметр наложено строгое ограничение платформы: структура отбора может содержать только один элемент.
Кроме того, поле, по которому устанавливается отбор, должно удовлетворять следующим требованиям конфигуратора:
В приведенном примере в структуру Отбор были добавлены сразу два ключа (Объект и Свойство). Именно передача структуры с двумя и более элементами приводит к ошибке недопустимого значения первого параметра.
Разберем наиболее эффективный и универсальный способ обхода этого ограничения. Использование запроса позволяет выполнять выборку по любому количеству измерений, реквизитов или ресурсов с произвольными условиями в секции ГДЕ. Это работает значительно быстрее выборки методом Выбрать() и не требует предварительного индексирования реквизитов.
Посмотрим на пример реализации через запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗначенияСвойствОбъектов.Объект КАК Объект,
| ЗначенияСвойствОбъектов.Свойство КАК Свойство,
| ЗначенияСвойствОбъектов.Значение КАК Значение
|ИЗ
| РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
|ГДЕ
| ЗначенияСвойствОбъектов.Объект = &Объект
| И ЗначенияСвойствОбъектов.Свойство = &Свойство";
Запрос.УстановитьПараметр("Объект", Подразделение);
Запрос.УстановитьПараметр("Свойство", ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Date_special"));
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Обработка полученных записей
КонецЦикла;
Рассмотрим альтернативный вариант, когда необходимо прочитать записи регистра с использованием объекта РегистрСведенийНаборЗаписей.<Имя регистра>. Данный способ позволяет задавать сложные отборы по нескольким измерениям одновременно.
Обратите внимание: отбор в наборе записей можно устанавливать только по измерениям регистра и только на точное равенство.
НаборЗаписей = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Объект.Установить(Подразделение);
НаборЗаписей.Отбор.Свойство.Установить(ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Date_special"));
НаборЗаписей.Прочитать();
Для Каждого Запись Из НаборЗаписей Цикл
// Обработка полученной записи
ЗначениеСвойства = Запись.Значение;
КонецЦикла;
Если вам известны значения всех измерений, формирующих основной ключ записи непериодического регистра сведений, вы можете воспользоваться методом Получить(). Он принимает структуру со всеми измерениями и сразу возвращает структуру с значениями ресурсов.
СтруктураКлюча = Новый Структура;
СтруктураКлюча.Вставить("Объект", Подразделение);
СтруктураКлюча.Вставить("Свойство", ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоНаименованию("Date_special"));
ЗначенияРесурсов = РегистрыСведений.ЗначенияСвойствОбъектов.Получить(СтруктураКлюча);
ЗначениеСвойства = ЗначенияРесурсов.Значение;
Проанализировав работу методов регистра сведений, подведем итог:
Выбрать() подходит только для простой выборки с фильтрацией строго по одному полю.