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