Friday, February 8, 2013

Рассылка СКД отчетов из 1С с помощью фоновых заданий.

Интересная схема рассылки отчетов из 1С.
СКД в 1С достаточно мощная и грамотная схема, конечно есть и ошибки и проблемы, но думаю их исправят.
Так вот, раньше что бы сформировать отчет, приходилось достаточно много писать и дорабатывать не только на 1с, но и на других языках.
Сейчас же можно достаточно быстро и эффективно формировать данные самой 1С. На текущий момент, я использую платформу 1С 8.2.17.153.

1. И самое основное для создания рассылки необходимо создать фоновое задание и процедуру формирования рассылки. Для этого я создал общий модуль "ПочтовыеРассылки" и установил в свойствах что он является "Серверным" и свойствах "Вызов сервера=Истина" + "Привилегированный=Истина".
Далее в него добавил 2 процедуры:

С процедурой отправить, думаю все понятно.


Exported from Notepad++



//Требование к запуску процедуры
//1.ДанныеПисьма = Структура
//1.1 ДанныеПисьма.Кому = массив адресат
//1.2 ДанныеПисьма.Вложения = массив строчный на файлы для вложения
//1.3 ДанныеПисьма.Тема - Тема письма
//1.4 Тело
//1.5 ОбратныйАдрес
//ДанныеПисьма = Новый Структура("Тема,Тело,Кому,Вложения");

Процедура Отправить(ДанныеПисьма) экспорт
//для получения доступа к набору свойств для соединения с сервером
//создадим новый объект
УстановитьПривилегированныйРежим(Истина);
Профиль = Новый ИнтернетПочтовыйПрофиль;

//Пропишем параметры соединения
//ip адрес или имя SMTP сервера
Профиль.АдресСервераSMTP = "*********";

//Порт SMTP сервера
Профиль.ПортSMTP = "***";

//Имя пользователя почтового ящика
Профиль.Пользователь = "***********";

//Пароль доступа к почтовому ящику
Профиль.Пароль = "******************";

//При необходимости добавляем аутентификацию
Профиль.АутентификацияSMTP = СпособSMTPАутентификации.БезАутентификации;
//Профиль.ПарольSMTP = Профиль.Пароль;
//Профиль.ПользовательSMTP = Профиль.Пользователь;
// Создаем объект для работы с почтой
Почта = Новый ИнтернетПочта;

//Выполняем подключение, согласно указанный параметров
Попытка
Почта.Подключиться(Профиль);
Исключение
//При подключении возникла ошибка, сообщим
Сообщить("Ошибка при подключении к серверу" + ОписаниеОшибки());
Возврат;
КонецПопытки;

//Создаем новое письмо (сообщение)
Сообщение = Новый ИнтернетПочтовоеСообщение;
Если ДанныеПисьма.Свойство("ОбратныйАдрес") И ТипЗнч(ДанныеПисьма.ОбратныйАдрес)= Тип("Строка") тогда
Сообщение.ОбратныйАдрес.Добавить(ДанныеПисьма.ОбратныйАдрес);
Сообщение.Отправитель = ДанныеПисьма.ОбратныйАдрес;
КонецЕсли;

//Указываем отправителя
//Сообщение.Отправитель = "*********@*****";

Если ТипЗнч(ДанныеПисьма.Кому)= Тип("Строка") тогда
Сообщение.Получатели.Добавить(ДанныеПисьма.Кому);
ИначеЕсли ТипЗнч(ДанныеПисьма.Кому) = Тип("Массив") тогда
Для Каждого ЗначКому из ДанныеПисьма.Кому Цикл
Сообщение.Получатели.Добавить(ЗначКому);
КонецЦикла;
Иначе
//Если какая-то жопа то шлем мне
Сообщение.Получатели.Добавить("********@******");
КонецЕсли;


//Пишем тему письма
Сообщение.Тема = ДанныеПисьма.Тема;

//Формируем текст письма,указываем тип письма
Сообщение.Тексты.Добавить(ДанныеПисьма.Тело,ТипТекстаПочтовогоСообщения.HTML);

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

//Непосредственно отправка сообщения
Почта.Послать(Сообщение);

//После отправки закрываем соединение
Почта.Отключиться();
Сообщение = Неопределено;
Почта = Неопределено;
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры



// Передаем
//1. СхемаКомпоновкиДанных
//2. КомпоновщикНастроекКомпоновкиДанных
//3. СтрктуруПисьма - см. процедуру Отправить
//4. СтруктуруФайла отправки
//4.1. Файлом = Истина (если доп. вложением) Если ложь то html4 и вставляем в тело письма
//4.2 Типом файла

Процедура СформироватьИОтправитьОтчетПоПочте(СтруктураФормирования) Экспорт

УстановитьПривилегированныйРежим(Истина);
СхемаКомпоновкиДанных=СтруктураФормирования.СхемаКомпоновкиДанных;
//Настройки=СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
//Если СтруктураНастроек=Неопределено тогда
// КомпоновщикНастроекКомпоновкиДанных = СтруктураФормирования.КомпоновщикНастроекКомпоновкиДанных;
//Иначе
// КомпоновщикНастроекКомпоновкиДанных = СтруктураНастроек.КомпоновщикНастроекКомпоновкиДанных;
//КонецЕсли;


КомпоновщикМакета=Новый КомпоновщикМакетаКомпоновкиДанных;
//МакетКомпоновки=КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроекКомпоновкиДанных.Настройки);
МакетКомпоновки=КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, СтруктураФормирования.КомпоновщикНастроекКомпоновкиДанныхНастройки);
ПроцессорКомпоновки=Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ТабДок=Новый ТабличныйДокумент;
ПроцессорВывода=Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

ТемпФайл=ПолучитьИмяВременногоФайла(Строка(СтруктураФормирования.СтруктураФайла.ТипФайлаТабличногоДокумента));

//ТабДок.Записать(ТемпФайл,ТипФайлаТабличногоДокумента.HTML4);
ТабДок.Записать(ТемпФайл,СтруктураФормирования.СтруктураФайла.ТипФайлаТабличногоДокумента);
Если СтруктураФормирования.СтруктураФайла.Файлом тогда
СтруктураФормирования.СтрктуруПисьма.Вставить("Вложения",ТемпФайл);
Иначе
Текст = Новый ЧтениеТекста(ТемпФайл);
СтруктураФормирования.СтруктураПисьма.Вставить("Тело",Текст.Прочитать());
Текст = Неопределено;
КонецЕсли;

//Требование к запуску процедуры
//1.ДанныеПисьма = Структура
//1.1 ДанныеПисьма.Кому = массив адресат
//1.2 ДанныеПисьма.Вложения = массив строчный на файлы для вложения
//1.3 ДанныеПисьма.Тема - Тема письма
//1.4 Тело
//1.5 ОбратныйАдрес
//ДанныеПисьма = Новый Структура("Тема,Тело,Кому,Вложения");

//Отправить(ДанныеПисьма)

ПочтовыеРассылки.Отправить(СтруктураФормирования.СтруктураПисьма);
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры




А вот вторую процедуру опишу более подробно.
Процедура "СформироватьИОтправитьОтчетПоПочте" получает на входе в структуре следующие значения
1. СхемаКомпоновкиДанных - Схему компоновки данных СКД
2. КомпоновщикНастроекКомпоновкиДанныхНастройки - Настройки схемы компоновки данных, пробывал передавать компоновщик настроек, но по непонятным причинам при выполнении на сервере в структуру вместо компоновщика, передавалась схема. Поигравшись с разными вариантами, стал передавать только настройки, так как сам компоновщик мне и не нужен.
3. СтруктураФайла - в этой структуре я описываю, информацию по вложениям
3.1. СтруктураФайла.ТипФайлаТабличногоДокумента - Передается значение ТипФайлаТабличногоДокумента, если же формируем отчет в теле письма то передаем html4.
3.2. СтруктураФормирования.СтруктураФайла.Файлом - Булево, если значение = Истина, тогда файл передается вложением, если = Ложь - тогда в теле письма.
3.3. СтруктураФормирования.СтруктураПисьма - Передается структура для отправки.

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



Exported from Notepad++



Процедура ВыполнитьНаСервереТестовоеСоздание()
Обработка = ВнешниеОтчеты.Создать("c:\Work\UT11\МаркетинговыйОтчет.erf");



СтруктураРаботы = Новый структура;
СхемаКомпоновкиДанных=Обработка.СхемаКомпоновкиДанных;
СтруктураРаботы.Вставить("СхемаКомпоновкиДанных",СхемаКомпоновкиДанных);


КомпоновщикНастроекКомпоновкиДанных = Новый КомпоновщикНастроекКомпоновкиДанных;
//КомпоновщикНастроекКомпоновкиДанных.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
//КомпоновщикНастроекКомпоновкиДанных.ЗагрузитьНастройки(СхемаКомпоновкиДанных.НастройкиПоУмолчанию);




КомпоновщикНастроекКомпоновкиДанных.ЗагрузитьНастройки(СхемаКомпоновкиДанных.ВариантыНастроек.Основной.Настройки);
КомпоновщикНастроекКомпоновкиДанных.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));



КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоПериода", НачалоДня(Дата(2013,02,05)));
КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("КонецПериода", КонецДня(Дата(2013,03,29)));
КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Организация", Справочники.Организации.НайтиПоНаименованию("Опт"));
КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("СегментНоменклатурыАкция", Справочники.СегментыНоменклатуры.НайтиПоНаименованию("Акция"));
КомпоновщикНастроекКомпоновкиДанных.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("СегментПартнеровАкция", Справочники.СегментыПартнеров.НайтиПоНаименованию("Рабочие"));



СтруктураРаботы.Вставить("КомпоновщикНастроекКомпоновкиДанных",КомпоновщикНастроекКомпоновкиДанных);

СтруктураФайла = Новый Структура;
СтруктураФайла.Вставить("Файлом",Ложь);
СтруктураФайла.Вставить("ТипФайлаТабличногоДокумента",ТипФайлаТабличногоДокумента.HTML4);
СтруктураРаботы.Вставить("СтруктураФайла",СтруктураФайла);

СтруктураПисьма = Новый Структура;
СтруктураПисьма.Вставить("Кому","*****@*********");
СтруктураПисьма.Вставить("Тема","Акция SOX");
//Новый Структура("Кому,Тема,Тело","********@********","График оплат",СтрHTML)
СтруктураРаботы.Вставить("СтруктураПисьма",СтруктураПисьма);
СтруктураРаботы.Вставить("КомпоновщикНастроекКомпоновкиДанныхНастройки",КомпоновщикНастроекКомпоновкиДанных.Настройки);
//ПочтовыеРассылки.СформироватьИОтправитьОтчетПоПочте(СтруктураРаботы);

Задание = РегламентныеЗадания.СоздатьРегламентноеЗадание(Метаданные.РегламентныеЗадания.ПочтовыеРассылкиОтчетов);
Задание.Использование = Ложь;
Задание.Наименование = "Почтовая рассылка Акция";

ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(СтруктураРаботы);
ПараметрыЗадания.Добавить(Новый Структура("КомпоновщикНастроекКомпоновкиДанных",КомпоновщикНастроекКомпоновкиДанных));
Задание.Параметры = ПараметрыЗадания;

Задание.Записать();



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


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

No comments:

Post a Comment