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