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