Создание модулей в 1С 8.3: виды, события и отладка кода
Содержание
Весь код конфигурации 1С 8.3 живёт в модулях. Создаются и редактируются они в Конфигураторе: открываете нужный объект дерева конфигурации, вызываете его модуль и пишете процедуры и функции на встроенном языке. Какой именно модуль выбрать — зависит от того, где должен исполняться код: на сервере, на клиенте или и там, и там.
Разберём по порядку: общий модуль, модуль объекта, модуль формы и модуль менеджера. У каждого своё назначение, свой набор событий и свои правила компиляции. Плюс покажу, как добавить код в типовую конфигурацию , не ломая обновления, и как потом всё отладить.
Перед работой откройте конфигурацию в режиме редактирования: меню Конфигурация → Открыть конфигурацию. Если это типовая конфигурация на поддержке — об этом ниже отдельный раздел.
Как устроены модули в дереве конфигурации
Модуль — это контейнер для процедур и функций. Разные модули компилируются в разном контексте, поэтому код из одного не всегда виден в другом. Основные виды:
- 🗂 Общий модуль — переиспользуемые процедуры и функции, не привязанные к конкретному объекту.
- 📄 Модуль объекта — логика конкретного справочника, документа, регистра: что делать при записи, проведении, удалении.
- 🖥 Модуль формы — обработка действий пользователя: нажал кнопку, изменил поле, открыл форму.
- ⚙️ Модуль менеджера — методы уровня объекта в целом (не отдельного элемента), печать, выбор данных.
- 🌐 Модуль приложения (управляемого и обычного), модуль сеанса, модуль внешнего соединения — запуск системы, старт сеанса, работа через COM.
Главное, что определяет выбор, — где исполняется код. Серверный код имеет доступ к базе данных и запросам, клиентский — к интерфейсу и формам. Таблица ниже помогает не промахнуться.
| Задача | Куда писать код |
|---|---|
| Общий расчёт, вызываемый из многих мест | Общий модуль |
| Проверка и движения при записи документа | Модуль объекта |
| Реакция на действия пользователя в форме | Модуль формы |
| Метод «на весь справочник», печать | Модуль менеджера |
| Код при старте программы | Модуль приложения |
Как создать общий модуль и настроить флаги
Общий модуль — рабочая лошадка: сюда выносят повторяющийся код, чтобы не копировать его по десять раз.
- В дереве конфигурации раскройте ветку
Общие → Общие модули. - Правой кнопкой →
Добавить. Задайте имя латиницей без пробелов, напримерРаботаСКонтрагентами. - Откройте палитру свойств (если не видна —
Правка → Свойстваили клавиша F4) и настройте флаги.
Ключевые свойства общего модуля:
- Флаги контекста компиляции:
Сервер,Клиент (управляемое приложение),Клиент (обычное приложение),Внешнее соединение. Отмечаете те контексты, где модуль должен быть доступен. Для серверной бизнес-логики обычно хватает одного флагаСервер. - Вызов сервера — разрешает вызывать экспортные процедуры серверного модуля прямо с клиента. Без этого флага обращение с клиента вызовет ошибку компиляции.
- Привилегированный — код исполняется без контроля прав доступа. Включайте осознанно: привилегированный модуль видит все данные в обход ролей.
- Повторное использование возвращаемых значений —
На время вызова,На время сеансаилиНе использовать. Кэширует результат функции, чтобы не считать одно и то же дважды. Подходит только для функций, которые для одинаковых параметров всегда возвращают один результат. - Глобальный — экспортные методы вызываются без указания имени модуля. Увеличивает время запуска, поэтому глобальных модулей держат минимум.
Простой пример экспортной функции в серверном общем модуле:
Функция ПолноеИмя(Фамилия, Имя, Отчество = "") Экспорт
Результат = СокрЛП(Фамилия) + " " + СокрЛП(Имя);
Если НЕ ПустаяСтрока(Отчество) Тогда
Результат = Результат + " " + СокрЛП(Отчество);
КонецЕсли;
Возврат Результат;
КонецФункции
Ключевое слово Экспорт делает метод видимым снаружи. Вызов из другого модуля: РаботаСКонтрагентами.ПолноеИмя(Фам, Имя). Без Экспорт функция доступна только внутри своего модуля.
Не смешивайте в одном модуле клиентский и серверный код без необходимости. Если на модуле стоят оба флага, компилятор потребует указывать директивы у каждой процедуры.
Код в модуле объекта: события справочника и документа
Модуль объекта содержит логику конкретного прикладного объекта. Он компилируется на сервере и реагирует на предопределённые события жизненного цикла.
Чтобы открыть модуль
: двойным кликом по объекту (например, документу) в дереве конфигурации, затем вкладка (или пункт контекстного меню) Открыть модуль объекта.
Добавлять нужно не произвольные процедуры, а обработчики событий с заранее заданными именами. Самые частые:
ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)— проверка перед записью.ПередЗаписью(Отказ)— последняя возможность отменить запись или дозаполнить реквизиты.ПриЗаписи(Отказ)— после записи объекта, но внутри той же транзакции.ОбработкаПроведения(Отказ, РежимПроведения)— только у документов: формирование движений по регистрам.ПередУдалением(Отказ)— контроль перед удалением.
Если установить Отказ = Истина, операция прерывается — удобно для контроля данных. Пример проверки заполнения с корректным сообщением, привязанным к реквизиту:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если НЕ ЗначениеЗаполнено(Контрагент) Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не заполнен контрагент";
Сообщение.Поле = "Контрагент";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
А так документ формирует движения по регистру накопления при проведении (имена регистра и табличной части — для примера, в вашей конфигурации они свои):
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.ОстаткиТоваров.Записывать = Истина;
Для Каждого СтрокаТовары Из Товары Цикл
Движение = Движения.ОстаткиТоваров.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Номенклатура = СтрокаТовары.Номенклатура;
Движение.Количество = СтрокаТовары.Количество;
КонецЦикла;
КонецПроцедуры
Внутри модуля объекта текущий объект доступен как ЭтотОбъект, а его реквизиты — напрямую по имени (Контрагент, Дата, Товары).
Модуль формы: директивы компиляции и клиентская логика
Форма — это то, что видит пользователь. Её модуль управляет поведением интерфейса и в отличие от модуля объекта работает в двух контекстах сразу — на клиенте и на сервере. Поэтому у каждой процедуры обязательна директива компиляции.
Основные директивы управляемой формы:
&НаКлиенте— исполняется на клиенте, имеет доступ к элементам формы и интерактивным методам.&НаСервере— исполняется на сервере, имеет доступ к базе; получает реквизиты формы, но не её элементы.&НаСервереБезКонтекста— то же, но без передачи данных формы на сервер и обратно. Самый быстрый серверный вызов, потому что не «таскает» контекст формы по сети.&НаКлиентеНаСервереБезКонтекста— процедура доступна в обоих контекстах (например, общая проверка).
Обработчики событий формы и её элементов удобнее добавлять через палитру свойств: выделяете элемент или саму форму, находите нужное событие (например, у поля — ПриИзменении) и нажимаете значок с лупой справа от строки события. Платформа сама создаст процедуру с правильной сигнатурой и перейдёт в модуль.
&НаКлиенте
Процедура ТоварыКоличествоПриИзменении(Элемент)
СтрокаТовары = Элементы.Товары.ТекущиеДанные;
СтрокаТовары.Сумма = СтрокаТовары.Количество * СтрокаТовары.Цена;
КонецПроцедуры
Частые события формы: ПриСозданииНаСервере (начальная настройка, исполняется при открытии на сервере), ПриОткрытии (клиент), ПередЗаписью и ПослеЗаписи. Логику подготовки данных держите в серверных процедурах, реакцию на действия пользователя — в клиентских.
С клиента нельзя напрямую обратиться к базе данных. Если из &НаКлиенте-процедуры нужны данные из базы, вызывайте серверную процедуру (&НаСервере или &НаСервереБезКонтекста), а не пытайтесь выполнить запрос на клиенте.
Модуль менеджера и подписки на события
Модуль менеджера хранит методы, которые относятся к объекту в целом, а не к отдельному элементу. Открывается так же, как модуль объекта: контекстное меню объекта → Открыть модуль менеджера. Компилируется на сервере.
Сюда помещают методы, которые логично вызывать «от имени» справочника или документа:
// Модуль менеджера справочника "Контрагенты"
Функция НайтиПоИНН(ИНН) Экспорт
Возврат Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", ИНН);
КонецФункции
Экспортный метод вызывается через менеджер объекта: Справочники.Контрагенты.НайтиПоИНН(СтрокаИНН). В модуле менеджера также размещают обработчик ОбработкаПолученияДанныхВыбора и команды печати.
Отдельный приём, которого нет в наивной инструкции, — подписки на события. Они позволяют вынести код из модуля объекта в общий модуль, не трогая сам объект. Это важно, когда нужно повесить обработку на типовой документ.
- Создайте экспортную процедуру в неглобальном серверном общем модуле. Её параметры должны совпадать с сигнатурой события.
- В дереве конфигурации:
Общие → Подписки на события → Добавить. - Укажите Источник (тип или набор типов), Событие (например,
ПередЗаписью) и Обработчик (вашу процедуру).
Так один общий модуль обслуживает событие сразу у многих объектов, а логика собрана в одном месте.
Расширения конфигурации: код без снятия с поддержки
Если вы дорабатываете типовую конфигурацию (БП 3.0, ЗУП 3.1, УТ 11), просто так в её модули писать нельзя — она на поддержке поставщика. Есть два пути.
Снятие с поддержки (Конфигурация → Поддержка → Настройка поддержки) снимает замок редактирования, но тогда автоматическое обновление
усложняется: типовые релизы придётся сверять вручную. Для небольших доработок это неоправданно.
Расширение конфигурации — правильный современный способ (доступен с платформы 8.3.6). Расширение хранит ваши изменения отдельным файлом и накладывается на типовую конфигурацию, не изменяя её. Обновления типовой при этом продолжают ставиться штатно.
- Меню
Конфигурация → Расширения конфигурации, добавьте новое расширение, задайте имя и префикс. - Переключитесь на дерево расширения и добавляйте свои общие модули, формы, а к заимствованным объектам — обработчики через аннотации
&Перед,&После,&Вместо. - Загрузите расширение (
.cfe) и обновите конфигурацию базы данных — это два отдельных шага.
Для доработки типовой конфигурации сначала рассматривайте расширение и подписки на события. Снятие с поддержки оставляйте на случай, когда задачу иначе не решить.
Как отладить и проверить написанный код
Написать код мало — его нужно проверить. В Конфигураторе для этого есть встроенный отладчик.
Сначала базовая проверка синтаксиса: кнопка синтаксического контроля на панели инструментов модуля проверяет текущий модуль, а Конфигурация → Проверить конфигурацию — всю конфигурацию целиком. Синтаксический контроль ловит опечатки и неизвестные имена ещё до запуска.
Пошаговая отладка:
- Поставьте точку останова на нужной строке — клавиша F9 или клик на серой полосе слева от кода.
- Запустите
1С:Предприятиев режиме отладки — клавиша F5. Когда исполнение дойдёт до точки, оно остановится. - Двигайтесь по коду: F11 — шагнуть внутрь процедуры, F10 — выполнить строку не заходя внутрь, Shift+F11 — выйти из текущей процедуры.
- Смотрите значения переменных в окне Табло, а разовые выражения вычисляйте через
Отладка → Вычислить выражение(Shift+F9).
Для файловой базы отладка подключается автоматически. Для клиент-серверной базы отладку по протоколу нужно разрешить в параметрах информационной базы (флаг разрешения отладки), а в Конфигураторе выбрать предмет отладки через меню Отладка → Подключение.
Полезно и измерение производительности: Отладка → Замер производительности покажет, какие строки кода выполняются дольше всего, — удобно искать медленные запросы в цикле.
Частые вопросы
Чем модуль объекта отличается от модуля менеджера?
Почему процедура из общего модуля не вызывается с клиента?
Экспорт у процедуры.Что означает директива &НаСервереБезКонтекста?
Как добавить обработчик события, не меняя типовой объект?
Общие → Подписки на событие. Либо используете расширение конфигурации с аннотациями &Перед, &После, &Вместо.