Как правильно вызвать серверную процедуру или функцию из клиентского кода с передачей параметров в 1С:Предприятие 8.3?

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

В процессе разработки на платформе 1С:Предприятие 8.3 одной из наиболее частотных задач является организация взаимодействия между клиентской частью приложения и сервером. Поскольку управляемое приложение четко разделяет среду исполнения кода, программисту необходимо понимать, как эффективно передавать данные «туда и обратно». В этой статье мы подробно разберем механизмы вызова серверных процедур из клиентских, затронем использование ИИ-помощника для написания кода, проанализируем использование различных директив компиляции и выясним, как правильно передавать параметры разных типов.

Основы взаимодействия клиента и сервера

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

  1. &НаКлиенте — код выполняется на стороне пользователя.
  2. &НаСервере — код выполняется на сервере с доступом к контексту формы.
  3. &НаСервереБезКонтекста — код выполняется на сервере максимально быстро, так как данные формы не передаются.

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

Вариант 1: Вызов процедуры с контекстом формы

Рассмотрим случай, когда нам необходимо на сервере обратиться к реквизитам формы (например, прочитать значение поля ввода или изменить состояние элементов управления). В этом случае используется директива &НаСервере.

Посмотрим на пример кода, где мы передаем массив идентификаторов товаров для расчета их общей стоимости:


&НаКлиенте
Процедура РассчитатьСтоимостьНажатие(Команда)
    
    МассивТоваров = Новый Массив;
    МассивТоваров.Добавить(Объект.Товары[0].Номенклатура); // Пример того, как работает получение значения реквизита по ссылке
    
    // Вызываем серверную функцию
    ИтоговаяСумма = ПолучитьСуммуНаСервере(МассивТоваров);
    
    Сообщить("Итоговая сумма: " + ИтоговаяСумма);
    
КонецПроцедуры

&НаСервере
Функция ПолучитьСуммуНаСервере(ПараметрыРасчета)
    
    Сумма = 0;
    // Здесь доступен объект "ЭтаФорма" и "Объект"
    Для Каждого ТекТовар Из ПараметрыРасчета Цикл
        // Логика расчета
        Сумма = Сумма + 100; // Условный расчет
    КонецЦикла;
    
    Возврат Сумма;
    
КонецФункции

Важно понимать, что при использовании &НаСервере платформа упаковывает все данные формы, передает их на сервер, там восстанавливает контекст, выполняет код, а затем отправляет измененный контекст обратно. Это может замедлять работу, если форма «тяжелая» (содержит много данных или большие таблицы).

Вариант 2: Оптимизированный вызов без контекста

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

Рассмотрим, как это выглядит на практике. Допустим, нам нужно проверить корректность ИНН контрагента:


&НаКлиенте
Процедура ПроверитьКонтрагента(Команда)
    
    ТекИНН = Объект.ИНН; // Берем данные с клиента
    
    Если ПроверитьИНННаСервере(ТекИНН) Тогда
        Сообщить("ИНН корректен");
    Иначе
        Сообщить("Ошибка в ИНН");
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПроверитьИНННаСервере(Знач ИНН)
    
    // Здесь НЕ доступны реквизиты формы напрямую. 
    // Все данные должны быть переданы через параметры.
    
    Результат = Истина; // Представим, что здесь сложная проверка в БД
    Возврат Результат;
    
КонецФункции

В данном примере функция ПроверитьИНННаСервере является статической по отношению к форме. Она получает значение ИНН, выполняет действия и возвращает результат. Это лучший способ написания производительного кода.

Особенности передачи параметров различных типов

Выясним причину, по которой иногда возникают ошибки при вызове сервера. Не все типы данных в 1С можно передавать между клиентом и сервером. К сериализуемым (допустимым) типам относятся:

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

Рассмотрим пример передачи сложной структуры параметров:


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

&НаСервереБезКонтекста
Функция ОбработатьДанныеНаСервере(Данные)
    
    // Читаем данные из структуры
    СкладСсылка = Данные.Склад;
    // Выполняем действия...
    
    Возврат "Успешно";
    
КонецФункции

Возврат значений из серверных функций

Если нам нужно не просто выполнить действие на сервере, но и получить результат, мы используем конструкцию Функция. Процедуры на сервере значений не возвращают.

Разберем по шагам, как вернуть сложный объект, например, структуру с несколькими результатами:

  1. Создаем функцию с директивой &НаСервере или &НаСервереБезКонтекста.
  2. Внутри функции формируем структуру Результат = Новый Структура;.
  3. Наполняем структуру данными.
  4. Используем ключевое слово Возврат.
  5. На клиенте принимаем это значение в переменную.

&НаСервереБезКонтекста
Функция ПолучитьДанныеКонтрагента(СсылкаКонтрагент)
    
    Ответ = Новый Структура;
    Ответ.Вставить("КПП", СсылкаКонтрагент.КПП);
    Ответ.Вставить("ПолноеНаименование", СсылкаКонтрагент.НаименованиеПолное);
    
    Возврат Ответ;
    
КонецФункции

Рекомендации по повышению производительности

Проанализируем несколько советов, которые помогут сделать ваши вызовы более эффективными:

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

← На главную