Как получить данные с сервера на клиент через функцию в 1С 8.3

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

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

Понятие контекста и директивы выполнения

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

Шаг 1: Создание серверной функции для поиска данных

Рассмотрим ситуацию: нам нужно проверить, существует ли в базе документ "Задание менеджера" на текущую дату для конкретного сотрудника. Поскольку запрос к базе данных возможен только на сервере, мы создадим функцию. Мы будем использовать директиву &НаСервереБезКонтекста, так как это наиболее производительный метод.

Давайте проанализируем код серверной функции:


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

В этом примере мы возвращаем не просто Истина или Ложь, а саму ссылку на найденный документ. Это более профессиональный подход: если документ найден, мы сразу сможем открыть его на клиенте, не делая повторных запросов.

Шаг 2: Вызов функции с клиента и обработка результата

Теперь разберем, как правильно вызвать эту функцию из обработчика события ПриИзменении на клиенте. Основная ошибка начинающих — попытка обратиться к реквизиту Менеджер напрямую внутри серверного вызова. На клиенте мы должны передавать Объект.Менеджер.

Рассмотрим по шагам логику клиентской процедуры:


&НаКлиенте
Процедура МенеджерПриИзменении(Элемент)
    
    // 1. Проверяем, заполнено ли значение на клиенте, чтобы не гонять пустой запрос на сервер
    Если ЗначениеЗаполнено(Объект.Менеджер) Тогда
        
        // 2. Вызываем серверную функцию и ловим результат в переменную
        // Передаем именно Объект.Менеджер, так как мы работаем без контекста
        СсылкаНаДокумент = НайтиЗаданиеМенеджераНаТекущуюДату(Объект.Менеджер);
        
        // 3. Анализируем полученные данные
        Если ЗначениеЗаполнено(СсылкаНаДокумент) Тогда
            
            // Если документ найден, предлагаем пользователю его открыть
            ПоказатьЗначение(, СсылкаНаДокумент);
            
        Иначе
            
            // Если документ не найден, выводим предупреждение и ограничиваем доступ к форме
            Объект.ТолькоПросмотр = Истина; // Пример блокировки формы
            ТекстСообщения = "На сегодня у менеджера нет проведенного задания! Форма заблокирована.";
            ПоказатьПредупреждение(, ТекстСообщения);
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Типичные ошибки при передаче данных

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

Также важно помнить о количестве параметров. Если в определении функции написано Функция Имя(Параметр1, Параметр2), то при вызове вы обязаны передать оба значения, иначе система выдаст ошибку "Недостаточно фактических параметров".

Почему стоит возвращать Ссылку, а не Булево?

Как мы увидели в примере выше, возвращая Ссылка (или Неопределено), мы получаем гораздо больше гибкости. Если ваша задача — просто проверить наличие, то Истина/Ложь достаточно. Но в 90% случаев в бизнес-логике после проверки следует действие с объектом. Если вы вернете Истина, вам придется снова идти на сервер, чтобы найти этот документ для открытия. Возврат ссылки позволяет избежать лишнего "round-trip" (похода на сервер), что критически важно для производительности системы.

Использование асинхронных методов

Обратите внимание, что в примере кода использована функция ПоказатьПредупреждение() вместо старого метода Предупреждение(). В современных версиях платформы 1С (начиная с 8.3.15 и выше) работа в режиме "без модальности" является стандартом. Асинхронные методы не блокируют выполнение всего приложения и корректно работают в веб-клиенте. При написании нового кода всегда старайтесь использовать методы с префиксом Показать....

Резюме

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

  1. Определите, нужен ли вам контекст всей формы. Если нет — используйте &НаСервереБезКонтекста.
  2. В параметрах функции опишите все данные, которые ей нужны для работы (например, ссылку на менеджера или дату).
  3. В тексте функции обязательно используйте оператор Возврат, чтобы передать результат обратно.
  4. На клиенте вызывайте функцию как часть выражения или присваивайте её результат переменной: Результат = МояФункция(Параметры);.
  5. Всегда проверяйте результат функции на клиенте перед тем, как использовать его в логике интерфейса.

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

← На главную