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