Как обратиться к команде документа и напечатать его из модуля управляемого приложения в 1С?

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

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

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

Почему нельзя напрямую вызвать команду документа из кода

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

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

Архитектура решения: разделение контекста Клиент/Сервер

Разберем по шагам правильную организацию процесса:

  1. Клиентский контекст: в процедуре ПриНачалеРаботыСистемы модуля управляемого приложения проверяются необходимые условия (например, день недели) и запрашивается список данных.
  2. Серверный контекст: создаются объекты документов, заполняются табличные части, выполняется проведение, а также формируются печатные формы (объекты типа ТабличныйДокумент).
  3. Возврат на клиент: сформированный табличный документ передается на клиент для вывода на экран через метод Показать() или для отправки на печать методом Напечатать().

Шаг 1. Вызов процедуры в модуле управляемого приложения

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


Процедура ПриНачалеРаботыСистемы()
    
    Если ДеньНедели(ТекущаяДата()) = 1 Тогда
        
        // Получаем массив типов ценностей из внешнего источника/регистра
        ТипСкупленныхЦенностей = ВнешниеСоединения.ПолучитьДанные();
        
        Если ТипСкупленныхЦенностей.Количество() > 0 Тогда
            Для Каждого ТипЦенности Из ТипСкупленныхЦенностей Цикл
                // Создаем и проводим документ на сервере
                ОбщиеДанныеСервер.ФормируемДокументПередачиСкупленныхЦенностей(ТипЦенности);
            КонецЦикла;
            
            // Печать товарной накладной
            ТабДокНакладная = Новый ТабличныйДокумент;
            ОбщиеДанныеСервер.СформироватьТоварнуюНакладную(ТабДокНакладная);
            ТабДокНакладная.АвтоМасштаб = Истина;
            ТабДокНакладная.КоличествоЭкземпляров = 3;
            ТабДокНакладная.Напечатать();
            
            // Печать реестра
            ТабДокРеестр = Новый ТабличныйДокумент;
            ОбщиеДанныеСервер.СформироватьРеестр(ТабДокРеестр);
            ТабДокРеестр.АвтоМасштаб = Истина;
            ТабДокРеестр.КоличествоЭкземпляров = 1;
            ТабДокРеестр.Напечатать();
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Шаг 2. Серверная логика создания и заполнения документа

В серверном общем модуле (например, ОбщиеДанныеСервер с установленными свойствами Сервер и Вызов сервера) разместим код создания и заполнения объекта документа.


Функция ФормируемДокументПередачиСкупленныхЦенностей(ТипЦенности) Экспорт
    
    ДокументОбъект = Документы.ПередачаСкупленныхЦенностейВЦО.СоздатьДокумент();
    ДокументОбъект.Организация = Константы.ОрганизацияПоУмолчаниюДляСкупки.Получить();
    ДокументОбъект.Филиал = Константы.ПодразделениеПоУмолчанию.Получить();
    ДокументОбъект.Дата = ТекущаяДата();
    ДокументОбъект.ТипЦенностей = ТипЦенности;
    
    ЗаполнитьТабличнуюЧасть(ДокументОбъект);
    
    Возврат ДокументОбъект;
    
КонецФункции

Процедура ЗаполнитьТабличнуюЧасть(ДокументОбъект)
    
    ДанныеВДокументе = Ложь;
    СекундВСутках = 86400;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	СкупленныеЦенности.СкупочнаяКвитанция КАК СкупочнаяКвитанция,
        |	СкупленныеЦенности.ДатаСкупки КАК ДатаСкупки,
        |	СкупленныеЦенности.Номенклатура КАК Номенклатура,
        |	СкупленныеЦенности.Количество КАК Количество,
        |	СкупленныеЦенности.Сумма КАК Сумма,
        |	СкупленныеЦенности.Номенклатура.ОбщийВес КАК ВесОбщий,
        |	СкупленныеЦенности.Номенклатура.ЧистыйВес КАК ВесЧистый,
        |	СкупленныеЦенности.Номенклатура.Проба КАК Проба,
        |	СкупленныеЦенности.Металл КАК Металл
        |ИЗ
        |	РегистрСведений.СкупленныеЦенности КАК СкупленныеЦенности
        |ГДЕ
        |	СкупленныеЦенности.ДатаСкупки МЕЖДУ &ДатаНач И &ДатаКон
        |	И СкупленныеЦенности.ТипСкупаемойЦенности = &ТипСкупаемойЦенности
        |УПОРЯДОЧИТЬ ПО
        |	СкупленныеЦенности.СкупочнаяКвитанция.Номер";
        
    Запрос.УстановитьПараметр("ДатаКон", КонецДня(ТекущаяДата() - СекундВСутках));
    Запрос.УстановитьПараметр("ДатаНач", НачалоДня(ТекущаяДата() - (7 * СекундВСутках)));
    Запрос.УстановитьПараметр("ТипСкупаемойЦенности", ДокументОбъект.ТипЦенностей);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        СтрокаТЧ = ДокументОбъект.СписокЦенностей.Добавить();
        ЗаполнитьЗначенияСвойств(СтрокаТЧ, Выборка);
        Если Выборка.Количество <> 0 Тогда
            СтрокаТЧ.Цена = Выборка.Сумма / Выборка.Количество;
        КонецЕсли;
        ДанныеВДокументе = Истина;
    КонецЦикла;
    
    Если ДанныеВДокументе Тогда
        ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
    КонецЕсли;
    
КонецПроцедуры

Шаг 3. Формирование печатной формы на сервере

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


Процедура СформироватьТоварнуюНакладную(ТабДок) Экспорт
    
    Макет = Документы.ПередачаСкупленныхЦенностейВЦО.ПолучитьМакет("ТоварнаяНакладная");
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    
    // Заполнение параметров и вывод областей в ТабличныйДокумент
    ТабДок.Вывести(ОбластьШапка);
    
    // Дополнительная логика обхода проведенных документов за день
    // ...
    
КонецПроцедуры

Альтернативный вариант: показ документа вместо прямой печати

Если требуется не сразу отправлять печатную форму на принтер, а дать пользователю возможность просмотреть ее перед печатью, вместо метода ТабДок.Напечатать() используется метод ТабДок.Показать(). Он доступен исключительно на клиенте и открывает окно просмотра табличного документа.

Рекомендации по повышению надежности алгоритма

← На главную