Меню

Инструкции препроцессора и директивы компиляции

Инструкции препроцессора в 1С 8.3

Препроцессор

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

С помощью инструкций препроцессора можно указать где именно будет выполняться код на встроенном языке: на сервере, на клиенте, в вебклиенте и т.д.

Часть кода расположенная между #Если ВебКлиент Тогда и #КонецЕсли будет отсутствовать в данной процедуре при выполнении не в веб клиенте 1С.

Данный кусок кода будет присутствовать в скомпилированном модуле только при выполнении на сервере, в режиме обычного приложения или при подключении через COM (внешнее соединение).

У каждой инструкции препроцессора обязательно должен быть завершающий оператор #КонецЕсли. Если его не указать, то будет ошибка компиляции «Ожидается завершение оператора препроцессора Если (If)»:

Процесс выполнения кода на встроенном языке 1с:

  1. Обработка исходного кода препроцессором
  2. Компиляция модуля во внутренний байт-код 1С
  3. Исполнение байт-кода на виртуальной машине 1С (интерпретация)

При этом один и тот же модуль может быть скомпилирован как на сервере, так и на клиенте. С помощью инструкций препроцессора можно указать должен ли присутствовать в скомпилированном модуле тот или кусок кода.

Инструкции препроцессора

Возможные варианты инструкций препроцессора:

  • Клиент
  • НаКлиенте
  • НаСервере
  • Сервер
  • ТонкийКлиент
  • ВебКлиент
  • МобильныйАвтономныйСервер
  • МобильноеПриложениеКлиент
  • МобильноеПриложениеСервер
  • МобильныйКлиент
  • ТолстыйКлиентОбычноеПриложение
  • ТолстыйКлиентУправляемоеПриложение
  • ВнешнееСоединение

Клиент и НаКлиенте — одно и то же. Сервер и НаСервере — одно и то же.

Также есть инструкции для выделения областей в модуле и для директивы «Изменение и контроль» в расширениях. В данной статье они не будут рассмотрены.

Инструкции препроцессора и директивы компиляции

Директивы компиляции используются в модулях форм и команд. Они определяют где будет скомпилирована процедура: на клиенте или на сервере. Директивы компиляции начинаются с символа &.

Сначала выполняются инструкции препроцессора, а уже потом определяются директивы компиляции. Например:

Данный кусок кода будет присутствовать в серверном модуле формы, но не будет скомпилирован. В клиентском модуле формы его даже не будет.

Часто инструкции препроцессора по ошибке называют директивы препроцессора. Но правильно все-таки инструкции препроцессора.

Исполнение процедур и функций

В файловой базе данных инструкции препроцессора будут игнорироваться, куски кода не будут вырезаны при компиляции.

В клиент-серверном варианте экземпляры общих модулей создаются как на сервере, так и на клиенте. Если в модуле есть #Если Сервер Тогда … #КонецЕсли, то кусок кода между ними будет только на сервере. Если обратиться к процедуре в этом куске кода на клиенте, то вызов будет перенаправлен на сервер, потому что на клиенте не будет этой процедуры. Если между #Если Сервер Тогда … #КонецЕсли находится только часть процедуры, то она будет присутствовать только на сервере, и тогда вызов этой процедуры на сервере будет отличаться от вызова на клиенте.

Если в модуле есть #Если ТонкийКлиент (или толстый) Тогда … #КонецЕсли, то этот кусок будет только на клиенте. Если там была процедура, то к ней нельзя будет обращаться на сервере, потому что нельзя с сервера вызывать клиента.

В типовых конфигурациях можно часто встретить конструкцию:

Источник



Директивы компиляции и инструкции препроцессора

Эти конструкции предназначены для явного указания того, где должен выполняться программный код. Для этого во встроенном языке 1с существуют специальные конструкции.

Директивы компиляции

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

&НаКлиенте — определяет клиентскую процедуру (функцию).
&НаСервере — определяет серверную процедуру (функцию) с контекстом.
&НаСервереБезКонтекста — определяет серверную процедуру (функцию) без контекста.
&НаКлиентеНаСервереБезКонтекста — определяет процедуру (функцию), исполняемую в модуле формы на клиенте и на сервере.
&НаКлиентеНаСервере — определяет процедуру (функцию), исполняемую в модуле команды, выполняемую на клиенте и на сервере.
Без контекста — это означает без доступа к данным формы.

Инструкции препроцессора

Инструкции могут задаваться для процедур (функций) целиком или для отдельных участков программного кода.

Русский Английский
#Если #If
#Тогда #Then
#ИначеЕсли #ElsIf
#Иначе #Else
#КонецЕсли #EndIf
#Область #Region
#КонецОбласти #EndRegion
Клиент (для совместимости) Client
НаКлиенте AtClient
Сервер (для совместимости) Server
НаСервере AtServer
МобильноеПриложениеКлиент MobileAppClient
МобильноеПриложениеСервер MobileAppServer
ТолстыйКлиентОбычноеПриложение ThickClientOrdinaryApplication
ТолстыйКлиентУправляемоеПриложение ThickClientManagedApplication
ВнешнееСоединение ExternalConnection
ТонкийКлиент ThinClient
ВебКлиент WebClient
И AND
ИЛИ OR
НЕ NOT
Читайте также:  Привод для секционных ворот NordMotors NS 600

#Если НаСервере Тогда
#КонецЕсли

#Если НаКлиенте Тогда
#КонецЕсли

Комментарии (0)

Для того чтобы добавить сообщение, необходимо Войти или Зарегистрироваться

Источник

Что такое инструкции препроцессору 1с

После написания программы на встроенном языке 1С она сохраняется в конфигурацию в составе модуля. При запуске 1С в режиме 1С Предприятие программа на языке 1С будет выполнена.

Сначала немного терминов:

  • Препроцессор — специальная программа, которая перерабатывает программный код из «вида» удобного для работы программиста, в «вид», удобный для работы копилятора;
  • Компилятор — специальная программа, которая умеет перерабатывать программный код в «машинный» код — выполняемый непосредственно процессором компьютера;
  • Интерпретатор — специальная программа, которая вместо компилирования кода в машинный код для процессора, выполняет его самостоятельно. Интерпретатор с предварительной компиляцией — компилирует программу не в машинный код, а в специальный «байт-код» удобный для последующего выполнения интерпретатором.

Как выполняются программы написанные на встроенном языке 1С?

Программа на языке 1С перед выполнением компилируется – преобразовывается в специальный код.

Выполнение кода на языке 1С производится в три этапа:

  • Обработка модулей препроцессором 1С согласно директив препроцессора 1С
  • Компиляция в байт-код
  • Исполнение

Компиляция производится отдельно на клиенте и отдельно на сервере (даже одного и того же модуля), при первом обращении к нему.

Компилятор 1С на входе получает модуль не в том виде, в каком его видит программист. Препроцессор 1С разрезает модуль на части (вырезая не нужное) и потом соединяет его.

Директива препроцессора 1С — это способ указать препроцессору 1С где будет выполняться указанный участок кода на языке 1С.

Это связано с тем, что выполнение текста программы производится на сервере и на клиенте. Есть функции и процедуры, которые не могут быть выполнены на сервере/клиенте. Например на сервере Вы не можете показать пользователю предупреждение с необходимостью нажатия кнопки ОК.

Поэтому в модуле указывается где должен выполняться код:

  • Общий модуль (ветка Общие/Общие модули) – в свойствах модуля указывается может ли он выполняться на сервере и на клиенте
  • В остальных модулях – для этого используются директива препроцессора 1С.

Непосредственно в тексте модуля, блоки программного кода, отмечаются директивы препроцессора 1С:
Функция Пример1() //будет выполнена и на клиенте и на сервере
КонецФункции

#Если Сервер Тогда //будет выполнена только на сервере
Процедура Пример2()
КонецПроцедуры
#КонецЕсли

#Если Клиент Тогда //будет выполнена на [любом] клиенте
Процедура Пример3()
КонецПроцедуры
#КонецЕсли

Если никаких инструкций препроцессору 1С в тексте не указано, и использована функция, которую нельзя выполнять на сервере/клиенте, то в момент компилирования модуля (при первом доступе к нему) в исполняемом режиме будет вызвана ошибка.

«Обертывать» можно не только функции, но и конкретные строки исполняемого кода.

Так как компиляция 1С на данный момент еще не началась, то можно с помощью таких блоков создавать функции с одинаковыми наименованиями (для сервера, для клиента).

Есть разница между «функция есть на сервере» и «функцию можно вызывать на сервере». Во втором случае функция «видна» с клиента и может быть вызвана. В первом – не видна на клиенте и может быть вызвана только из другой функции, выполняемой на сервере. Поэтому есть инструкция #Сервер (доступен вызов с клиенте) и #НаСервере (видна только на сервере), и аналогично для клиента.

В модуле управляемой формы инструкции препроцессору 1С рекомендуется использовать только внутри функций/процедур.

После того, как препроцессор 1С «склеил» модуль, он передает его компилятору 1С, который его компилирует. Далее в режиме исполнения код будет выполнен.

При выполнении кода одного модуля, [может] происходит разовое/множественное переключения выполнения с клиента на сервер и обратно.

Например, если требуется выполнить запрос к базе данных, то выполнение будет переключено на сервер, выполнен запрос, данные переданы на клиент. Таким образом модуль существует на сервере и на клиенте.

Переключение исполнения с клиента на сервер и обратно производится «автоматически».

По умолчанию толстый клиент выполняет весь код на клиенте и иногда вызывает сервер. Тонкий клиент наоборот – все выполняет на сервере и иногда вызывает клиент (хотя в любом случае инициализация первого вызова сервера производится клиентом).

Программист в получившемся «склеенном» модуле может для каждой функции указать, где ее требуется исполнять. Не забываем, что доступ к данным производится на сервере, а инициализация вызова на клиенте. Например:
&НаСервере
Функция ПолучитьДанныеБазыДанных()
Запрос = Новый Запрос(«»);
КонецФункции

Ранее, в толстом клиенте, форма создавалась и была доступна только на клиенте (если не передать ее параметром на сервер, конечно). Управляемая форма создается на сервере и может обрабатываться на клиенте и на сервере.

Читайте также:  Для чего проводится внеплановый инструктаж по пожарной безопасности

Поэтому, при выполнении функций модуля, при переключении выполнения с клиента на сервер и обратно, передаются кроме прочего все данные формы (называется «контекст»).

Данных может быть много и передаваться они будут «долго». А в вызываемой функции они могут быть и не нужны, она их не использует вовсе. Для таких случаев есть директива &НаСервереБезКонтекста.

Источник

Использование директив компиляции и инструкций препроцессора

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

1. Директивы компиляции:

&НаКлиенте (&AtClient)
&НаСервере (&AtServer)
&НаСервереБезКонтекста (&AtServerNoContext)

следует применять только в коде модулей управляемых форм и в коде модулей команд. В остальных модулях рекомендуется применять инструкции препроцессору.

В серверных или клиентских общих модулях контекст исполнения очевиден, поэтому смысла в директивах компиляции нет. В общих модулях с признаками клиент и сервер применение директив компиляции затрудняет понимание, какие же процедуры (функции) доступны в конечном итоге.

2. Не следует использовать инструкции препроцессора в клиент-серверных общих модулях для проверки клиентского и серверного контекстов (#Если Сервер, #Если Клиент) ввиду невозможности надежного определения контекста исполнения. Процедуры и функции, которые работают по-разному при вызове с клиента и с сервера, следует размещать в общих модулях с постфиксами Клиент и Сервер , а не КлиентСервер .

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

Функция КодОсновногоЯзыка() Экспорт
#Если НЕ ТонкийКлиент И НЕ ВебКлиент Тогда
Возврат Метаданные.ОсновнойЯзык.КодЯзыка;
#Иначе
Возврат СтандартныеПодсистемыКлиент.ПараметрКлиента(«КодОсновногоЯзыка»);
#КонецЕсли
КонецФункции

Функция КодОсновногоЯзыка() Экспорт
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
Возврат Метаданные.ОсновнойЯзык.КодЯзыка;
#Иначе
Возврат СтандартныеПодсистемыКлиент.ПараметрКлиента(«КодОсновногоЯзыка»);
#КонецЕсли
КонецФункции

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

В то же время, как и в обычных клиентских модулях, допустимо ветвление кода для учета специфики различных режимов работы клиентского приложения: веб-клиент, тонкий или толстый клиент (например, #Если ВебКлиент).

3. Не следует разрывать инструкциями препроцессора и областями отдельные грамматические конструкции, выражения, а также объявления и места вызова процедур и функций.

Процедура Пример1()
а = 1
#Область ИмяОбласти
+ 2;
#КонецОбласти // разрыв выражения
КонецПроцедуры

#Область ИмяОбласти
Процедура Пример2()
// .
#КонецОбласти // разрыв процедуры
КонецПроцедуры

Если Тогда
// .
#Если ВебКлиент Тогда // разрыв блока Если
Иначе
// .
#КонецЕсли
КонецЕсли;

Результат = Пример4(Параметр1,
#Если Клиент Тогда
Параметр2, // некорректный вызов функции
#КонецЕсли
Параметр3);

Данные ошибки диагностируются автоматически с помощью среды разработки 1C:Enterprise Development Tools (EDT).

Правильно использовать инструкции препроцессора без разрыва конструкций.

Источник

Код Икс Пи :: Лучшие IT-решения для бизнеса

Nav view search

Navigation

  • Главная
  • Прайс
  • Контакты
  • Услуги
  • Заметки
  • Вход

Search

Инструкции препроцессору

Синтаксис инструкций препроцессору

Процесс компиляции и исполнения программного кода проходит в 1С в несколько стадий. Препроцессор вырезает все «лишнее» из процедуры (для данного контекста), и передает на компиляцию, компилятор производит компиляцию в машинный код, интерпретатор получает машинный код и исполняет его. Некоторые куски кода могут быть намерено объявлены программистом как «лишние» для сервера. Таким образом один и тот же модуль может быть выполнен в двух разных вариантах, например при исполнении на клиенте он будет содержать блок интерактивного взаимодействия с пользователем, а при исполнении на сервере нет, в этом нет никакого смысла, более того модуль может быть завершен с ошибкой исполнения из-за недоступности интерактивного метода на сервере.

  • Препроцессор — специальная программа, которая перерабатывает программный код из «вида» удобного для работы программиста, в «вид», удобный для работы копилятора;
  • Компилятор — специальная программа, которая умеет перерабатывать программный код в «машинный» код — выполняемый непосредственно процессором компьютера;
  • Интерпретатор — специальная программа, которая вместо компилирования кода в машинный код для процессора, выполняет его самостоятельно. Интерпретатор с предварительной компиляцией — компилирует программу не в машинный код, а в специальный «байт-код» удобный для последующего выполнения интерпретатором.

О том как код написанный программистом превращается в байт код интересно описано в статьте на хабре https://habr.com/ru/post/489392/

Рассмотрим конкретный пример. Например у нас запущена конфигурация в режиме толстого клиента (без управляемых форм). В модуле объекта мы сделали предупреждение о нехватке остатка на складе (не стоит так делать в реальных базах).

Читайте также:  Микросистема LG LX M340 микро Hi Fi центр Субъективные впечатления объективного пользователя

Как видим на рисунке все работает и выполняется. Но проблема в том, что если данный документ будет проводится какой-то регламентной работой, которая будет выполняться на сервере 1С:Предприятие, то модуль просто не будет скомпилирован. Создадим новый общий модуль и выставим у него «Сервер» и «Вызов сервера»:

В модуле попытаемся создать документ с превышением остатка:

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

В контексте серверного модуля прекрасно создается документ, но метод предупреждение не работает. Идем в справку для метода «Предупреждение» (ctrl-F1), нас интересует в справке раздел «доступность». В разделе доступность нет слова «Сервер», значит этот метод в серверных модулях не может быть использован, модуль попросту не скомпилируется.

Как поступить если необходимо часть модуля выполнять только там где он доступен, а остальной код трогать не хочется? Надо использовать инструкции препроцессору, т.е. объяснить программе что кусочек кода должен присутствовать\исполняться только тогда когда он может быть выполнен.

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

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

Инструкции могут включать целиком процедуру или несколько процедур

Используемые термы (ключевые слова):

Директивы комплиляции

Директивы появились вместе с управляемыми формами. Дело в том что при создании управляемой формы модуль формы компилируется одновременно и на сервере и на клиенте, но в клиентском варианте не будут присутствовать процедуры перед которыми отсутствует ключевое слово «..Клиенте..», для серверной копии модуля аналогично.

  • &НаКлиенте — определяет клиентскую процедуру (функцию).
  • &НаСервере — определяет серверную процедуру (функцию) с контекстом.
  • &НаСервереБезКонтекста — определяет серверную процедуру (функцию) без контекста.
  • &НаКлиентеНаСервереБезКонтекста — определяет процедуру (функцию), исполняемую в модуле формы на клиенте и на сервере.
  • &НаКлиентеНаСервере — определяет процедуру (функцию), исполняемую в модуле команды, выполняемую на клиенте и на сервере.
    Без контекста — это означает без доступа к данным формы.

Директивы &НаКлиенте и подобные принципиально отличаются от инструкций препроцессору. Инструкция, как правило, просто вырезает кусок кода перед тем как он будет передан на компиляцию, а с директивой программа точно знает что такая функция все же есть, но будет выполнена на стороне сервера\клиента.

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

Совместное использование инструкций и директив

Ошибки использования директив компилятору

Излишне частое и неоправданное выполнение контекстных вызовов &НаСервере

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

Процесс исполнения серверного вызова выглядит примерно следующим образом: форма упаковывается в контейнер (!), переправляется по каналу tcp\ip на сервер, распаковывается сервером, выполняется код целевой процедуры, форма запаковывается обратно в контейнер, передается на клиент, распаковывается клиентом, отображается на экране.

Сразу становится понятным что такие вещи стоит делать как можно реже, и уж точно не в цикле! В случае с «..БезКонтекста» платформа выполняет код «налегке», т.е. на сервер передаются только параметры функции, а обратно прилетает только результат выполнения.

Использование &НаСервере вместо &НаКлиенте

Иногда программист помещает весь код в процедуру «на сервере» хотя код может быть выполнен на клиенте. Если ведется работа с простыми типами (доступными на клиенте), намного лучше весь код выполнить на клиенте. Если необходимо что-то получить с сервера, создать дополнительную функцию «на сервере без контекста» для получения данных, которые невозможно получить в текущей клиентской функции.

Источник

Adblock
detector