Как выполнить код на сервере в толстом клиенте 1С при использовании обычных форм

Программист 1С v8.3 (Обычные формы) Торговля и дистрибуция
← На главную

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

Анализ проблемы: почему директивы не работают в обычных формах

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

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

Решение 1: Использование серверных общих модулей

Рассмотрим основной и самый правильный с точки зрения архитектуры способ выноса кода на сервер — использование общего модуля. Выясним, какие условия должны быть соблюдены, чтобы этот механизм заработал:

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

Посмотрим на пример кода, который мы можем разместить в таком модуле для оптимизации получения данных:


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

Теперь в нашей внешней обработке (обычная форма) мы просто вызываем эту функцию. Разберем, в чем выгода: по сети VPN пройдет только маленькая структура ПараметрыФильтра в одну сторону и уже готовая, сжатая таблица результатов в другую сторону. Тяжелый процесс соединения таблиц и первичная выборка произойдут внутри локальной сети сервера приложений и сервера БД.

Решение 2: Использование фоновых заданий (без изменения конфигурации)

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

Фоновые задания в 1С всегда выполняются на стороне сервера. Мы можем запустить процедуру из модуля объекта нашей обработки как фоновое задание. Рассмотрим алгоритм действий:

  1. Поместим логику обработки данных в Модуль объекта внешней обработки (не в модуль формы!).
  2. В модуле формы напишем код запуска задания через ФоновыеЗадания.Выполнить().
  3. Для передачи результата используем Временное хранилище.

Разберем пример реализации этого метода:


// Код в модуле формы обработки
Процедура КнопкаВыполнитьНажатие(Кнопка)
    // Помещаем саму обработку во временное хранилище, чтобы сервер мог её прочитать
    АдресОбработки = ПоместитьВоВременноеХранилище(ЭтотОбъект.ПолучитьМакет("ДанныеОбработки")); 
    
    УникальныйИдентификаторЗадания = Новый УникальныйИдентификатор;
    ПараметрыЗадания = Новый Массив;
    ПараметрыЗадания.Добавить(НужныеПараметры);
    ПараметрыЗадания.Добавить(УникальныйИдентификаторЗадания);
    
    // Запускаем серверный метод через фоновое задание
    Задание = ФоновыеЗадания.Выполнить("ИмяВашегоОбщегоМодуля.ВыполнитьПроцедуруОбработки", ПараметрыЗадания);
    Задание.ОжидатьЗавершения();
    
    Результат = ПолучитьИзВременногоХранилища(УникальныйИдентификаторЗадания);
    // Обрабатываем полученный результат
КонецПроцедуры

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

Решение 3: Переход на управляемые формы внутри обычного приложения

Выясним еще одну интересную особенность платформы 8.3. Она позволяет в режиме обычного приложения открывать управляемые формы. Если ваша задача требует частого взаимодействия с сервером, возможно, стоит перерисовать форму обработки, сделав её управляемой. В процессе проектирования интерфейса вам может пригодиться конструктор управляемых форм, позволяющий гибко настраивать элементы.

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

Важные технические нюансы и выводы

Подводя итог нашему анализу, выделим ключевые правила работы с контекстом в толстом клиенте:

Таким образом, мы выяснили, что простое написание директивы &НаСервере в коде старой обработки — это путь в никуда. Для реальной оптимизации работы через VPN необходимо использовать либо серверные общие модули с флагом «Вызов сервера», либо переходить на технологию управляемых форм.

← На главную