Open
Close

Клиент- серверные вызовы. Общие модули 1с общие модули использование

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

Для примера возьмем нашу старую конфигурацию, которую я использовал в предыдущих статьях. У нас в ней есть два документа это Приход Товара на склад и Отпуск товара на склад. В обоих документах есть процедуры, которые рассчитывают сумму в строке табличной части.

В каждом документе написан один и тот же код для расчёта суммы.

Процедура МатериалыЦенаПриИзменении(Элемент)
СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;
СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
КонецПроцедуры

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

Создаём общий модуль для расчета суммы

И так начнем для начала нужно создать общий модуль. Для этого заходим в конфигуратор ищем пункт Общие модули кликаем правой кнопкой и добавляем новы пишем имя РаботаСДокументами. Вписываем в него следующих код.

Так же обязательно поставьте в окне свойств галочки напротив Клиент(Управляемое приложение) и Сервер.

Теперь нужно немного изменить код в модуле формы документов. Слева в конфигурации ищем документ Приход товара разворачиваем окна до окна Формы кликаем два раза на Форма Документа и в открывшемся окне формы снизу переходим на вкладку Модуль. У нас есть вот такой код

Эта процедура работает при изменение Количества в табличной части документа Приход товара и подсчитывает сумму.

&НаКлиенте



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

А это процедура начинает работать при изменении Цены в табличной части документа Приход товара и рассчитывает сумму.

&НаКлиенте

СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;
СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
КонецПроцедуры

Заменяем его на этот

&НаКлиенте
Процедура МатериалыКоличествоПриИзменении(Элемент)
СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;

КонецПроцедуры
&НаКлиенте
Процедура МатериалыЦенаПриИзменении(Элемент)
СтрокаТабличнойЧасти = Элементы.Материалы.ТекущиеДанные;
РаботаСДокументами.РассчитатьСумму(СтрокаТабличнойЧасти);
КонецПроцедуры

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

Тоже самое делаем для документа Отпуск товара со склада, запускаем и проверяем работоспособность кода. Вот мы с вами и сделали первый общий модуль надеюсь кому-то пригодится моя статья.

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

Обычно программный модуль состоит из трех разделов:

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

Пример структуры программного модуля:

//***************** ОБЛАСТЬ ОБЪЯВЛЕНИЯ ПЕРЕМЕННЫХ **********************

Перем Фамилия Экспорт; //это глобальная переменная
Перем Имя , Отчество ; //это переменная модуля
Перем ФИО ; //это тоже переменная модуля и к ней можно обращаться

//из любой процедуры и функции нашего модуля

//*************** ОБЛАСТЬ ОПИСАНИЯ ПРОЦЕДУР И ФУНКЦИЙ ****************

Процедура Процедура1 ()
Перем Итог ; //Итог это локальная переменная (переменная процедуры)

Итог = Фамилия + " "+ Имя + " "+ Отчество ;

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

Функция Функция1 ()

// операторы функции

Возврат(Фамилия + " "+ Имя );

КонецФункции

//******************* ОСНОВНОЙ ТЕКСТ ПРОГРАММЫ ***********************

Фамилия = "Иванов";
Имя = "Иван";
Отчество = "Иванович";

//******************************************************************************

В конкретном программном модуле любая из областей может отсутствовать.
Область объявления переменных размещается от начала текста модуля до первого оператора Процедура или оператора Функция или любого исполняемого оператора. В этом разделе могут находиться только операторы объявления переменных Перем .

Область описания процедур и функций размещается от первого оператора Процедура или оператора Функция до любого исполняемого оператора вне тела описания процедур или функций.

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

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

Каждый отдельный программный модуль воспринимается системой как единое целое, поэтому все процедуры и функции программного модуля выполняются в едином контексте.

Контекст выполнения модулей делится на клиентский и серверный. Кроме того, некоторые программные модули могут быть скомпилированы как на стороне клиента, так и на стороне сервера.

Модуль приложения (управляемого или обычного)

В модуле приложения описываются процедуры (обработчики) событий, которые инициализируются при старте и окончании работы системы. Например, при начале работы приложения можно обновить какие-либо данные конфигурации, а при завершении работы - поинтересоваться, стоит ли вообще выходить из программы. Кроме того, в данном модуле перехватываются события от внешнего оборудования, например, торгового или фискального. Стоит отметить, что модуль приложения выполняется только в случае интерактивного запуска приложения, то есть когда запускается окно программы. Этого не происходит, если приложение запускается в режиме com- соединения.
В платформе 1С 8 существует два различных модуля приложения. Это модуль Обычного приложения и модуль Управляемого приложения. Они срабатывают при запуске различных клиентов. Так, модуль Управляемого приложения срабатывает при запуске веб-клиента, тонкого клиента и толстого клиента в режиме управляемого приложения. А модуль обычного приложения срабатывает при запуске толстого клиента в режиме обычного приложения. Настройка режима запуска приложения задается в свойстве конфигурации "Основной режим запуска".

В модуле приложения могут располагаться все 3 раздела – объявления переменных, описания процедур и функций, а так же основной текст программы. Модуль приложения компилируется на стороне клиента, что сильно ограничивает нас в использовании многих типов данных. Расширить контекст модуля приложения можно за счет методов общих модулей, для которых установлено свойство «Вызов сервера». Все переменные и методы программного модуля приложения, помеченные как экспортные, будут доступны в любом модуле конфигурации, работающем на стороне клиента. Однако, как бы ни было это заманчиво, не следует размещать здесь большое количество процедур и функций. Чем больше в данном модуле находится кода, тем длительнее время компиляции, а, следовательно, и время запуска приложения.

Как уже отмечалось выше, модуль приложения обрабатывает события запуска и завершения приложения. Для обработки каждого из этих событий в модуле приложения существует пара обработчиков Перед… и При… Отличия между заключается в следующем: при выполнении кода в обработчике Перед… действие еще не свершилось и мы можем отказаться от его выполнения. Для этого предназначен параметр Отказ. В обработчиках При.. действие уже свершилось, и отказаться от запуска приложения или выхода из него мы не можем.

Модуль внешнего соединения

  • может содержать все 3 области
  • располагается в корневом разделе конфигурации

Назначение модуля аналогично назначению модуля приложения. В нем идет обработка событий старта и завершения работы приложения. Модуль внешнего соединения срабатывает, когда запуск приложения происходит в режиме com- соединения. Сам процесс внешнего соединения – это процесс не интерактивный. В этом режиме происходит программная работа с информационной базой и не происходит открытия окна приложения, что накладывает определенные ограничения на использование методов, предназначенных для интерактивной работы. В этом режиме нельзя использовать вызовы диалоговых форм, предупреждений и сообщений пользователю и т.п. Они просто не будут выполняться.

Как и в модуле приложения, здесь доступны все три области: объявления переменных, описания процедур и функций, а так же основной текст программы. Главное отличие от модуля приложения заключается в том, что в режиме com- соединения вся работа с информационной базой происходит на стороне сервера, поэтому модуль внешнего соединения компилируется на стороне сервере. Соответственно в нем не доступны экспортные переменные и методы общих клиентских модулей.

Модуль сеанса

  • выполняется на стороне сервера
  • располагается в корневом разделе конфигурации

Это узкоспециализированный модуль, предназначенный исключительно для инициализации параметров сеанса. Почему для этого необходимо было делать собственный модуль? Его использование обусловлено тем, что само приложение может запускаться в различных режимах (что приводит к выполнению либо модуля управляемого, либо обычного приложения, либо модуля внешнего соединения), а инициализацию параметров сеанса необходимо производить вне зависимости от режима запуска. Чтобы не писать один и тот же программных код во всех трех указанных модулях, нам и потребовался дополнительный модуль, который выполняется вне зависимости от режима запуска приложения.

В модуле сеанса существует одно единственное событие «УстановкаПараметровСеанса», которое выполняется самым первым, даже раньше события модуля приложения ПередНачаломРаботыСистемы. В нем не доступны раздел объявления переменных и раздел основной программы. А так же нельзя объявлять экспортные методы. Модуль компилируется на стороне сервера.

Общие модули

  • может содержать область описания процедур и функций
  • выполняется на стороне сервера или клиента (зависит от настроек модуля)
  • располагается в ветке дерева объектов конфигурации «Общие» - «Общие модули»

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

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

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

Модуль формы

  • может содержать все 3 области
  • выполняется на стороне сервера и клиента

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

Структура управляемой формы содержит раздел объявления переменных, описания процедур и функций и основной текст программы (выполняется в момент инициализации формы). К стандартным событиям формы можем обратиться через список ожидаемых процедур и функций формы (Ctrl+Alt+P) , либо через палитру свойств самой формы.

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

Модуль объекта

  • может содержать все 3 области
  • выполняется на стороне сервера

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

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

Модуль менеджера объекта

  • может содержать все 3 области
  • выполняется на стороне сервера

Модуль менеджера объектов появился только начиная с версии 1С 8.2. Модуль менеджера существует у всех прикладных объектов и предназначен для управления этим объектом как объектом конфигурации. Модуль менеджера позволяет расширить функциональность объекта за счет введения (написания) процедур и функций, которые относятся не к конкретному экземпляру объекта базы данных, а к самому объекту конфигурации. Модуль менеджера объектов позволяет размещать общие процедуры и функции для данного объекта и обращаться к ним из вне, например, из обработки (конечно, если эта процедура или функция будет с ключевым словом Экспорт). Что это нам дает нового? В общем-то, ничего, кроме упорядочивания процедур по объектам и хранения их в отдельных местах - Модулях менеджеров объектов. Мы можем с таким же успехом эти процедуры и функции помещать в общих модулях, но 1С советует общие процедуры и функции объектов размещать в Модуле менеджера объектов. Примеры использования процедур и функций Модуля менеджеров объектов: первоначальное заполнение отдельных реквизитов справочника или документа по определенным условиям, проверка заполнения реквизитов справочника или документа по определенным условиям и т.д.

Модуль команды

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

Команды – это объекты, подчиненные прикладным объектам или конфигурации в целом. У каждой команды есть модуль команды, в котором можно описать предопределенную процедуру ОбработкаКоманды() для выполнения этой команды.

Что такое модули и для чего собственно они предназначены? В модуле располагается программный код. Причем, стоит отметить, что в отличие от платформы 7.7, где код мог располагаться и в свойствах элементов формы и в ячейках таблиц макета, в платформе 8.х любая строчка кода должна располагаться в каком-либо модуле. Обычно модуль состоит из трех разделов - это раздел описания переменных, раздел описания процедур и функций, а так же раздел основной программы. Такая структура характерна практически для всех модулей платформы, за некоторым исключением. В некоторых модулях нет раздела описания переменных и раздела основной программы. Например, Модуль сеанса и любой Общий модуль.

Контекст выполнения модулей, в общем случае, делится на клиентский и серверный. Кроме того некоторые модули могут быть скомпилированы как на стороне клиента, так и на стороне сервера. А некоторые исключительно на стороне сервера или на стороне клиента. Итак:

Модуль приложения

Модуль предназначен для того, чтобы отловить моменты запуска приложения (загрузки конфигурации) и завершения его работы. И в соответствующих событиях можно расположить процедуры проверки. Например, при начале работы приложения обновить какие-либо справочные данные конфигурации, при завершении работы поинтересоваться, а стоит ли вообще выходить из него, может день рабочий еще не закончился. Кроме того в нем перехватываются события от внешнего оборудования, например, торгового или фискального. Стоит отметить, что модуль приложения перехватывает описанные события только в случае интерактивного запуска. Т.е. когда создается само окно программы. Этого не происходит, если приложение запускается в режиме com- соединения.

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

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

Как уже отмечалось выше, модуль приложения обрабатывает события запуска и завершения приложения. Для обработки каждого из этих событий в модуле приложения существует пара обработчиков Перед… и При… Отличия между ними таково, что при выполнении кода в обработчике Перед… действие еще не свершилось и мы можем отказаться от его выполнения. Для этого предназначен параметр Отказ. В обработчиках При.. действие уже свершилось, и отказаться от запуска приложения или выхода из него мы не можем.

Модуль внешнего соединения

Назначение модуля аналогично назначению модуля приложения. В нем идет обработка точек старта и завершения приложения. Модуль внешнего соединения срабатывает, когда запуск приложения происходит в режиме com- соединения. Сам процесс внешнего соединения - это процесс не интерактивный. В этом режиме происходит программная работа с информационной базой и не происходит открытия окна приложения, что накладывает определенные ограничения на использование методов, предназначенных для интерактивной работы. В этом режиме нельзя использовать вызовы диалоговых форм, предупреждающих сообщений и т.п. Они просто не сработают.

Как и в модуле приложения, здесь доступны разделы описания переменных, методов и раздел основной программы. Так же можно объявлять экспортные переменные и методы. Отличие заключается в том, что в режиме com- соединения вся работа с информационной базой происходит на стороне сервера, поэтому модуль внешнего соединения компилируется исключительно на сервере. Соответственно в нем не доступны экспортные переменные и методы общих клиентских модулей.

Модуль сеанса

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

В модуле сеанса существует единственное событие «УстановкаПараметровСеанса», которое выполняется самым первым, даже раньше события модуля приложения ПередНачаломРаботыСистемы. В нем не доступны раздел объявления переменных и раздел основной программы. А так же нельзя объявлять экспортные методы. Модуль компилируется на стороне сервера.

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

Общие модули

Модули предназначены для описания некоторых общих алгоритмов, которые будут вызываться из других модулей конфигурации. Общий модуль не содержит раздела описания переменных и раздела основной программы. В нем можно объявлять экспортные методы, контекст доступности которых будет определяться флагами компиляции. В связи с тем, что раздел описания переменных не доступен, определять глобальные переменные в общих модулях нельзя. Для этого нужно использовать функции общих модулей с кешированием возвращаемых значений или модуль приложения. Стоит иметь в виду, что даже если свойство повторного использования общего модуля установлено в значение "На время сеанса", то и в этом случае время жизни закешированных значений не превышает 20 минут, с момента последнего к ним обращения.
Поведение общего модуля зависит от выставленных параметров (глобальный или нет, различные флаги компиляции, доступен ли вызов сервера и т.д.). Не будем в данной статье рассматривать всевозможные настройки, а также особенности поведения и подводные камни, возникающие при неразумной установке флагов свойств. Это тема для отдельной статьи. Остановимся лишь на нескольких моментах, которыми стоит руководствоваться при выставлении флагов:

  • Хорошим правилом будет не использовать флаг «Глобальный» повсеместно. Это сократит время запуска приложения, а также улучшит читаемость кода (конечно если общий модуль имеет вполне осмысленное название).
  • Не желательно использовать больше одного флага компиляции. Методов, которые необходимо выполнять в разных контекстах не так много, и если все же такие методы потребуются, то для них можно выделить отдельный общий модуль.
  • Флаг «Вызов сервера» имеет смысл, только если модуль компилируется «На сервере». Поэтому все остальные флаги компиляции стоит снять во избежание различных проблем.
  • Если в методах модуля происходит массовая обработка данных, чтение и запись в базу данных, то для увеличения скорости работы лучше отключить контроль прав доступа, выставив флаг «Привилегированный». Этот режим доступен только для общих модулей, компилируемых на сервере.

Модуль формы

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

Модуль объекта

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

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

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

Модуль менеджера объекта

Этот модуль существует для многих объектов конфигурации. Основное предназначение данного модуля - это переопределение стандартного события выбора, которое возникает в момент ввода по строке и расширение функционала менеджера. Модуль компилируется на стороне сервера. В нем возможно определение экспортных свойств и методов. Вызов экспортных методов менеджера не требует создания самого объекта.

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

Условные обозначения на схеме: О.М. Клиент - Клиентский общий модуль; О.М. Сервер - Серверный общий модуль; М.Ф. Клиент - Клиентские процедуры модуля формы; М.Ф. Сервер - Серверные процедуры модуля формы.

Печать (Ctrl+P)

Объекты, расположенные в ветви дерева конфигурации Общие модули, предназначены для размещения в них текстов функций и процедур, которые могут вызываться из любого другого модуля конфигурации.
ВНИМАНИЕ! Общий модуль может содержать только определения процедур и функций .
Процедуры и функции общего модуля, для которых в заголовках указано ключевое слово Экспорт, являются одними из составных частей глобального контекста. Подробнее о написании процедур в общем модуле можно узнать в разделах «Формат исходных текстов программных модулей» и «Операторы» справки по встроенному языку.
Для редактирования общего модуля необходимо в палитре свойств объекта типа Общие модули окна Конфигурация в свойстве Модуль щелкнуть мышью ссылку Открыть. Текст общего модуля будет выдан для редактирования в редакторе текстов системы «1С:Предприятие» в режиме редактирования текста программного модуля.
Общий модуль, являясь частью конфигурации, сохраняется только в составе конфигурации.
Свойство Глобальный определяет, являются ли экспортируемые методы общего модуля частью глобального контекста.
Если свойство Глобальный установлено в значение Истина, то экспортируемые методы общего модуля доступны как методы глобального контекста.
Если свойство Глобальный установлено в значение Ложь, то в глобальном контексте создается свойство с именем, соответствующим имени общего модуля в метаданных. Данное свойство доступно только для чтения. Значением данного свойства является объект ОбщийМодуль . Через данный объект доступны экспортируемые методы данного общего модуля. Таким образом, обращение к методам неглобальных общих модулей выглядит как XXXXX.YYYYY, где XXXXX – это имя свойства, соответствующее контексту общего модуля, а YYYYY – имя экспортируемого метода общего модуля.
Пример:

РаботаСТорговымОборудованием.ПодключитьСканерШтрихкодов() ;

Различные контекст и общие модули

С помощью свойств общих модулей и инструкций препроцессора можно организовать выполнение различных методов общих модулей в нужном контексте.
Каждое свойство общего модуля отвечает за возможность компиляции (и исполнения) общего модуля в том или ином контексте.
Доступны следующие свойства, отвечающие за контекст, в котором доступны методы общего модуля:
Клиент (обычное приложение) – методы общего модуля будут доступны для толстого клиента в режиме обычного приложения;
● – методы общего модуля будут доступны для тонкого клиента, веб-клиента, а также для толстого клиента в
режиме управляемого приложения;
● Сервер – методы общего модуля будут доступны на сервере;
Внешнее соединение – методы общего модуля будут доступны во внешнем соединении.
Если устанавливаются одновременно несколько свойств, то это означает, что методы общего модуля будут доступны в нескольких контекстах.
Если у общего модуля установлено свойство Сервер и еще какое-либо свойство, то это означает, что общий модуль будет доступен одновременно на сервере и в выбранном клиенте. При этом необходимо понимать, что фактически это будет несколько вариантов скомпилированного кода (по числу выбранных клиентов и собственно для сервера).
При этом если метод, расположенный в таком общем модуле, вызывается со стороны клиента, то будет использована клиентская копия общего модуля, а если с сервера – серверная. В этом случае с помощью директив препроцессора (подробнее см. здесь) можно «оградить» сервер от того кода, который на нем не может исполняться.
Рассмотрим пример. В общем модуле (который может исполняться на тонком клиенте и на сервере) есть метод, который имеет несколько различное поведение на стороне тонкого клиента и на стороне сервера. Посмотрим, как это можно сделать:



#Если ТонкийКлиент Тогда
// Покажем предупреждение
ПоказатьОповещениеПользователя (“На клиенте”);
#КонецЕсли
КонецПроцедуры
Тогда на стороне сервера код приобретет следующий вид:
Процедура МетодОбщегоМодуля() Экспорт
// Тут размещается различный важный код
КонецПроцедуры
А на стороне тонкого клиента код будет иметь следующий вид:
Процедура МетодОбщегоМодуля() Экспорт
// Тут размещается различный важный код
// Покажем предупреждение
ПоказатьОповещениеПользователя(“На клиенте”);
КонецПроцедуры

Для передачи управления с клиента на сервер существует несколько способов:
● вызвать метод серверного общего модуля;
● в модуле формы или команды вызвать метод, который предваряется директивами компиляции &НаСервере, &НаСервереБезКонтекста

При этом из серверных процедур невозможно вызвать методы клиентских общих модулей (у которых не установлено свойство Сервер) и клиентские методы модуля формы или модуля команды. Управление вернется на клиента после того, как будет завершен самый внешний вызов серверного метода.
Исключение составляют методы модуля формы и модуля команды, которые предваряются директивами компиляции &НаКлиентеНаСервере , &НаКлиентеНаСервереБезКонтекста
Также следует упомянуть следующие моменты:
● Если общий модуль доступен более чем для одного клиента, то при написании программного кода следует учитывать максимальные ограничения, которые могут накладываться клиентами, либо использовать инструкции препроцессора для «изоляции» кода, специфичного для того или иного клиента.
● Инструкции препроцессора также имеют смысл тогда, когда один общий модуль имеет несколько контекстов исполнения, например, внешнее соединение и тонкий клиент или (что встречается значительно чаще) какой-либо клиент и сервер. В этом случае инструкции препроцессора будут обрамлять интерактивный код, который невозможно использовать на сервере, но возможно на клиенте (см. пример выше).
Подробнее об инструкциях препроцессора и директивах компиляции в разделе «Исполнение процедур и функций» справки по встроенному языку.
Свойство Вызов сервера предназначено для управления возможностью вызова экспортируемых методов серверного общего модуля из клиентского кода.
Если свойство установлено, то экспортируемые методы серверного общего модуля доступны для вызова со стороны клиента. Если свойство не установлено, то такие экспортируемые методы можно вызывать только из серверных методов (как методов серверных общих модулей, так и серверных методов модуля формы и модулей команд).
Совет . Рекомендуется устанавливать в значение Ложь свойство Вызов сервера в тех случаях, когда серверный общий модуль содержит методы, которые нежелательно вызывать с клиента (например, по причинам безопасности).
Примечание . Если одновременно установлены свойства Клиент (обычное приложение) , Клиент (управляемое приложение) , Внешнее соединение , то свойство Вызов сервера автоматически сбрасывается. Если устанавливается свойство Вызов сервера , то автоматически сбрасываются свойства Клиент (обычное приложение) , Клиент (управляемое приложение) и Внешнее соединение , если эти свойства были установлены одновременно.
Свойство Привилегированный предназначено для отключения контроля прав доступа при выполнении методов общего модуля.
ПРИМЕЧАНИЕ. Если свойство Привилегированный установлено, то общему модулю автоматически устанавливается свойство Сервер и сбрасываются остальные свойства (Клиент (обычное приложение) , Клиент (управляемое приложение) и Внешнее соединение ). Привилегированный общий модуль может исполняться только на сервере.

Повторное использование возвращаемых значений

Если общий модуль не является глобальным, то становится доступно свойство Повторное использование возвращаемых значений. Это свойство может принимать следующие значения:
● Не использовать – повторное использование возвращаемых значений для функций этого общего модуля не используется.
● На время вызова и На время сеанса – для общего модуля используется метод определения повторного использования данных. Суть этого метода заключается в том, что в ходе выполнения кода система запоминает параметры и результат работы функций после первого вызова функции. При повторном вызове функции с такими же параметрами, происходит возврат запомненного значения (из первого вызова) без выполнения самой функции. Если функция во время своего выполнения меняет значения параметров, то повторный вызов функции не будет это делать.
Можно выделить следующие особенности сохранения результатов вызова:
● если функция выполняется на сервере и вызывается из серверного кода, то значения параметров и результат вызова запоминаются для текущего сеанса на стороне сервера;
● если функция выполняется на толстом или тонком клиенте, то значения параметров и результатов вызова запоминаются на стороне клиента;
● если функция выполняется на стороне сервера, а вызывается из клиентского кода, то значения параметров вызова запоминаются и на стороне клиента, и на стороне сервера (для текущего сеанса).
Сохраненные значения удаляются:
● если свойство установлено в значение На время вызова:
● на стороне сервера – при возврате управления с сервера;
● на стороне клиента – при завершении работы процедуры или функции встроенного языка верхнего уровня (вызванной системой из интерфейса, а не из другой процедуры или функции встроенного языка);
● если свойство общего модуля установлено в значение На время сеанса:
● на стороне сервера – при окончании сеанса;
● на стороне клиента – при закрытии клиентского приложения.
Сохраненные значения будут удалены:
● на сервере, в толстом клиенте, во внешнем соединении, в тонком клиенте и в веб-клиенте с обычной скоростью соединения – через 20 минут после вычисления сохраняемого значения или через 6 минут после последнего использования;
● в тонком клиенте и веб-клиенте с низкой скоростью соединения – через 20 минут после вычисления сохраняемого значения;
● при нехватке оперативной памяти в рабочем процессе сервера;
● при перезапуске рабочего процесса;
● при переключении клиента на другой рабочий процесс.
После удаления значений вызов экспортируемой функции выполняется как при первом вызове.
На выполнение процедур данное свойство общих модулей не влияет – процедуры выполняются всегда.

Если у общего модуля установлено повторное использование возвращаемых значений, то на типы параметров экспортируемых функции накладывается ряд ограничений. Типы параметров могут быть только:
● Примитивными типами (Неопределено, NULL, Булево, Число, Строка, Дата ).
● Любыми ссылками на объекты базы данных.
● Структурами со значениями свойств вышеперечисленных типов. В этом случае идентичность параметров контролируется «по содержимому» структур.
Если экспортируемая функция возвращает какой-либо объект, то фактически возвращается ссылка на объект, хранимый в кеше. Если после получения этой ссылки произойдет изменение состояния объекта, то последующий вызов той же самой функции приведет к возврату ссылки на уже измененный объект без фактического выполнения функции. Такое поведение будет наблюдаться до удаления сохраненного значения (по любой причине). Другими словами – изменение состояния объекта, полученного в результате вызова функции из общего модуля с повторным использованием возвращаемых значений, не является основанием для фактического вызова функции. Также следует помнить, что кеш возвращаемых объектов индифферентен к
состоянию привелигированного режима в момент вызова функции с повторным использованием возвращаемых значений. Эта особенность может привести к следующей особенности поведения:
● Фактическое выполнение вызова функции с повторным использованием возвращаемых значений (первый вызов) выполнялось при включенном привелигированном режиме.
● При выполнении функции был получен объект, который не может быть получен с отключенным привелигированным режимом.
● Последующие вызовы функции выполнялись без установки привелигированного режима.
● Однако, до момента очистки кеша возвращаемых объектов или повторного фактического вызова, функция будет возвращать формально недоступный объект.
● Также верно и обратное поведение, когда первый вызов выполняется без установки привелигированного режима, а в привелигированном режиме не возвращается объект, который мог быть получен в привелигированном режиме.

Если у общего модуля свойство Повторное использование возвращаемых значений установлено в значение На время сеанса , то в значениях, возвращаемых функциями такого модуля, нельзя использовать значения типа МенеджерВременныхТаблиц .
Если функция общего модуля, с установленным повторным использованием, вызываются из этого же самого общего модуля (например, с именем ОбщийМодуль ), то следует помнить о следующей особенности: если функция вызывается по имени МояФункция() , то исполнение функции будет происходить при каждом вызове функции. Для того чтобы использовались сохраненные значения, функция следует вызывать по полному имени:
ОбщийМодуль.МояФункция().
Метод глобального контекста удаляет все повторно используемые значения, как на стороне сервера, так и на стороне клиента, независимо от места вызова метода. После выполнения метода ОбновитьПовторноИспользуемыеЗначения() первый вызов функции будет выполнен полностью.

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

1.2. При разработке общих модулей следует выбирать один из четырех контекстов выполнения кода:

Тип общего модуля Пример наименования Вызов сервера Сервер Внешнее соединение Клиент
(обычное приложение)
Клиент
(управляемое приложение)
1. Серверный ОбщегоНазначения (или ОбщегоНазначенияСервер)
2. Серверный для вызова с клиента ОбщегоНазначенияВызовСервера
3. Клиентский ОбщегоНазначенияКлиент (или ОбщегоНазначенияГлобальный)
4. Клиент-серверный ОбщегоНазначенияКлиентСервер

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

  • Сервер (флажок Вызов сервера сброшен),
  • Клиент (обычное приложение) ,
  • Внешнее соединение .

В таком случае гарантируется возможность вызова серверных процедур и функций с параметрами мутабельных типов (например, СправочникОбъект , ДокументОбъект и т.п.). Как правило, это:

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

Серверные общие модули называются по общим правилам именования объектов метаданных.
Например: РаботаСФайлами , ОбщегоНазначения

В отдельных случаях для предотвращения конфликта имен со свойствами глобального контекста может быть добавлен постфикс «Сервер» .
Например: РегламентныеЗаданияСервер , ОбменДаннымиСервер .

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

  • Сервер (флажок Вызов сервера установлен)

Серверные общие модули для вызова с клиента называются по общим правилам именования объектов метаданных и должны именоваться с постфиксом «ВызовСервера» .
Например: РаботаСФайламиВызовСервера

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

См. также: Ограничение на установку признака «Вызов сервера» у общих модулей

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

  • Клиент (управляемое приложение )
  • Клиент (обычное приложение)

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

Клиентские общие модули именуются с постфиксом «Клиент» .
Например: РаботаСФайламиКлиент , ОбщегоНазначенияКлиент

См. также: минимизация кода, выполняемого на клиенте

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

  • Клиент (управляемое приложение)
  • Сервер (флажок Вызов сервера сброшен)
  • Клиент (обычное приложение)
  • Внешнее соединение

Общие модули этого вида именуются с постфиксом «КлиентСервер» .
Например: РаботаСФайламиКлиент , ОбщегоНазначенияКлиентСервер

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

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

3.1. Имена общих модулей рекомендуется строить по общим правилам именования объектов метаданных. Название общего модуля должно совпадать с названием подсистемы или отдельного механизма, процедуры и функции которой он реализует. Рекомендуется избегать в названиях общих модулей таких общих слов как "Процедуры", "Функции", "Обработчики", "Модуль", "Функциональность" и т.п. и применять их только в исключительных случаях, когда они более полно раскрывают назначение модуля.

Для того чтобы различать общие модули одной подсистемы, которые созданы для реализации процедур и функций, выполняемых в разных контекстах, рекомендуется задавать им постфиксы, описанные ранее в пп. 2.1-2.4.