Разработка и Конфигурация · 12 мин
Общие модули 1С 8.3: как использовать на практике
Как создавать и использовать общие модули в 1С 8.3: флаги Сервер, Клиент, Вызов сервера, директивы компиляции, типичные ошибки и примеры кода.
Общие модули в 1С 8.3 — это контейнеры для процедур и функций, которые нужны сразу в нескольких объектах конфигурации: документах, справочниках, отчётах, обработках. Вместо копирования одного и того же кода в каждый объект разработчик помещает его в общий модуль и вызывает отовсюду по имени.
Главная сложность работы с общими модулями — не написание кода, а правильная настройка флагов компиляции: Сервер, Клиент, Вызов сервера, Привилегированный режим. Ошибка в этих настройках приводит к лишним серверным вызовам, падению производительности или ошибкам «Процедура или функция с указанным именем не определена».
Ниже разобраны практические вопросы: как создать модуль, какие флаги выставить в типовых сценариях, как организовать вызовы между клиентом и сервером и как проверить, что всё работает корректно.
Что такое общий модуль и когда он нужен
Общий модуль — это объект конфигурации, не привязанный к конкретному документу или справочнику. Его процедуры доступны из любого другого модуля, если у них стоит служебное слово Экспорт. Типовые конфигурации содержат сотни таких модулей: например, ОбщегоНазначения, РаботаСФайлами, РасчетЗарплаты.
Общий модуль оправдан, когда одна и та же логика нужна минимум в двух местах: расчёт скидки в заказе и в счёте, проверка заполнения реквизита в разных документах, формирование строки представления контрагента. Если код нужен только в одном объекте — оставьте его в модуле этого объекта, иначе конфигурация раздувается без пользы.
Не стоит превращать общие модули в «свалку» несвязанных функций. Принято группировать процедуры по предметной области: РаботаСКонтрагентами, Ценообразование, ОбменДанными. Так модуль проще искать, тестировать и переносить между конфигурациями.
Как создать общий модуль в конфигураторе
Откройте конфигуратор, разверните ветку Конфигурация → Общие → Общие модули и нажмите «Добавить». Задайте имя латиницей без пробелов — именно по нему модуль будет вызываться из кода: МойМодуль.МояФункция(). Имя должно быть уникальным в пределах конфигурации и не совпадать с именами объектов метаданных.
После создания откройте палитру свойств модуля (правый клик → Свойства) — именно здесь задаются флаги контекста исполнения. Затем напишите код в открывшемся окне модуля. Процедуры, которые должны быть видны извне, завершайте словом Экспорт:
Функция ПолучитьСтавкуНДС(Дата) Экспорт
// серверная логика
Возврат 20;
КонецФункции
Сохраните конфигурацию (F7 — обновить конфигурацию базы данных не требуется, общие модули не меняют структуру БД, достаточно Ctrl+S и обновления через «Конфигурация → Обновить конфигурацию базы данных» при необходимости). После этого функция доступна из любого модуля конфигурации.
- 1Создайте модуль: Общие → Общие модули → Добавить
- 2Задайте уникальное имя латиницей
- 3Выставьте флаги контекста в палитре свойств
- 4Напишите процедуры и функции, экспортируемые — со словом Экспорт
- 5Сохраните конфигурацию и проверьте вызов из другого модуля
Флаги контекста: Сервер, Клиент, Вызов сервера
Именно флаги определяют, где физически выполняется код модуля. Неправильная комбинация — самая частая причина ошибок у начинающих разработчиков.
| Флаг | Что означает | Когда ставить |
|---|---|---|
| Сервер | Код компилируется и выполняется на сервере 1С | Запросы к БД, работа с объектами, проведение |
| Клиент (управляемое приложение) | Код выполняется на клиенте в управляемых формах | Интерфейсные действия, предупреждения, работа с файлами пользователя |
| Клиент (обычное приложение) | Код доступен в обычных формах | Только если конфигурация ещё поддерживает обычное приложение |
| Вызов сервера | Серверный модуль разрешено вызывать с клиента | Когда клиенту нужен результат серверной функции |
| Привилегированный режим | Код выполняется без проверки прав доступа | Служебные операции, которые должны работать под любым пользователем |
Флаг «Вызов сервера» — источник риска. Каждый вызов такого модуля с клиента — это сетевой обмен между клиентом и сервером, который занимает заметное время. Если в цикле на клиенте вызывается серверная функция сто раз, форма «зависнет» на десятки секунд. Правильный подход — собрать данные на клиенте в структуру и передать на сервер одним вызовом.
Флаг «Привилегированный режим» снижает безопасность: любой пользователь, даже без прав на объект, косвенно выполнит операцию. Ставьте его только там, где это осознанно необходимо (например, запись служебных констант), и никогда — в модулях, обрабатывающих ввод пользователя без проверки.
Директивы компиляции и клиент-серверное взаимодействие
Внутри общего модуля, у которого включены и клиентские, и серверные флаги, можно уточнять контекст отдельных процедур директивами &НаСервере, &НаКлиенте, &НаСервереБезКонтекста. Это позволяет держать в одном модуле парные функции: клиентскую обёртку и серверную реализацию.
Типовой паттерн вызова сервера с клиента выглядит так: клиентская процедура собирает параметры, вызывает серверную функцию, та выполняет запрос к базе и возвращает простые данные (число, строку, структуру, массив). Возвращать с сервера объекты типа СправочникОбъект или ДокументОбъект нельзя — они не сериализуются, используйте ссылки и примитивные типы.
&НаКлиенте
Процедура ПоказатьОстаток(Товар) Экспорт
Остаток = ПолучитьОстатокНаСервере(Товар);
ПоказатьПредупреждение(, "Остаток: " + Остаток);
КонецПроцедуры
&НаСервере
Функция ПолучитьОстатокНаСервере(Товар)
Запрос = Новый Запрос("ВЫБРАТЬ ...");
// ...
Возврат Остаток;
КонецФункции
Обратите внимание: в серверном коде недоступны интерактивные команды (Предупреждение, Вопрос, открытие форм), а в клиентском — прямые запросы к базе и объектная модель записи. Компилятор выдаст ошибку ещё при сохранении, если флаги и директивы противоречат коду.
&НаКлиенте
Процедура РассчитатьИтог(Команда)
Итог = ОбщийМодульСервер.РассчитатьИтогНаСервере(ТаблицаТоваров);
Элементы.ИтоговаяСумма.Заголовок = Формат(Итог, "ЧДЦ=2");
КонецПроцедурыПовторное использование возвращаемых значений
В свойствах общего модуля есть параметр «Повторное использование возвращаемых значений» с вариантами «Не использовать», «На время вызова» и «На время сеанса». Он включает кэширование результата функций: платформа запоминает значение и не выполняет функцию повторно при тех же параметрах.
Это эффективный способ ускорить работу для функций, которые часто вызываются с одинаковыми параметрами и редко меняют результат: получение настроек, курсов валют, значений констант, ФИО текущего пользователя. В типовых конфигурациях для этого существуют отдельные модули с постфиксом ПовтИсп.
Опасность кэширования — устаревшие данные. Если функция возвращает, например, склад по умолчанию, а пользователь в той же сессии его изменил, кэш «На время сеанса» продолжит отдавать старое значение до перезапуска. Для изменяемых данных используйте «На время вызова» или отключайте повторное использование.
Типичные ошибки при работе с общими модулями
Первая ошибка — попытка вызвать серверный модуль с клиента без флага «Вызов сервера». Платформа сообщит, что переменная не определена, хотя модуль существует. Проверяйте флаги в первую очередь при такой ошибке.
Вторая — хранение изменяемых данных в переменных модуля. Переменные общего модуля инициализируются при первом обращении и живут в рамках сеанса или вызова, но поведение отличается в разных режимах и является частым источником трудноуловимых багов. Для хранения состояния используйте параметры сеанса, константы или регистры сведений.
Третья — слишком «толстые» модули на тысячи строк с разнородной логикой. Такой модуль трудно сопровождать, а при командной разработке он становится источником конфликтов слияния. Дробите модули по функциональным областям.
Как проверить, что модуль работает правильно
После создания модуля выполните синтаксическую проверку: в конфигураторе «Конфигурация → Проверка конфигурации» с включённым флажком проверки модулей для нужных режимов (тонкий клиент, веб-клиент, сервер). Это выявит несоответствие директив и флагов до запуска.
Затем проверьте вызов в реальном режиме: запустите отладку (F5), поставьте точку останова внутри функции модуля и выполните действие, которое её вызывает. Убедитесь, что код выполняется в ожидаемом контексте — в окне отладки видно, на сервере или на клиенте исполняется строка.
Для оценки производительности при активном клиент-серверном обмене включите замер производительности («Отладка → Замер производительности») и посмотрите, сколько раз и как долго вызывается каждая процедура модуля. Если одна серверная функция вызывается сотни раз за одно действие пользователя — это повод пересмотреть архитектуру вызова.
Как проверить результат
Серверный код выполняется на сервере, клиентский — на клиенте
Серверная функция вызывается с клиента без «Вызова сервера» или наоборот
Один-два вызова на действие пользователя
Десятки вызовов из цикла
После изменения настройки функция возвращает новое значение
До перезапуска сеанса возвращается старое значение
Часто задаваемые вопросы
Чем общий модуль отличается от модуля объекта?
Модуль объекта принадлежит конкретному справочнику или документу и работает с его данными, имеет обработчики событий (ПриЗаписи, ОбработкаПроведения). Общий модуль не привязан к объекту, не имеет событий и служит библиотекой функций для всей конфигурации.
Можно ли вызвать функцию общего модуля из внешней обработки?
Да, если обработка открыта в той же информационной базе: вызов выполняется по имени модуля, как из любого другого кода. Ограничения те же — контекст исполнения определяется флагами модуля, а серверный модуль без «Вызова сервера» недоступен из клиентского кода обработки.
Почему изменения в общем модуле не видны пользователям?
Чаще всего причина в кэше повторно используемых значений или в том, что пользователи продолжают работать в старых сеансах. Для серверного кода изменения подхватываются после обновления конфигурации, но сеансы, запущенные до обновления, могут держать старую версию — попросите пользователей перезайти.
Нужен ли отдельный модуль для каждой пары «клиент + сервер»?
Не обязательно, но это удобная практика из типовых конфигураций: модуль с постфиксом «Клиент» содержит интерфейсную логику, одноимённый серверный — работу с данными, а «КлиентСервер» — функции, доступные в обоих контекстах. Такое разделение упрощает навигацию и снижает риск ошибок с флагами.
Что делать, если функция нужна и на клиенте, и на сервере?
Включите в модуле оба флага (Клиент и Сервер) и поместите функцию без директив либо с директивой для конкретного контекста. Функция будет скомпилирована в обеих средах. Убедитесь, что внутри неё нет методов, недоступных в одном из контекстов, иначе проверка конфигурации выдаст ошибку.
Влияет ли количество общих модулей на производительность?
Само по себе число модулей почти не влияет — влияет объём кода, который компилируется при обращении, и частота серверных вызовов. Большие модули с тысячами строк компилируются дольше, поэтому дробление на тематические модули полезно и для производительности, и для сопровождения.
Что важно запомнить
Общий модуль — библиотека кода для всей конфигурации. Создаётся в ветке «Общие → Общие модули», экспортируемые функции помечаются словом «Экспорт». Ключ к корректной работе — флаги контекста: «Сервер» для работы с данными, «Клиент» для интерфейса, «Вызов сервера» только при необходимости вызова с клиента, «Привилегированный режим» — с осторожностью. Минимизируйте серверные вызовы и не храните состояние в переменных модуля.