Особенности компиляции общих клиент-серверных модулей в управляемом приложении 1С 8.2
В данной статье я буду употреблять выражение «клиентский(серверный) экземпляр модуля». «Клиентский экземпляр модуля» — это совокупность процедур и функций данного общего модуля, которые будут скомпилированы на стороне клиента. Аналогично: «Серверный экземпляр модуля» это совокупность процедур и функций данного общего модуля, которые будут скомпилированы на стороне сервера. В принципе это понятие означает тоже, что и «клиентский(серверный) контекст», но на мой взгляд, применительно к общим модулям более точно отражает суть.
Рассмотрим общий модуль, у которого установлены флажки «Клиент (управляемое приложение)» и «Сервер», разрешим вызов сервера с клиента, установив флажок «Вызов сервера». Основной момент, на который следует обратить внимание, это то, что в данном случае будет скомпилировано ДВА ЭКЗЕМПЛЯРА этого общего модуля, один на сервере, один на клиенте. Все процедуры и функции, объявленные с директивой компиляции &НаСервере, попадут в серверный экземпляр модуля, соответственно все процедуры и функции, объявленные с директивой компиляции &НаКлиенте, попадут в клиентский экземпляр модуля. Все процедуры и функции, объявленные без директив компиляции попадут и в клиентский, и в серверный экземпляры модуля.
Рассмотри пример, допустим, в тексте общего клиент-серверного модуля, который называется «МодульКлиентСервер» определены следующие процедуры:
// Попадет в серверный экземпляр модуля &НаСервере Процедура ПроцедураОбщегоМодуля() Экспорт Сообщить("Сервер"); КонецПроцедуры // Попадет в клиентский экземпляр модуля &НаКлиенте Процедура ПроцедураОбщегоМодуля() Экспорт Сообщить("Клиент"); КонецПроцедуры
Заметьте, несмотря на то, что процедуры называются одинаково, никакой синтаксической ошибки не возникает, так как они будут скомпилированы в разных экземплярах модуля. Если у модуля установлен флажок «Вызов сервера», а у нашего модуля он установлен, то возникает вполне закономерный вопрос: Какая из двух одноименных процедур будет вызвана? Из серверного или клиентского экземпляра модуля? Тут действует так называемое правило «ближнего вызова»: если вызов осуществляется с клиента – будет вызвана процедура из клиентского экземпляра модуля, если с сервера – то серверного. Вызов процедур общего модуля из модуля любой формы:
&НаКлиенте Процедура Команда1(Команда) МодульКлиентСервер.ПроцедураОбщегоМодуля();// <-КЛИЕНТСКИЙ экземпляр ВызовСервера(); КонецПроцедуры &НаСервере Процедура ВызовСервера() МодульКлиентСервер.ПроцедураОбщегоМодуля();// <-СЕРВЕРНЫЙ экземпляр КонецПроцедуры
Напоследок заметим что в общем модуле можно было объявить всего одну процедуру ПроцедураОбщегоМодуля() без директив компиляции, а «разделить контекст» уже с помощью инструкций препроцессора.
// Попадет в оба экземпляра модуля Процедура ПроцедураОбщегоМодуля() Экспорт #Если НаСервере Тогда Сообщить("Сервер"); #КонецЕсли #Если НаКлиенте Тогда Сообщить("Клиент"); #КонецЕсли КонецПроцедуры
Как было написано выше, в этом случае ПроцедураОбщегоМодуля() будет скомпилирована в обоих экземплярах модуля, но код в клиентском и серверном экземплярах будет РАЗНЫЙ.
// В серверный экземпляр модуля попадет: Процедура ПроцедураОбщегоМодуля() Экспорт Сообщить("Сервер"); КонецПроцедуры // В клиентский экземпляр модуля попадет: Процедура ПроцедураОбщегоМодуля() Экспорт Сообщить("Клиент"); КонецПроцедуры
Как видите, мы получили результат точно такой же, как и в первом случае. В заключении сделаем небольшое, но важное замечание которое касается работы толстого клиента в режиме и обычного, и управляемого приложения с файл-серверной базой. Оно заключается в так называемом «слиянии» клиентского и серверного контекстов. В результате чего в первом случае возникнет ошибка компиляции, потому что обе процедуры попадут в один и тот же контекст. Во втором случае ошибки не возникнет, в процедуру будут включены и те строки кода которые относятся к клиентскому контексту и те, что относятся к серверному контексту.
Если публикация помогла Вам справится с проблемой, решить задачу или расширить свои знания - поддержите автора.
Комментарии:
Чтобы оставить комментарий, Вы должны войти в систему.

Подписаться по RSS
Непонятно, как быть, если нужна только процедура «НаКлиенте», например, для организации диалога, которая вызывается из тела процедуры, выполняемой на сервере. При компиляции на сервере «не видно» вызываемой процедуры, и система выдает ошибку, сообщая, что такой процедуры вообще нет.
Из серверной процедуры нельзя вызвать клиентскую.
=несмотря на то, что процедуры называются одинаково, никакой синтаксической ошибки не возникает, так как они будут скомпилированы в разных экземплярах модуля=
возникает.
{ОбщийМодуль.МодульКлиентСервер.Модуль(9,11)}: Процедура или функция с указанным именем уже определена (ПроцедураОбщегоМодуля)
Процедура <>ПроцедураОбщегоМодуля() Экспорт
Дочитайте статью до конца.
Отлично все рассказал.
Я для себя все расставил по местам. Получил так сказать понимание предмета
Спасибо.
а можно ли в обычном приложении заставить выполняться некий код на сервере?
я так понял для толстого клиента директивы сервер/клиент игнорируются и весь модуль компилируется на компе клиента, соответственно на компе клиента и исполняется, а как-то вызывать в тостом клиенте и обычном приложении (на обычных формах) процедуры, которые будут исполняться на сервере, можно?
Можно, для выполнения кода на сервере в обычном приложении используют общие модули с включенными флажками «Сервер» и «Вызов сервера»
Процедуры и функции, которые содержаться в таких модулях выполняются на сервере
Спасибо.