Как передать результат запроса из функции на сервере в переменную на клиенте

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

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

Основы передачи данных между клиентом и сервером

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

  1. Создание функции на сервере, которая выполняет запрос и возвращает результат через инструкцию Возврат.
  2. Вызов этой функции на клиенте и присваивание результата переменной.

Важно помнить о сериализации: с сервера на клиент можно передавать только простые типы данных (числа, строки, даты, булево) или специальные коллекции, такие как Структура или Массив. Вы не сможете передать сам объект РезультатЗапроса или ВыборкаИзРезультатаЗапроса — их нужно «распаковать» на сервере.

Способ 1: Получение данных через объект «Запрос»

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

Серверная часть:


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

Клиентская часть:


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

Способ 2: Использование метода «ПолучитьПоследнее» (объектная техника)

Проанализируем ситуацию, когда нам не нужно писать сложный запрос. Платформа предоставляет удобный метод для работы с регистрами сведений — ПолучитьПоследнее(). Это работает быстрее и код выглядит чище.

Рассмотрим реализацию:


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

Этот метод предпочтителен, так как система сама формирует оптимальный запрос к базе данных. Если на указанную дату записи нет, метод вернет структуру с пустыми значениями (например, 0 для чисел), что не приведет к ошибке.

Типичные ошибки и как их избежать

Разберем основные моменты, на которых часто спотыкаются разработчики:

  1. Неправильные фильтры в запросе. В виртуальных таблицах (таких как СрезПоследних) фильтры нужно устанавливать в параметрах таблицы, а не в секции ГДЕ. Это критически влияет на производительность.
  2. Передача пустых значений. Если функция на сервере вернет Неопределено или пустую строку, а на клиенте вы попытаетесь умножить это на число, программа выдаст ошибку. Всегда приводите результат к нужному типу (например, через 0).
  3. Вызов функции как процедуры. Помните, что результат функции нужно обязательно присвоить переменной: МояПеременная = ИмяФункции();. Если просто написать ИмяФункции();, результат будет получен сервером, но «потерян» при возврате на клиент.

Получение контактной информации и кодов (ЕДРПОУ / ОКПО)

Часто возникает вопрос: как получить адрес, телефон или код организации? Выясним причины, почему это работает иначе.

Код ЕДРПОУ (или ОКПО) обычно является реквизитом справочника Организации или Контрагенты. Его получить проще всего:


&НаСервереБезКонтекста
Функция ПолучитьКодОрганизации(ОрганизацияСсылка)
    // Обращение через точку на сервере допустимо и работает быстро
    Возврат ОрганизацияСсылка.КодПоОКПО; 
КонецФункции

Что касается адресов и телефонов, то в современных конфигурациях они хранятся в специальном регистре или табличной части. Для их получения лучше использовать функции БСП (Библиотеки Стандартных Подсистем):


&НаСервере
Функция ПолучитьАдресКонтрагента(Контрагент)
    // Пример использования типовых механизмов
    Данные = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(Контрагент, Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента);
    Если Данные.Количество() > 0 Тогда
        Возврат Данные[0].Представление;
    КонецЕсли;
    Возврат "";
КонецФункции

Таким образом, мы рассмотрели основные способы извлечения данных из базы и их передачи между программными слоями 1С. Главное — всегда контролировать типы передаваемых данных и использовать возможности серверного контекста максимально эффективно.

← На главную