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