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

Директивы в 1С &НаКлиенте &НаСервере &НаСервереБезКонтекста &НаКлиентеНаСервереБезКонтекста

Для чего нужны директивы компиляции?

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

Немного истории

С появлением 1С:Предприятие 8.2, разработчики могут явно указывать, где будет выполняться код — на клиенте или на сервере. Это стало особенно актуально с развитием «тонкого клиента» и «веб-клиента». Они требуют тщательного управления передачей данных между клиентом и сервером. До появления Предприятие 8.2 был толстый клиент. В нем было доступен функционал и клиента и сервера. С появлением тонкого клиента выполнение кода стало разделяться на клиента и сервера.

Если говорить проще, то в современных конфигурациях, построенных на управляемых формах, код распределяется между клиентом и сервером. Клиент отвечает за интерфейс, а сервер — за работу с базой данных, бизнес-логикой и объектами метаданных.

Директивы позволяют:

  • явно указать место выполнения метода;
  • избежать ошибок доступа к несуществующим объектам (например, попытки обратиться к таблице базы данных напрямую с клиента);
  • повысить производительность, вынося тяжелые вычисления на сервер;
  • организовать безопасность, скрывая серверную логику от клиента.

Директивы компиляции используются только в модулях управляемых форммодулях команд и модулях объектов (в последних — только &НаСервере, так как объекты существуют только на сервере). В общих модулях директивы не применяются: вместо этого контекст выполнения задаётся флагами модуля («Клиент», «Сервер» и т.д.). Использование директив в общем модуле является нарушением стандартов и может привести к неоднозначному поведению.

Контекстные и неконтекстные вызовы

Контекстные вызовы используются, когда нужно передать на сервер не только данные, которые мы явно указали, но и все изменения, которые были сделаны на клиенте с момента последнего обращения к серверу. Это означает, что сервер получает всю информацию о форме, которая была изменена на клиенте. Такие вызовы используются, когда на сервере нужно что-то сделать с данными формы.

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

&НаКлиенте

Назначение: эта директива означает, что процедура или функция работают только со стороны клиента, осуществляя доступ к данным формам, но без доступа к базе данных напрямую. Используется для обработки событий интерфейса, проверки ввода и локальных компьютеров без обращения к серверу.

Особенности:

  • Нет прямого доступа к таблицам базы данных и большинству объектов метаданных (справочники, документы, регистры) — только через вызов серверных методов.
  • Доступны реквизиты формы, элементы формы, параметры формы, а также глобальные клиентские функции.
  • Работа с интерфейсом (диалоги, сообщения пользователю, изменение видимости элементов) выполняется именно в клиентском коде.

Пример:

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

&НаКлиенте
Процедура Команда1Выполнить(Команда)
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Клик по кнопке выполнен на клиенте";
    Сообщение.Сообщить();
    
    Элементы.Кнопка.Доступность = Ложь;
    КодКонтрагента = Элементы.Таблица.ТекущиеДанные.Код;
    
    // Нельзя напрямую обратиться к справочнику:
    // Спр = Справочники.Контрагенты.НайтиПоКоду("000001"); // Ошибка!
    
    // Нужно вызвать серверный метод
    ПолучитьДанныеКонтрагентаНаСервере(КодКонтрагента);
&КонецПроцедуры

&НаСервере
Процедура ПолучитьДанныеКонтрагентаНаСервере(КодКонтрагента)
    Спр = Справочники.Контрагенты.НайтиПоКоду(КодКонтрагента);
    // ... дальнейшая работа
&КонецПроцедуры

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

&НаСервере

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

Особенности:

  • Полный доступ к базе данных, объектам метаданных, запросам.
  • В контексте формы доступны все реквизиты формы, их значения автоматически синхронизируются с клиентом.
  • Можно изменять данные формы, но изменения будут отправлены на клиент только после завершения серверного вызова.

Пример:

На форме есть таблица Товары, которая заполняется по нажатию на кнопку значениями цен номенклатуры

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

&НаКлиенте
Процедура ЗаполнитьПоКнопке(Команда)
    ЗаполнитьТабличнуюЧастьНаСервере();
&КонецПроцедуры

В данном случае мы обращаемся на сервер для получения данных о товарах к справочнику Номенклатура. При этом у нас доступен и контекст формы, мы обращаемся к таблице Товары, которая находится к контексте формы.

&НаСервереБезКонтекста

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

Особенности:

  • Отсутствует неявная передача данных формы, все данные нужно передавать явно через параметры.
  • Может быть вызвана как из клиента, так и из сервера.
  • Хорошо подходит для выноса сложных алгоритмов, не зависящих от конкретной формы: математические расчеты, обработка массивов, работа с файловой системой на сервере и т.п.
  • Позволяет избежать случайной модификации реквизитов формы и делает код более чистым.

Пример:

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

&НаКлиенте
Процедура ТоварыПриАктивизацииСтроки(Элемент)
   ТекущаяНоменклатура = Элементы.Товары.ТекущиеДанные.Номенклатура;  
   Дата = ТекущаяДата();
   ЦенаНоменклатуры = ЦенаНоменклатуры(ТекущаяНоменклатура, Дата);
КонецПроцедуры

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

   Выборка = РезультатЗапроса.Выбрать();
	
   Пока Выборка.Следующий() Цикл
      Возврат Выборка.Цена;
   КонецЦикла; 
	
   // вернем 0, если цена не задана для переданной номенклатуры 
   Возврат 0;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста

Назначение: процедура или функция выполняется и на клиенте, и на сервере, но в обоих случаях без доступа к контексту формы. Фактически это чистая функция, которая работает только с переданными параметрами и возвращает результат.

Особенности:

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

Пример:

Заменить в строке с номером телефона «+7» на «8». Эта функция может быть полезна как на клиенте, так и на сервере.

&НаКлиентеНаСервереБезКонтекста
Процедура ЗаменитьКодВНомереТелефона(НомерТелефона)
   НомерТелефона = СтрЗаменить(НомерТелефона, "+7", "8");
КонецПроцедуры

&НаКлиенте
Процедура ПреобразоватьНомер(Команда)
   НомерТелефона = ЗаменитьКодВНомереТелефона(НомерТелефона);
КонецПроцедуры

&НаСервере
Процедура ОбработатьТЧДанныеКонтрагента()

   Для каждого Контрагент Из Объект.Контрагенты Цикл
      ... // какой это код обработки данных контрагента
      Контрагент.НомерТелефона = ЗаменитьКодВНомереТелефона(Контрагент.НомерТелефона);
   КонецЦикла;

КонецПроцедуры

Памятка вместо заключения

  • &НаКлиенте — для интерфейса и взаимодействия с пользователем.
  • &НаСервере — для работы с данными внутри формы.
  • &НаСервереБезКонтекста — для серверных утилит, не зависящих от формы.
  • &НаКлиентеНаСервереБезКонтекста — для универсальных функций, работающих везде.

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

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Отправьте форму и мы вам перезвоним

Отправляя форму вы соглашаетесь с политикой конфиденциальности и даете согласие на обработку персональных данных компании ИП Рыжиченко Антону Ивановичу
Сайт itviar.ru использует cookie для персонализации и хранения настроек.
Отправляя форму вы соглашаетесь с политикой конфиденциальности и даете согласие на обработку персональных данных компании ИП Рыжиченко Антону Ивановичу