Как исправить ошибку «Недопустимое значение параметра (параметр номер '1')» при работе с методом Получить() регистра сведений в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разработка в среде 1С:Предприятие сопряжена с постоянным взаимодействием с базами данных, где ключевую роль играют регистры сведений. При извлечении данных из них начинающие программисты часто сталкиваются с неинформативным сообщением об ошибке: «Недопустимое значение параметра (параметр номер '1')». Это происходит непосредственно при вызове метода Получить() менеджера регистра сведений.

В рамках этой статьи мы подробно разберем, почему возникает данная ошибка, проанализируем реальный кейс с технического форума, изучим особенности работы с периодическими и непериодическими регистрами, а также рассмотрим альтернативные и более надежные способы извлечения информации с помощью запросов.

Анализ практической ситуации: опечатка в имени ключа структуры

Давайте обратимся к коду, который вызвал затруднения у автора темы. В обработчике изменения номенклатуры в табличной части документа вызывается серверная функция для получения цены поставщика:


&НаСервере
Функция ПолучитьЦену(ТоварИзДокумента)
    СтруктураПоиска = Новый Структура;                            
    СтруктураПоиска.Вставить("Номенклатура", ТоварИзДокумента);
    СтруктураПоиска.Вставить("Котрагент", Объект.Контрагент); // Обратите внимание на этот ключ!
    СтруктураПоиска.Вставить("Договор", Объект.Договор);
    
    РезультатПоиска = РегистрыСведений.ЦеныПоставщиков.Получить(СтруктураПоиска);
    Возврат РезультатПоиска.Цена;
КонецФункции

На первый взгляд, код выглядит абсолютно логично. Мы создаем объект типа Структура, наполняем его параметрами поиска и передаем в метод Получить(). Однако при выполнении этой строки система аварийно завершает работу с ошибкой в первом параметре.

Причина кроется в банальной опечатке: вместо правильного имени измерения "Контрагент" разработчик указал строковое значение "Котрагент" (пропущена буква «н»). Когда платформа 1С анализирует переданную структуру отбора, она сопоставляет ее ключи с реальными измерениями регистра в метаданных. Не найдя измерения с именем "Котрагент", система генерирует исключение, сообщая о недопустимом параметре.

Важные правила метода Получить(): только измерения!

Для того чтобы избежать подобных ошибок в будущем, необходимо четко понимать внутреннюю логику работы платформы 1С. Метод Получить() накладывает жесткие ограничения на структуру, передаваемую в качестве аргумента:

  1. Исключительность измерений. В структуру поиска разрешено включать исключительно те свойства, которые объявлены как измерения регистра сведений в конфигураторе. Если вы попытаетесь передать туда имя ресурса (например, "Цена") или реквизита (например, "Автор"), платформа незамедлительно выдаст ошибку недопустимого параметра.
  2. Точное совпадение имен. Имена ключей структуры должны посимвольно совпадать с именами измерений в конфигураторе. Любая опечатка или лишний пробел приведут к мгновенному сбою.
  3. Обязательность всех ключевых полей. Поскольку метод Получить() возвращает значения ресурсов для конкретной уникальной записи, структура отбора должна содержать значения для абсолютно всех измерений регистра. Если хотя бы одно измерение будет упущено, метод не сможет однозначно идентифицировать строку и вернет ошибку или пустую структуру ресурсов.

Влияние периодичности регистра на синтаксис метода

В процессе обсуждения на форуме прозвучал очень важный вопрос: «Регистр ЦеныПоставщиков — периодический?». Это фундаментальный нюанс, который часто упускают начинающие программисты. Сигнатура метода Получить() напрямую зависит от свойства периодичности регистра сведений:

Вариант 1. Непериодический регистр сведений

Если регистр хранит только актуальные статичные данные без привязки ко времени, метод принимает только один параметр — структуру отбора:

Результат = РегистрыСведений.ИмяРегистра.Получить(СтруктураОтбора);

Вариант 2. Периодический регистр сведений

Если у регистра включена периодичность (например, цены меняются со временем), первым параметром должна выступать дата (или момент времени), на которую запрашиваются данные, а вторым — структура отбора:

Результат = РегистрыСведений.ИмяРегистра.Получить(Период, СтруктураОтбора);

Если в периодическом регистре вызвать метод в формате первого варианта (передав только структуру), платформа попытается сопоставить структуру с первым ожидаемым параметром — Период (ожидается тип Дата или МоментВремени). Из-за несовпадения типов данных 1С выдаст ошибку: «Недопустимое значение параметра (параметр номер '1')».

Вот как должен выглядеть корректный вызов для периодического регистра сведений:


// Получаем цену на дату текущего документа
РезультатПоиска = РегистрыСведений.ЦеныПоставщиков.Получить(Объект.Дата, СтруктураПоиска);

Альтернатива: почему запросы предпочтительнее метода Получить()?

В профессиональной разработке использование прямого метода Получить() менеджера регистров считается не самым лучшим тоном, особенно если код выполняется внутри циклов обработки табличных частей. Мы рекомендуем использовать механизмы запросов по следующим причинам:

  1. Отказоустойчивость. Запрос никогда не приведет к аварийному завершению работы всей формы, даже если вы передадите пустые параметры или ошибетесь в условиях связи. Он просто вернет пустой результат, который можно корректно обработать в коде.
  2. Гибкость фильтрации. В запросе вы можете накладывать условия на любые поля — не только на измерения, но и на ресурсы, реквизиты, а также использовать сложные логические операторы.
  3. Производительность. Запросы работают быстрее и эффективнее с точки зрения СУБД, особенно когда требуется получить срез последних цен сразу по всей табличной части документа, а не обращаться к базе данных в цикле для каждой строки отдельно.

Давайте посмотрим на пример реализации той же задачи через запрос к виртуальной таблице СрезПоследних для периодического регистра:


&НаСервере
Функция ПолучитьЦенуЧерезЗапрос(ТоварИзДокумента, Контрагент, Договор, ДатаДокумента)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   ЦеныПоставщиковСрезПоследних.Цена КАК Цена
        |ИЗ
        |   РегистрСведений.ЦеныПоставщиков.СрезПоследних(&Период, Номенклатура = &Номенклатура И Контрагент = &Контрагент И Договор = &Договор) КАК ЦеныПоставщиковСрезПоследних";
    
    Запрос.УстановитьПараметр("Период", ДатаДокумента);
    Запрос.УстановитьПараметр("Номенклатура", ТоварИзДокумента);
    Запрос.УстановитьПараметр("Контрагент", Контрагент);
    Запрос.УстановитьПараметр("Договор", Договор);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Возврат Выборка.Цена;
    КонецЕсли;
    
    Возврат 0;
    
КонецФункции

Пошаговая методика отладки ошибки параметров

Если вы столкнулись с подобной ошибкой в своей конфигурации, мы рекомендуем пройти по следующим шагам для быстрой локализации проблемы:

  1. Установите точку останова. Откройте конфигуратор, найдите строку, вызывающую ошибку (в нашем случае это вызов метода Получить()), и установите точку останова клавишей F9.
  2. Запустите отладку. Воспроизведите ошибку в пользовательском режиме. Программа остановится на вашей точке останова до возникновения сбоя.
  3. Используйте Табло (Shift+F9). Выделите переменную СтруктураПоиска и добавьте ее в табло отладки. Разверните дерево свойств структуры.
  4. Сверьте свойства с метаданными. Откройте параллельно ветку метаданных вашего регистра сведений в конфигураторе. Посимвольно сравните каждое свойство из Табло со списком Измерений регистра. Убедитесь, что нет лишних полей, опечаток или реквизитов/ресурсов.
  5. Проверьте тип первого параметра. Если ваш регистр периодический, убедитесь, что вы передаете в качестве первого параметра объект типа Дата.

Следуя этим простым правилам и аккуратно проверяя типы данных, вы всегда сможете быстро и безболезненно решать любые проблемы, связанные с извлечением информации из регистров сведений в 1С!

← На главную