В практике разработки на платформе 1С:Предприятие 8.3 иногда возникают ситуации, которые кажутся парадоксальными. Одной из таких проблем является ошибка «Слишком много фактических параметров», возникающая при вызове процедуры, количество параметров в которой визуально и фактически соответствует определению в коде. Особенно часто это проявляется в типовых конфигурациях, использующих Библиотеку стандартных подсистем (БСП), в частности, в модулях оценки производительности.
В рамках данной статьи мы детально разберем, почему возникает эта ошибка, как проанализировать стек вызовов и какие шаги предпринять для устранения этой технической коллизии. Мы рассмотрим ситуацию на примере вызова процедуры ЗафиксироватьВремяОкончания в общем модуле ОценкаПроизводительностиВызовСервера.
Рассмотрим типовой сценарий. В глобальном общем модуле ОценкаПроизводительностиКлиентГлобальный происходит вызов серверного метода. Код выглядит следующим образом:
ОценкаПроизводительностиВызовСервера.ЗафиксироватьВремяОкончания(, Истина);
При этом определение процедуры в модуле ОценкаПроизводительностиВызовСервера имеет ровно два параметра, где первый может быть не заполнен (передается пустое значение или неопределено), а второй имеет тип Булево. Казалось бы, синтаксических ошибок нет. Однако в моменты пиковой нагрузки или после возникновения конфликта блокировок платформа внезапно прерывает выполнение с сообщением о лишних параметрах.
Проанализируем возможные причины такого поведения платформы. Опытные разработчики знают, что в 1С ошибка «Слишком много параметров» при их фактическом равенстве обычно указывает не на ошибку в написании кода, а на проблемы компиляции модулей или состояния кэша.
Самая распространенная причина — так называемое «демоническое» (динамическое) обновление конфигурации. Когда изменения вносятся в серверные модули без перезагрузки рабочих процессов сервера, может возникнуть рассинхронизация. Клиентское приложение «думает», что у процедуры одна сигнатура, а сервер выполняет скомпилированный код старой версии.
Что нужно сделать для решения:
%AppData%\1C\1cv8.snccntxt и reg_1541 (за исключением файлов журналов и настроек кластера).Проанализируем ситуацию с точки зрения контекста. Процедура ЗакончитьЗамерВремениАвто находится в глобальном общем модуле. Глобальные модули загружаются в память при старте сеанса и всегда доступны в области видимости. В редких случаях, при возникновении системных исключений (например, при откате транзакции из-за блокировки), внутренний стек платформы может передавать в вызываемые методы скрытые параметры, такие как структуры состояния или контексты ошибок.
Если вызов происходит внутри цепочки событий, инициированных платформой автоматически, может возникнуть путаница в количестве аргументов. Чтобы проверить это, в момент возникновения ошибки (если её удается поймать в отладчике) необходимо обязательно открыть окно «Стек вызовов». Обратите внимание на то, какая процедура вызвала ЗакончитьЗамерВремениАвто. Если вы видите там системные обработчики или неопознанные вызовы, проблема кроется в нестабильной работе сеанса после критической ошибки.
Если в вашей базе используются расширения, проверьте, не заимствован ли в них модуль ОценкаПроизводительностиВызовСервера или ОценкаПроизводительностиКлиентГлобальный. Даже если вы не меняли количество параметров, само наличие аннотаций &Перед, &После или &Вместо может влиять на компиляцию вызова. Платформа иногда ошибочно интерпретирует расширенный метод, добавляя к нему внутренние параметры для управления выполнением расширения. Для быстрого выявления подобных несоответствий в сигнатурах методов можно использовать инструмент для автоматического анализа конфигураций и расширений.
Если снять модуль с поддержки нельзя, а ошибка мешает работе пользователей, мы можем применить методику создания «прослойки». Рассмотрим по шагам, как это реализовать через расширение:
ОценкаПроизводительностиВызовСервера.ОценкаПроизводительностиКлиентГлобальный заменим вызов типовой процедуры на вызов нашей новой процедуры из расширения.Пример кода в расширении для модуля ОценкаПроизводительностиВызовСервера:
&Вместо("ЗафиксироватьВремяОкончания")
Процедура Имя_ЗафиксироватьВремяОкончанияБезопасно(Параметр1, Параметр2)
// Вызываем оригинальный метод, явно контролируя количество передаваемых данных
ПродолжитьВызов(Параметр1, Параметр2);
КонецПроцедуры
Зачастую подсистема «Оценка производительности» включена по умолчанию в типовых решениях (например, БП 3.0 или УТ 11), но реально не используется компанией для анализа. Если ошибка «плавает» и её невозможно локализовать, а замеры производительности вам не требуются, самым эффективным решением будет просто отключить этот функционал.
Разберем, как это сделать в интерфейсе:
После этого вызовы процедур в модуле ОценкаПроизводительностиКлиентГлобальный прекратятся, и ошибка перестанет беспокоить пользователей. Это не решает вопрос «почему платформа ведет себя так», но полностью снимает симптомы проблемы в продуктивной среде.
Выяснив причину, мы понимаем, что ошибка «Слишком много фактических параметров» при их визуальном равенстве — это сигнал о сбое в механизме компиляции или кэширования 1С. Основные инструменты борьбы с этим: очистка серверного кэша, анализ стека вызовов и, в крайнем случае, программный обход через расширение или отключение проблемного функционала. Помните, что стабильность работы системы важнее, чем работа фоновых сервисов мониторинга, которыми никто не пользуется.