В процессе разработки в системе 1С:Предприятие часто возникает задача унификации кода. Например, когда алгоритм расчета должен запускаться интерактивно пользователем (с данными, которые еще не записаны в базу и находятся на клиенте) и одновременно с этим — автоматически при старте системы или по регламентному заданию (полностью на стороне сервера). Рассмотрим подробнее, как реализовать такую логику, какие инструменты предоставляет платформа и какие "подводные камни" могут встретиться на пути.
Для начала разберем основное различие, которое часто путает начинающих разработчиков. В 1С существует два способа управлять тем, где будет выполнен код: директивы компиляции и инструкции препроцессора. Проанализируем, в чем их разница.
Директивы компиляции (начинаются с символа &) используются в модулях управляемых форм и команд. Они указывают платформе, в какой контекст "поместить" процедуру или функцию при компиляции модуля.
&НаКлиенте — процедура доступна только на стороне клиента.&НаСервере — процедура выполняется на сервере с передачей всего контекста формы.&НаСервереБезКонтекста — серверный вызов без передачи данных формы (наиболее производительный вариант).&НаКлиентеНаСервереБезКонтекста — специальная директива, которая создает две копии метода: одну для клиента, другую для сервера.Инструкции препроцессора (начинаются с символа #) работают на этапе предварительной сборки кода. Они буквально вырезают или оставляют куски текста программы в зависимости от среды исполнения. Они чаще всего применяются в общих модулях.
#Если Сервер Тогда
// Этот код попадет только в серверную сборку
Результат = ВыполнитьРасчетНаСервере();
#ИначеЕсли НаКлиенте Тогда
// Этот код будет доступен только клиенту
Результат = ВыполнитьРасчетНаКлиенте();
#КонецЕсли
Если ваша задача — написать математический расчет, обработку строки или заполнение структуры, которая не требует обращения к базе данных напрямую, этот метод идеален. Рассмотрим, как это работает в модуле формы. Проанализируем пример кода:
&НаКлиентеНаСервереБезКонтекста
Процедура РассчитатьПоказатели(ПараметрыРасчета) Экспорт
// Данный код будет скомпилирован и для клиента, и для сервера
ПараметрыРасчета.Результат = ПараметрыРасчета.Цена * ПараметрыРасчета.Количество;
КонецПроцедуры
Важно помнить: внутри такой процедуры нельзя использовать методы, доступные только на сервере (например, Запрос) или только на клиенте (например, Предупреждение). Платформа ограничит вас только тем набором функций, который является общим для обеих сред.
Когда расчет должен инициироваться и при запуске системы (в МодулеУправляемогоПриложения), и в процессе работы из формы, правильнее всего вынести логику в Общий модуль. Выясним причину, по которой в общих модулях не работают директивы типа &НаСервере. В общих модулях управление средой выполнения осуществляется через свойства самого модуля (флажки в конфигураторе).
Рассмотрим по шагам настройку такого модуля:
ОбщийРасчетСервер).Однако здесь кроется нюанс: если у модуля включены флаги и "Клиент", и "Сервер", то при вызове его метода с клиента, 1С попытается выполнить его именно на клиенте. Чтобы гарантировать выполнение на сервере, лучше разделять модули на чисто серверные и клиентские, либо использовать инструкции препроцессора внутри методов.
Иногда разработчики сталкиваются с тем, что МодульУправляемогоПриложения "не видит" процедуру, даже если она помечена правильной директивой. Разберем основные причины:
Экспорт.Если ваш отчет сложный и данные для него формируются на клиенте, их невозможно просто "увидеть" на сервере. Разберем, как правильно передать эти данные для серверного расчета:
ПоместитьВоВременноеХранилище().ПолучитьИзВременногоХранилища(Адрес).Пример реализации передачи данных:
// На клиенте
АдресДанных = ПоместитьВоВременноеХранилище(МояТаблицаДанных, ЭтаФорма.УникальныйИдентификатор);
ОбщийРасчетСервер.ВыполнитьОбработкуНаСервере(АдресДанных);
// В общем модуле (Сервер, Вызов сервера)
Процедура ВыполнитьОбработкуНаСервере(АдресДанных) Экспорт
Данные = ПолучитьИзВременногоХранилища(АдресДанных);
// Теперь данные доступны для серверных запросов и расчетов
КонецПроцедуры
Таким образом, мы обеспечиваем эффективную работу системы: тяжелые расчеты уходят на сервер, а интерфейс клиента остается отзывчивым. Использование общих модулей с грамотно расставленными флагами компиляции позволяет использовать один и тот же программный код в разных сценариях запуска 1С:Предприятия.