Общие модули, директивы препроцессора и компиляции
В 1С ебанутые правила, связанные с модульностью. Свойства модуля:
- Способ обращения к подпрограммам
- «Глобальный». Возможность вызова подпрограмм без указания имени модуля. Имена должны быть уникальными в разрезе всего глобального контекста.
- Область видимости
- «Клиент». Возможность исполнения подпрограмм модуля на клиенте;
- «Сервер». Возможность исполнения подпрограмм модуля на сервере;
- «Внешнее соединение». Возможность исполнения подпрограмм модуля через подключение внешнего источника;
- Возможности со стороны подпрограмм модуля
- «Вызов сервера». Возможность подпрограмм модуля вызывать сервер, выполняясь на клиенте;
- «Привилегированный». При работе кода процедур модуля не проверяет права доступа. Вызвать общий модуль с такой настройкой можно только на сервере. Настройки «Клиент» и «Внешнее соединение» будут сброшены;
- Кэширование
- «Повторное использование». Варианты: «Не использовать», «На время сеанса», «На время вызова». При многократном вызове одной процедуры система может использовать рассчитанные ранее данные в рамках процедуры (вызов) или жизни всего сеанса (запуска 1С). Использовать осознанно.
Для разграничения кода можно использовать директивы препроцессора
Процедура АлгоритмСерверКлиент() Экспорт
#Если ТонкийКлиент Тогда
ПоказатьОповещениеПользователя("На клиенте");
ИначеЕсли Сервер Тогда
ПеременнаяСервер = "Серверный вызов";
#КонецЕсли
КонецПроцедуры
Директивы препроцессора и компиляции
Есть два режима, определяются при создании конфигурации: на локальном ПК (файловый) и на сервере 1С (клиент-серверный вариант). Файловый вариант объединяет в себе и код клиента, и код сервера, поэтому смысла от деления кода при помощи директив препроцессора нет.
Преобразование в машинный код и исполнение кода происходит так:
- Препроцессор используя директивы препроцессора и области видимостей модулей создает несколько слегка отличающихся копий (в соответствии с количеством платформ) кода. Директивы компиляции игнорируются. По умолчанию (без директив) все подпрограммы попадают во все копии. При наличии, код физически вырезается, и другая платформа не видит и никак не может исполнить процедуры не для себя. Нужно для уменьшения объема кода и ускорения работы каждого из блоков.
- Код компилируется для каждой платформы. Используя директивы компиляции, формируются алгоритмы взаимодействия. Например, при вызове из подпрограммы &НаКлиенте подпрограммы &НаСервере форма упаковывается в контейнер (!), переправляется по каналу tcp\ip на сервер, распаковывается сервером, выполняется код целевой процедуры, форма запаковывается обратно в контейнер, передается на клиент, распаковывается клиентом, отображается на экране. В случае с "..БезКонтекста" платформа выполняет код "налегке", т.е. на сервер передаются только параметры функции, а обратно прилетает только результат выполнения. Директивой по умолчанию является &НаСервере.
Директивы препроцессора
При компиляции блоки распределяются в соответствии с директивами. Для указания разрешения использования процедур и функций общих модулей и модулей объектов используют инструкции препроцессора.
Синтаксис:
#Если <Логическое выражение> Тогда
#ИначеЕсли <Логическое выражение> Тогда
#Иначе
#КонецЕсли
<Логическое выражение> = [НЕ] <Символ препроцессора> [<Булева операция> [НЕ] <Символ препроцессора> [<Булева операция> [НЕ] <Символ препроцессора>]…]
<Символ препроцессора> = {НаКлиенте | НаСервере | ТолстыйКлиентОбычноеПриложение | ТолстыйКлиентУправляемоеПриложение | Клиент | Сервер | ВнешнееСоединение }
<Булева операция> = {И | ИЛИ}
Можно использовать И (AND), ИЛИ (OR), НЕ (NOT) Регистр букв не имеет значения.
Области
#Область, #КонецОбласти Нужны только для визуального сворачивания блоков кода. Могут быть вложенными.
#Область [<Имя области>]
#КонецОбласти
Условия
#Если (#If), #Тогда (#Then), #ИначеЕсли (#ElsIf), #Иначе (#Else), #КонецЕсли (#EndIf) Можно организовывать выполнение различных процедур и функций на сервере приложения или на клиентском месте. Для того, чтобы процедура присутствовала и была вызвана на стороне сервера, фрагмент кода должен выглядеть следующим образом:
#Если Сервер Тогда
Процедура Проц1() Экспорт
КонецПроцедуры
#КонецЕсли
При запуске конфигурации на выполнение производится загрузка и компиляция конфигурации. Экземпляры всех общих модулей создаются как на серверной, так и на клиентской стороне.
Далее, при компиляции на стороне клиента модулей, в которых содержится обращение к данной процедуре, будет произведен ее поиск на стороне клиента. На стороне клиента таковой процедуры нет, следовательно, она не будет найдена. Тогда будет произведен поиск процедуры в общих модулях на стороне сервера, где она будет обнаружена и все вызовы будут переправляться для выполнения на сервер "1С:Предприятия".
Если блок #Если Сервер Тогда … #КонецЕсли включает только часть процедуры, то процедура будет присутствовать как на стороне клиента, так и на стороне сервера. Только на клиентской стороне она будет без той части, которая заключена в блок, поэтому результат выполнения процедуры может зависеть от того, где обрабатывается вызов этой процедуры.
Для выполнения на клиентском месте в обычном и управляемом режиме:
#Если НаКлиенте Тогда
#КонецЕсли
Точки исполнения
Инструкция препроцессора НаКлиенте (AtClient) определена для всех клиентских приложений. Для тонкой подстройки модуля под конкретное клиентское приложение дополнительно введены инструкции ТолстыйКлиентОбычноеПриложение (ThickClientOrdinaryApplication), ТолстыйКлиентУправляемоеПриложение (ThickClientManagedApplication), ТонкийКлиент (ThinClient) и ВебКлиент (WebClient), которые определены в соответствующих приложениях.
В обычном клиенте в обычном и управляемом режиме доступны НаКлиенте, Клиент, ТолстыйКлиентОбычноеПриложение, ТолстыйКлиентУправляемоеПриложение , НаСервере, Сервер.
В файловом варианте инструкции препроцессора #Если Сервер…, #Если Клиент…, #Если ТолстыйКлиентОбычноеПриложение или #Если ТолстыйКлиентУправляемоеПриложение… определены всегда, поэтому экземпляр кода будет присутствовать всегда.
В тонком клиенте доступны – ТонкийКлиент, НаКлиенте, Клиент.
На серверной части тонкого клиента – Сервер, НаСервере.
Во внешнем соединении – ВнешнееСоединение, НаСервере, Сервер.
Директивы компиляции
Каждая процедура и функция модуля формы, модуля команды и общего модуля управляемого приложения предваряется директивой компиляции, определяющей среду исполнения данной процедуры. Директива предваряется символом "&".
Запросы между клиентом и сервером за счет директив компиляции корректно формируются только внутри модуля какого-нибудь обработчика. Во внешнем модуле нельзя вызвать подпрограммы разных контекстов. Нужно сначала перейти в соответствующий контекст, затем вызвать подпрограмму.
&НаКлиенте (&AtClient) — определяет клиентскую процедуру (функцию); исполняется в среде клиентского приложения. В такой процедуре доступен клиентский контекст формы и вызовы любых процедур модуля.
&НаСервере (&AtServer) — определяет серверную процедуру (функцию); исполняется в среде серверного приложения. В такой процедуре доступны данные формы, доступен серверный контекст формы и вызовы серверных и серверных внеконтекстных процедур модуля. При вызове такой процедуры данные формы будут передаваться с клиента на сервер и обратно (по окончанию вызова).
&НаСервереБезКонтекста (&AtServerNoContext) — определяет серверную процедуру (функцию), исполняемую на сервере вне контекста формы. Переменные не могут быть внеконтекстными. В таких методах недоступен контекст формы (включая данные формы). Допустимыми являются вызовы только других внеконтекстных методов. При вызове этих методов не выполняется передача данных формы на сервер и обратно. Применение внеконтекстных методов позволяет существенно уменьшить объем передаваемых данных при вызове серверной процедуры из среды клиентского приложения;
&НаКлиентеНаСервереБезКонтекста (&AtClientAtServerNoContext) — определяет процедуру (функцию), исполняемую в модуле формы на клиенте и на сервере, не имеющую доступа к контексту формы, данным формы, переменным, но имеющую доступ к процедурам и функциям общих модулей – серверных, не глобальных и серверных и клиентских одновременно. Сама процедура (функция) доступна для клиентский, серверных контекстных и неконтекстных процедур и функций модуля формы. Из серверных внеконтекстных методов формы допускается вызов серверных методов общих модулей;
&НаКлиентеНаСервере (&AtClientAtServer) — определяет процедуру (функцию), исполняемую в модуле команды, выполняемую на клиенте и на сервере, имеющую доступ к процедурам и функциям общих модулей – серверных, не глобальных и серверных и клиентских одновременно, не имеющую доступ к переменным. Сама процедура (функция) доступна для клиентских серверных процедур и функций модуля команды.
Серверная процедура (функция), исполняемая вне контекста формы, (внеконтекстная) исполняется в среде серверного приложения. В такой процедуре (функции) недоступен контекст формы (включая данные формы). Допустимыми являются вызовы только других внеконтекстных процедур (функций). При вызове этих процедур (функций) не выполняется передача данных формы на сервер и обратно. Применение внеконтекстных процедур (функций) позволяет существенно уменьшить объем передаваемых данных при вызове серверной процедуры (функции) из среды клиентского приложения.
В модуле команды предопределенная процедура-обработчик ОбработатьКоманду должна предваряться директивой &НаКлиенте, так как выполнение команды происходит в клиентском приложении.
Модуль формы
В модуле формы доступны директивы компиляции – &НаКлиенте, &НаСервере, &НаСервереБезКонтекста, &НаКлиентеНаСервереБезКонтекста.
Модуль команды
В модуле команды доступны директивы компиляции – &НаКлиенте, &НаСервере, &НаКлиентеНаСервере.
Общий модуль
В общем модуле доступны директивы компиляции – &НаКлиенте, &НаСервере.