В этой статье я буду описывать свой поход к отправке отчетов, сделанных на СКД, по расписанию. Статья будет про неуправляемые формы обычное приложение. Будут описаны некоторые объекты 1С, будет много кода. Готовы? Тогда под кат.
Для начала определимся с целью. Какой функционал у нас должен получиться в результате? Я для себя решил примерно так:
- Отчет должен отправляться на почтовые адреса, указанные в настройках
- В одном письме может быть несколько отчетов
- При добавлении новых отчетов для отправки конфигурация не должна изменяться.
- Формат отчета должен быть pdf, xls, html и т.д.
- Для отправки отчетов должна быть гибкая настройка расписания.
Теперь немного изменим конфигурацию 1С:
- Создать справочник «Настройки отправки отчетов»
- Реквизиты: РегламентноеЗадание (Строка 40), ИспользоватьРегламентныеЗадания (Булево)
- Табличные части: ОтчетыДляОтправки, ПочтовыеАдреса
- Реквизиты табличной части «ОтчетыДляОтправки»: Отчет (СправочникСсылка.ВнешниеОбработки), ФорматФайла (Строка 10)
- Реквизиты табличной части «ПочтовыеАдреса»: Адрес (Строка 50)
- Создать регламентное задание «ОтправкаОтчетовПоРассписанию». Именно этот объект будет отвечать за действия выполняемые по расписанию. В нашем случае за отправку отчетов
- Создать процедуру для работы регламентного задания, нажав на кнопку в поле «Имя метода». Далее приведу код процедуры и вызываемой ею функции
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586Процедура ОтправитьНаПочту(Тема, Текст, СписокПолучателей, Вложения)Почта = Новый ИнтернетПочта;Сообщение = Новый ИнтернетПочтовоеСообщение;Сообщение.Тема = Тема;Сообщение.Отправитель.Адрес = "adres@otpravitelya.ru";Сообщение.Отправитель.ОтображаемоеИмя = "Отчеты из 1С";Сообщение.Отправитель.Пользователь = "user";Сообщение.Отправитель.Сервер = "server";Сообщение.Тексты.Добавить(Текст);Для Каждого стр из СписокПолучателей ЦиклЕсли ЗначениеЗаполнено(стр.Значение) ТогдаСообщение.Получатели.Добавить(стр.Значение);КонецЕсли;КонецЦикла;Для Каждого Вложение из Вложения ЦиклСообщение.Вложения.Добавить(Вложение.Значение);КонецЦикла;Профиль = Новый ИнтернетПочтовыйПрофиль;Профиль.Пароль = "password";Профиль.Пользователь = "user";Профиль.АдресСервераSMTP = "smtp_server";Профиль.ПользовательSMTP = "smtp_user";Профиль.ПарольSMTP = "smtp_password";Профиль.ПортSMTP = 587;Профиль.АутентификацияSMTP = СпособSMTPАутентификации.Login;Профиль.АутентификацияPOP3 = СпособPOP3Аутентификации.Обычная;Если Сообщение.Получатели.Количество() > 0 ТогдаПочта.Подключиться(Профиль);ПопыткаПочта.Послать(Сообщение);Исключение//Сообщить(ОписаниеОшибки());КонецПопытки;Почта.Отключиться();КонецЕсли;КонецПроцедурыПроцедура ВыполнитьОтправкуОтчета(Настройка)СписокПолучателей = Новый СписокЗначений;СписокВложений = Новый СписокЗначений;Для Каждого Получатель из Настройка.ПочтовыеАдреса ЦиклСписокПолучателей.Добавить(Получатель.Адрес);КонецЦикла;Для Каждого СтрокаОтчет из Настройка.ОтчетыДляОтправки ЦиклДвоичныеДанные = СтрокаОтчет.Отчет.ХранилищеВнешнейОбработки.Получить();врФайл = ПолучитьИмяВременногоФайла("epf");ДвоичныеДанные.Записать(врФайл);ТабДок = Новый ТабличныйДокумент;Отчет = ВнешниеОтчеты.Создать(врФайл);Отчет.СкомпоноватьРезультат(ТабДок);врФайл = КаталогВременныхФайлов() + СтрокаОтчет.Отчет.Наименование + "." + СтрокаОтчет.ФорматФайла;ТабДок.Записать(врФайл,ТипФайлаТабличногоДокумента[СтрокаОтчет.ФорматФайла]);СписокВложений.Добавить(врФайл);КонецЦикла;ОтправитьНаПочту(Настройка.Наименование,"Отчеты во вложении",СписокПолучателей,СписокВложений);КонецПроцедурыПроцедура ОтправкаОтчетовПоРассписанию(КодНастройки) ЭкспортЕсли НЕ ЗначениеЗаполнено(КодНастройки) ТогдаВозврат;КонецЕсли;НастройкаОтправки = Справочники.НастройкиОтправкиОтчетов.НайтиПоКоду(КодНастройки);Если НЕ ЗначениеЗаполнено(НастройкаОтправки) ТогдаВозврат;КонецЕсли;Если НастройкаОтправки.ПометкаУдаления ТогдаВозврат;КонецЕсли;ВыполнитьОтправкуОтчета(НастройкаОтправки);КонецПроцедуры
Немного поясню: Процедура ОтправкаОтчетовПоРассписанию создается тогда, когда Вы нажимаете на кнопку в поле «Имя метода». Другие две процедуры Вы должн
Ну и вставить свои учетные данные почтового сервера вместо этих: adres@otpravitelya.ru, user, server, password, smtp_server, smtp_user, smtp_password - Создаем форму элемента справочника «Настройки отправки отчетов» и раскидываем по ней все реквизиты и табличные части. Использовать в коде будем только процедуру формы «ПриОткрытии» и событие галочки «ИспользоватьРегламентныеЗадания». Также добавьте на форму надпись «НадписьРасписаниеРегламентногоЗаданияНастройки», т.к. будем использовать ее событие «ПриНажатии». Приведу код
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081Перем мЖирныйШрифт;Перем мОбычныйШрифт;Процедура УстановитьТекстНадписиРегламентнойНастройки()Перем ТекстЗаголовка, ТекстРасписания, РассписаниеАктивно;ПроцедурыОбменаДаннымиКлиент.ПолучитьТекстЗаголовкаИРасписанияРегламентнойНастройки(мРегламентноеЗадание, ТекстЗаголовка, ТекстРасписания, РассписаниеАктивно);//ЭлементыФормы.НастройкаРегламентногоЗадания.Заголовок = ТекстЗаголовка;ЭлементыФормы.НадписьРасписаниеРегламентногоЗаданияНастройки.Заголовок = ТекстРасписания;ЭлементыФормы.НадписьРасписаниеРегламентногоЗаданияНастройки.Шрифт = ?(РассписаниеАктивно И ИспользоватьРегламентныеЗадания, мЖирныйШрифт, мОбычныйШрифт);КонецПроцедурыПроцедура ОбновитьДоступностьАвтообмена()//ЭлементыФормы.НастройкаРегламентногоЗадания.Доступность = ИспользоватьРегламентныеЗадания;ЭлементыФормы.НадписьРасписаниеРегламентногоЗаданияНастройки.Доступность = ИспользоватьРегламентныеЗадания;КонецПроцедурыПроцедура РедактированиеРасписанияРегламентногоЗадания(ОбъектЗадания, РеквизитЗадания)Если ОбъектЗадания = Неопределено ТогдаОбъектЗадания = ПолучитьОбъектРегламентногоЗадания();КонецЕсли;Если ОбъектЗадания = Неопределено ТогдаОбъектЗадания = РегламентныеЗадания.СоздатьРегламентноеЗадание("ОтправкаОтчетовПоРассписанию");ОбъектЗадания.Наименование = Наименование;ОбъектЗадания.Использование = Истина;КонецЕсли;Диалог = Новый ДиалогРасписанияРегламентногоЗадания(ОбъектЗадания.Расписание);Если Диалог.ОткрытьМодально() ТогдаОбъектЗадания.Расписание = Диалог.Расписание;ОбъектЗадания.Записать();РеквизитЗадания = Строка(ОбъектЗадания.УникальныйИдентификатор);ИначеОбъектЗадания = ПолучитьОбъектРегламентногоЗадания();КонецЕсли;УстановитьТекстНадписиРегламентнойНастройки();КонецПроцедурыПроцедура НадписьРасписаниеРегламентногоЗаданияНастройкиНажатие(Элемент)РедактированиеРасписанияРегламентногоЗадания(мРегламентноеЗадание, РегламентноеЗадание);КонецПроцедурыПроцедура ПриОткрытии()УстановитьЗначенияПеременныхРегламентныхНастроек();УстановитьТекстНадписиРегламентнойНастройки();ОбновитьДоступностьАвтообмена();КонецПроцедурыПроцедура ИспользоватьРегламентныеЗаданияПриИзменении(Элемент)ОбновитьДоступностьАвтообмена();УстановитьТекстНадписиРегламентнойНастройки();Если ИспользоватьРегламентныеЗадания ТогдаНадписьРасписаниеРегламентногоЗаданияНастройкиНажатие(ЭлементыФормы.НадписьРасписаниеРегламентногоЗаданияНастройки);Конецесли;КонецПроцедурымРегламентноеЗадание = Неопределено;мЖирныйШрифт = Новый Шрифт(,,Истина);мОбычныйШрифт = Новый Шрифт();
Ну и код модуля справочника «Настройки отправки отчетов»:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140Перем мРегламентноеЗадание Экспорт;Функция НайтиРеглЗаданиеПоПараметру(УникальныйНомерЗадания)ПопыткаЕсли НЕ ПустаяСтрока(УникальныйНомерЗадания) ТогдаУникальныйИдентификаторЗадания = Новый УникальныйИдентификатор(УникальныйНомерЗадания);ТекущееРегламентноеЗадание = РегламентныеЗадания.НайтиПоУникальномуИдентификатору(УникальныйИдентификаторЗадания);ИначеТекущееРегламентноеЗадание = Неопределено;КонецЕсли;ИсключениеТекущееРегламентноеЗадание = Неопределено;КонецПопытки;Возврат ТекущееРегламентноеЗадание;КонецФункцииФункция НайтиРегламентноеЗаданиеПоНастройке() ЭкспортТекущееРегламентноеЗадание = НайтиРеглЗаданиеПоПараметру(РегламентноеЗадание);Возврат ТекущееРегламентноеЗадание;КонецФункцииФункция ПолучитьОбъектРегламентногоЗадания() ЭкспортЗадание = НайтиРегламентноеЗаданиеПоНастройке();Возврат Задание;КонецФункцииПроцедура УстановитьЗначенияПеременныхРегламентныхНастроек() ЭкспортЕсли мРегламентноеЗадание = Неопределено ТогдамРегламентноеЗадание = ПолучитьОбъектРегламентногоЗадания();КонецЕсли;КонецПроцедурыПроцедура ПередЗаписью(Отказ)Если ОтчетыДляОтправки.Количество() = 0 ТогдаСообщитьОбОшибке("Не выбрано отчетов для отправки", Отказ);КонецЕсли;Если ПочтовыеАдреса.Количество() = 0 ТогдаСообщитьОбОшибке("Не выбраны получатели для отправки", Отказ);КонецЕсли;Для Каждого Стр из ОтчетыДляОтправки ЦиклЕсли Не ЗначениеЗаполнено(Стр.ФорматФайла) ТогдаСообщитьОбОшибке("Не указан формат файла для отправки в строке '" + Стр.НомерСтроки + "'", Отказ);ИначеПопыткаврТип = ТипФайлаТабличногоДокумента[Стр.ФорматФайла];ИсключениеСообщитьОбОшибке("Не корректно указан формат файла для отправки в строке '" + Стр.НомерСтроки + "'", Отказ);КонецПопытки;КонецЕсли;КонецЦикла;УстановитьЗначенияПеременныхРегламентныхНастроек();Если ПометкаУдаленияИЛИ НЕ ИспользоватьРегламентныеЗадания ТогдаЕсли мРегламентноеЗадание <> Неопределено ТогдамРегламентноеЗадание.Использование = Ложь;КонецЕсли;Иначе// если оба выключены регл задания - то включаем основное регл заданиеЕсли мРегламентноеЗадание = Неопределено ТогдаСообщитьОбОшибке("Не выбрано регламентное задание для отправки отчетов.", Отказ);КонецЕсли;Если мРегламентноеЗадание <> Неопределено ТогдамРегламентноеЗадание.Использование = Истина;КонецЕсли;КонецЕсли;Если Отказ ТогдаВозврат;КонецЕсли;Если мРегламентноеЗадание <> НеопределеноИ Не ПустаяСтрока(мРегламентноеЗадание.Ключ) ТогдаКлючРегламентногоЗадания = мРегламентноеЗадание.Ключ;ИначеКлючРегламентногоЗадания = Строка(Новый УникальныйИдентификатор);КонецЕсли;УстановитьПараметрыРегламентногоЗадания(РегламентноеЗадание, мРегламентноеЗадание, КлючРегламентногоЗадания);КонецПроцедурыПроцедура УстановитьПараметрыРегламентногоЗадания(РеквизитЗадания, ПараметрЗадания, КлючРегламентногоЗадания, Постфикс = "")Если ПараметрЗадания = Неопределено ТогдаРеквизитЗадания = "";ИначеРеквизитЗадания = Строка(ПараметрЗадания.УникальныйИдентификатор);ПараметрЗадания.Наименование = Наименование + Постфикс;// генерируем уникальный ключ, что бы в один момент времени 2 регламентных задания не выполнялисьЕсли ПустаяСтрока(ПараметрЗадания.Ключ) ТогдаПараметрЗадания.Ключ = КлючРегламентногоЗадания;КонецЕсли;Массив = Новый Массив();Массив.Добавить(Код);ПараметрЗадания.Параметры = Массив;ПараметрЗадания.Записать();КонецЕсли;КонецПроцедуры
- Обновляем конфигурацию и пробуем то, что у нас получилось. Отправляются ли отчеты
Один Ответ
Подсистема является упрощенным аналогом Рассылки отчетов из БСП. Встраивается в конфигурацию элементарно.