Как вызвать процедуру формы элемента справочника в общем модуле для регламентного задания

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Почему нельзя вызвать процедуру формы из общего модуля?

Для начала проанализируем ключевое ограничение платформы: регламентные задания выполняются на сервере в фоновом сеансе. В этом сеансе не существует графического интерфейса, нет «клиента» и, соответственно, невозможно открыть ни одну форму. Форма — это объект визуального представления данных, который живет только в памяти клиентского приложения. Как только пользователь закрывает форму, она уничтожается. Регламентное задание, работая автономно, «не знает», какую именно форму и какого элемента справочника нужно открыть.

Следовательно, любая попытка получить форму через ПолучитьФорму() на сервере и вызвать её экспортную процедуру приведет к ошибке или не даст результата в контексте регламентного задания.

Шаг 1: Перенос логики из модуля формы в модуль менеджера или общий модуль

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

Если мы выбираем общий модуль, убедитесь, что у него установлены свойства «Сервер» и «Экспорт» у самой процедуры. Рассмотрим пример кода в общем модуле РассылкаСервер:


// Процедура в общем модуле (серверном)
Процедура ВыполнитьРассылкуПоНастройке(СсылкаНаНастройку) Экспорт
    
    // Получаем данные непосредственно из объекта базы данных
    ОбъектНастройки = СсылкаНаНастройку.ПолучитьОбъект();
    
    Для Каждого СтрокаАдреса Из ОбъектНастройки.СписокАдресов Цикл
        
        ПараметрыПисьма = Новый Структура;
        ПараметрыПисьма.Вставить("Адрес", СтрокаАдреса.Адрес);
        ПараметрыПисьма.Вставить("Тема", ОбъектНастройки.ТемаСообщения);
        ПараметрыПисьма.Вставить("Текст", ОбъектНастройки.ТекстСообщения);
        
        // Обработка вложения из ХранилищаЗначения
        Если ЗначениеЗаполнено(ОбъектНастройки.ВложениеВСообщение) Тогда
            ДвоичныеДанные = ОбъектНастройки.ВложениеВСообщение.Получить();
            ПараметрыПисьма.Вставить("Вложение", ДвоичныеДанные);
        КонецЕсли;
        
        // Вызов системной функции отправки
        ОтправитьПочтовоеСообщение(ПараметрыПисьма);
        
    КонецЦикла;

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

Шаг 2: Хранение данных в реквизитах объекта, а не формы

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

Выясним причину: регламентное задание не может прочитать то, что пользователь «набил» в экранные поля и не нажал кнопку «Записать». Поэтому в справочнике создаем соответствующие реквизиты: ТемаСообщения (Строка), ТекстСообщения (Строка), ВложениеВСообщение (ХранилищеЗначения). В форме в свойстве «Данные» для полей ввода указываем путь к реквизитам объекта (например, Объект.ТемаСообщения).

Шаг 3: Работа с файлами и ХранилищемЗначения

Если ваша процедура должна отправлять файл, выбранный пользователем, его нужно предварительно сохранить в базу. Разберем по шагам, как поместить файл в реквизит с типом ХранилищеЗначения:

  1. На клиенте пользователь выбирает файл через ДиалогВыбораФайла.
  2. Файл помещается во временное хранилище.
  3. На сервере данные из временного хранилища записываются в реквизит объекта.

Посмотрим на пример реализации в модуле формы:


&НаКлиенте
Асинхронная Процедура ВыбратьФайлИСохранить(Команда)
    
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    Если Ждать Диалог.ВыбратьАсинхронно() Тогда
        
        // Помещаем файл во временное хранилище
        ДвоичныеДанные = Новый ДвоичныеДанные(Диалог.ПолноеИмяФайла);
        АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ЭтаФорма.УникальныйИдентификатор);
        
        // Передаем адрес на сервер для сохранения в объект
        СохранитьФайлВОбъектеНаСервере(АдресХранилища);
        
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Процедура СохранитьФайлВОбъектеНаСервере(АдресХранилища)
    
    ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
    Объект.ВложениеВСообщение = Новый ХранилищеЗначения(ДвоичныеДанные);
    // Теперь файл физически будет в БД после записи объекта
    
КонецПроцедуры

Шаг 4: Настройка регламентного задания

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

Если нам нужно, чтобы задание знало, по какой именно настройке (какому элементу справочника) отправлять письма, рассмотрим вариант использования параметров регламентного задания:


// В общем модуле процедура, которую вызывает регламентное задание по расписанию
Процедура ОсновнаяРассылкаПоРасписанию() Экспорт
    
    // Например, находим нужную настройку по коду или предопределенному значению
    СсылкаНаНастройку = Справочники.ТипыСообщенийПоЭлПочте.НайтиПоКоду("130");
    
    Если Не СсылкаНаНастройку.Пустая() Тогда
        // Вызываем нашу универсальную процедуру
        ВыполнитьРассылкуПоНастройке(СсылкаНаНастройку);
    КонецЕсли;
    
КонецПроцедуры

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

Резюме

Для вызова функционала формы в общем модуле необходимо:

  1. Вынести код из модуля формы в общий модуль с флагом «Сервер».
  2. Заменить реквизиты формы на реквизиты объекта, чтобы данные сохранялись в базе данных.
  3. Использовать ХранилищеЗначения для файлов-вложений.
  4. Создать процедуру-точку входа в общем модуле для регламентного задания, которая будет находить нужный элемент справочника и запускать процесс.

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

← На главную