При разработке в среде 1С:Предприятие 8 одним из фундаментальных понятий является разделение контекста исполнения кода. Общие модули — это основные контейнеры для размещения процедур и функций, которые могут использоваться в различных частях конфигурации. Однако просто создать модуль недостаточно; необходимо правильно настроить его свойства, чтобы код был доступен именно там, где это требуется. В этой статье мы подробно разберем, за что отвечают «галочки» (флаги) в свойствах общего модуля, и решим типичные проблемы, возникающие у начинающих разработчиков.
Первое, что мы должны понять: платформа 1С работает в клиент-серверной архитектуре (даже в файловом варианте она эмулируется). Флаги контекста определяют, в какой среде будет скомпилирован код модуля. Рассмотрим их подробнее:
Экспорт.Важный технический нюанс: когда в общем модуле отмечено одновременно несколько флагов (например, «Клиент» и «Сервер»), система 1С создает две независимые копии этого модуля в памяти. Код компилируется отдельно для каждого контекста. Разберем ситуацию: если вы объявите переменную в разделе описания переменных такого модуля, ее значение на клиенте будет отличаться от значения на сервере. Изменение переменной в клиентском контексте никак не отразится на «такой же» переменной в серверном контексте.
Многие начинающие разработчики сталкиваются с проблемой: флаг Сервер стоит, функция помечена как Экспорт, но при попытке вызвать ее из модуля формы (на клиенте) возникает ошибка. Проанализируем причину.
Для обеспечения безопасности и производительности платформа 1С требует явного разрешения на «переход» границы между клиентом и сервером. За это отвечает флаг Вызов сервера. Рассмотрим правила его использования:
Рассмотрим пример кода в общем модуле ОбщийМодуль1:
// В свойствах модуля установлены флаги: Сервер, Вызов сервера
Функция ПолучитьОстатокТовара(ТоварСсылка) Экспорт
Запрос = Новый Запрос;
// ... текст запроса ...
Возврат Результат;
КонецФункции
Теперь эту функцию можно вызвать из клиентской части модуля формы:
&НаКлиенте
Процедура ПроверитьОстаток()
Остаток = ОбщийМодуль1.ПолучитьОстатокТовара(ВыбранныйТовар);
КонецПроцедуры
При использовании флага Вызов сервера мы должны помнить о процессе сериализации. Когда данные передаются с клиента на сервер, они упаковываются, передаются по сети и распаковываются. Выясним, какие данные нельзя передавать таким образом.
Нельзя передавать так называемые мутабельные значения. К ним относятся объекты базы данных (например, СправочникОбъект, ДокументОбъект) и наборы записей регистров. Если вы попытаетесь передать ссылку (СправочникСсылка), это сработает, так как ссылка — это простой ссылочный идентификатор. Но попытка передать сам объект приведет к ошибке выполнения.
Рекомендация: передавайте только простые типы (числа, строки, даты), ссылки или структуры/массивы, содержащие эти типы.
Флаг Глобальный делает функции модуля доступными в «глобальном контексте». Это означает, что вам не нужно писать имя модуля через точку. Вместо ОбщийМодуль1.МояФункция() можно написать просто МояФункция().
Однако, как мы увидели в обсуждении, этот флаг может вызывать ошибки. Проанализируем, почему это происходит:
Современный стандарт разработки 1С рекомендует минимизировать использование глобальных модулей. Всегда лучше обращаться к функции через имя модуля — это делает код более читаемым и исключает конфликты.
Разберем еще два важных флага, которые значительно расширяют возможности общих модулей.
Привилегированный — этот флаг работает только в связке с флагом Сервер. Код в таком модуле выполняется с полными правами. Это позволяет обойти ограничения RLS (ограничение прав на уровне записей). Посмотрим на пример: пользователю запрещено видеть закупочные цены, но для расчета себестоимости в документе системе нужно их прочитать. Мы выносим расчет в привилегированный модуль, и система выполнит запрос успешно, несмотря на ограничения прав текущего пользователя.
Повторное использование возвращаемых значений — это механизм кэширования. Если функция вызывается несколько раз с одними и теми же параметрами, платформа не будет выполнять код функции снова, а сразу вернет результат из кэша. Рассмотрим варианты настройки:
На время вызова — кэш очищается после завершения вызвавшей процедуры.На время сеанса — кэш живет до закрытия программы (но не более 20 минут, если данные не обновлялись).Осторожно: кэш не знает об изменениях в базе данных. Если ваша функция делает запрос к БД, она может вернуть устаревшие данные, если они уже были закешированы ранее в этом сеансе.
Подводя итог нашему анализу, сформулируем краткую инструкцию по настройке общего модуля:
Правильная настройка свойств общих модулей — это залог стабильной и быстрой работы вашей конфигурации.