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