Процедура УведомлениеГотовности() Экспорт
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ
| рдУведомлениеГотовности.ОтчетПроизводства КАК ОтчетПроизводства,
| ЗаказНаПроизводствоПродукция.Заказ.Ссылка КАК ЗаказПокупателя
|ИЗ
| РегистрСведений.рдУведомлениеГотовности КАК рдУведомлениеГотовности
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ВыпускПродукции КАК ВыпускПродукции
| ПОЛНОЕ СОЕДИНЕНИЕ Документ.ЗаказНаПроизводство.Продукция КАК ЗаказНаПроизводствоПродукция
| ПО ВыпускПродукции.Заказ.Ссылка = ЗаказНаПроизводствоПродукция.Ссылка
| ПО рдУведомлениеГотовности.ОтчетПроизводства = ВыпускПродукции.Регистратор
|ГДЕ
| рдУведомлениеГотовности.Отправлено = ЛОЖЬ
| И рдУведомлениеГотовности.Обработано = ЛОЖЬ";
ТЗ = Запрос.Выполнить().Выгрузить();
ТЗ.Сортировать("ЗаказПокупателя Возр,ОтчетПроизводства Убыв");
Заказ="";
Для каждого Строчка из ТЗ Цикл
Если Заказ <> Строчка.ЗаказПокупателя Тогда
Заказ = Строчка.ЗаказПокупателя;
Если НЕ ПустаяСтрока(Строчка.ОтчетПроизводства) Тогда
//ТЗ1 = Запрос.Выполнить().Выгрузить().ВыбратьСтроку();
рдОбработкаПроведенияОтчетПроизводстваЗаСменуРассылкаУведомленийГотовности(Строчка.ОтчетПроизводства);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура рдОбработкаПроведенияОтчетПроизводстваЗаСменуРассылкаУведомленийГотовности(Источник) Экспорт
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ссылка",Источник);
Запрос.УстановитьПараметр("Услуга","Услуга");
Запрос.УстановитьПараметр("ПустойОтчет",Документы.ОтчетПроизводстваЗаСмену.ПустаяСсылка());
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ
| ЗаказНаПроизводствоПродукция.Заказ.Ссылка КАК ЗаказПокупателя
|ПОМЕСТИТЬ ТЕМП
|ИЗ
| РегистрНакопления.ВыпускПродукции КАК ВыпускПродукции
| ПОЛНОЕ СОЕДИНЕНИЕ Документ.ЗаказНаПроизводство.Продукция КАК ЗаказНаПроизводствоПродукция
| ПО ВыпускПродукции.Заказ.Ссылка = ЗаказНаПроизводствоПродукция.Ссылка
|ГДЕ
| ВыпускПродукции.Регистратор.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ЗаказыПокупателей.Номенклатура КАК Номенклатура,
| ЗаказыПокупателей.ХарактеристикаНоменклатуры КАК Характеристика,
| ЗаказыПокупателей.Количество КАК КолЗаказ,
| 0 КАК КолВыпуск,
| &ПустойОтчет КАК Выпуск,
| ТЕМП.ЗаказПокупателя КАК Заказ
|ПОМЕСТИТЬ ТЗЗаказ
|ИЗ
| РегистрНакопления.ЗаказыПокупателей КАК ЗаказыПокупателей
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТЕМП КАК ТЕМП
| ПО ЗаказыПокупателей.Регистратор = ТЕМП.ЗаказПокупателя
|ГДЕ
| ЗаказыПокупателей.Номенклатура.ВидНоменклатуры.Наименование <> &Услуга
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ВыпускПродукции.Продукция,
| ВыпускПродукции.ХарактеристикаПродукции,
| 0 КАК КолЗаказ,
| ВыпускПродукции.Количество КАК КолВыпуск,
| ВыпускПродукции.Регистратор КАК Выпуск,
| ЗаказНаПроизводствоПродукция.Заказ.Ссылка КАК Заказ
|ПОМЕСТИТЬ ТЗВыпуск
|ИЗ
| РегистрНакопления.ВыпускПродукции КАК ВыпускПродукции
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЗаказНаПроизводство.Продукция КАК ЗаказНаПроизводствоПродукция
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТЕМП КАК ТЕМП
| ПО ЗаказНаПроизводствоПродукция.Заказ.Ссылка = ТЕМП.ЗаказПокупателя.Ссылка
| ПО ВыпускПродукции.Заказ.Ссылка = ЗаказНаПроизводствоПродукция.Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТЗЗаказ.Номенклатура КАК Номенклатура,
| ТЗЗаказ.Характеристика КАК Характеристика,
| ТЗЗаказ.КолЗаказ КАК КолЗаказ,
| ТЗВыпуск.КолВыпуск КАК КолВыпуск,
| ТЗВыпуск.Выпуск КАК Выпуск,
| ТЗЗаказ.Заказ КАК Заказ
|ИЗ
| ТЗЗаказ КАК ТЗЗаказ
| ЛЕВОЕ СОЕДИНЕНИЕ ТЗВыпуск КАК ТЗВыпуск
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ОтчетПроизводстваЗаСмену КАК ОтчетПроизводстваЗаСмену
| ПО ТЗВыпуск.Выпуск = ОтчетПроизводстваЗаСмену.Ссылка
| ПО ТЗЗаказ.Номенклатура = ТЗВыпуск.Продукция
| И ТЗЗаказ.Характеристика = ТЗВыпуск.ХарактеристикаПродукции";
//ТЗ = Запрос.Выполнить().Выгрузить().ВыбратьСтроку();
//Возврат;
Выборка = Запрос.Выполнить().Выбрать();
Отсылать = Ложь;
Пока Выборка.Следующий() Цикл
Если (Выборка.КолВыпуск = Выборка.КолЗаказ) И (Выборка.КолЗаказ<>0) Тогда
Отсылать = Истина;
иначе
Отсылать = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Результат = Ложь;
Если Отсылать Тогда
//Результат = Истина;
Результат = ОтправитьУведомление(Выборка.Заказ,Источник);
КонецЕсли;
СтрокаРегистра = РегистрыСведений.рдУведомлениеГотовности.СоздатьМенеджерЗаписи();
СтрокаРегистра.ОтчетПроизводства = Источник;
СтрокаРегистра.Отправлено = Результат;
СтрокаРегистра.Обработано = Истина;
Попытка
СтрокаРегистра.Записать();
Исключение
КонецПопытки;
КонецПроцедуры
Функция ОтправитьУведомление(Документ,ОтчетПр)
ДокОбъект = Документ.ПолучитьОбъект();
//Удалим pdf и flg оставшийся с прошлого раза
ИмяФайла = "1c_notify.pdf";
ПолноеИмяФайла = КаталогВременныхФайлов() + ИмяФайла;
УдалитьФайлы(ПолноеИмяФайла);
ИмяФлага = "1c_notify.flg";
ПолноеИмяФлага = КаталогВременныхФайлов() + ИмяФлага;
УдалитьФайлы(ПолноеИмяФлага);
ПрофильЭлектроннойПочты = ПолучитьПрофильЭлектроннойПочты();
Если ПрофильЭлектроннойПочты = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
АдресНазначения = ксОбщийМодуль.ПолучитьПочтуПоСотруднику(ДокОбъект.ксОсновнойИнженерКонсультант);
Если ПустаяСтрока(АдресНазначения) Тогда
ЗаписьЖурналаРегистрации("Не указан email у " + ДокОбъект.ксОсновнойИнженерКонсультант + ". Отправка сообщений указанному получателю не возможна!", УровеньЖурналаРегистрации.Ошибка, , ,"Уведомление");
Возврат Ложь;
КонецЕсли;
//Создадим новое письмо на указаный адрес
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Отправитель = "1c@ridan.ru";
Письмо.ИмяОтправителя = "ЗАО Ридан (отдел отгрузки)";
Письмо.Получатели.Добавить(АдресНазначения);
Письмо.Получатели.Добавить("ryuchin_a@ridan.ru");
Письмо.Тема = "Уведомление о готовности";
Письмо.Тексты.Добавить(Строка(ОтчетПр) + "
|Уведомление об готовности выпуска для " + ДокОбъект.Контрагент + " по счету " + СокрЛП(ДокОбъект.Ссылка.Номер) + " от " + Формат(ДокОбъект.Ссылка.Дата, "ДФ=dd.MM.yy") + " находится во вложении");
ПолноеИмяФайла = ФайлВложенияЙоксель(ДокОбъект,ОтчетПр);
Письмо.Вложения.Добавить(ПолноеИмяФайла, "Уведомление о готовности");
ИПочта = Новый ИнтернетПочта;
Попытка
ИПочта.Подключиться(ПрофильЭлектроннойПочты);
ИПочта.Послать(Письмо);
ИПочта.Отключиться();
ЗаписьЖурналаРегистрации("Уведомление об готовности выпуска для " + ДокОбъект.Контрагент + " по счету " + СокрЛП(ДокОбъект.Ссылка.Номер) + " от " + Формат(ДокОбъект.Ссылка.Дата, "ДФ=dd.MM.yy") + " отправлено " + ДокОбъект.ксОсновнойИнженерКонсультант, УровеньЖурналаРегистрации.Информация, , ,"Уведомление");
//ЗаписьЖурналаРегистрации("Удалить "+ПолноеИмяФайла, УровеньЖурналаРегистрации.Информация, , ,"Уведомление");
//УдалитьФайлы(ПолноеИмяФайла);
Возврат Истина;
Исключение
ЗаписьЖурналаРегистрации("Необходимо проверить настройки электронной почты! Отправка невозможна! (" + ОписаниеОшибки() + ")", УровеньЖурналаРегистрации.Ошибка, , ,"Уведомление");
Возврат Ложь;
КонецПопытки;
КонецФункции
Функция ПолучитьПрофильЭлектроннойПочты()
ПрофильПочты = Новый ИнтернетПочтовыйПрофиль;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("УчетнаяЗапись", Константы.ксУчетнаяЗаписьЭлектроннойПочты.Получить());
Запрос.Текст =
"ВЫБРАТЬ
| УчетныеЗаписиЭлектроннойПочты.SMTPСервер,
| УчетныеЗаписиЭлектроннойПочты.ПортSMTP,
| УчетныеЗаписиЭлектроннойПочты.ЛогинSMTP,
| УчетныеЗаписиЭлектроннойПочты.ПарольSMTP,
| УчетныеЗаписиЭлектроннойПочты.ТребуетсяSMTPАутентификация,
| УчетныеЗаписиЭлектроннойПочты.АдресЭлектроннойПочты,
| УчетныеЗаписиЭлектроннойПочты.Логин,
| УчетныеЗаписиЭлектроннойПочты.Пароль,
| УчетныеЗаписиЭлектроннойПочты.ВремяОжиданияСервера
|ИЗ
| Справочник.УчетныеЗаписиЭлектроннойПочты КАК УчетныеЗаписиЭлектроннойПочты
|ГДЕ
| УчетныеЗаписиЭлектроннойПочты.Ссылка = &УчетнаяЗапись";
Результат = Запрос.Выполнить();
ЭлектроннаяПочта = Результат.Выбрать();
Если ЭлектроннаяПочта.Следующий() Тогда
Если ЭлектроннаяПочта.ТребуетсяSMTPАутентификация Тогда
ПрофильПочты.АутентификацияSMTP = СпособSMTPАутентификации.Login;
ПрофильПочты.ПользовательSMTP = ЭлектроннаяПочта.ЛогинSMTP;
ПрофильПочты.ПарольSMTP = ЭлектроннаяПочта.ПарольSMTP;
Иначе
ПрофильПочты.АутентификацияSMTP = СпособSMTPАутентификации.ПоУмолчанию;
КонецЕсли;
ПрофильПочты.АдресСервераSMTP = ЭлектроннаяПочта.SMTPСервер;
ПрофильПочты.ПортSMTP = ЭлектроннаяПочта.ПортSMTP;
ПрофильПочты.ВремяОжидания = ЭлектроннаяПочта.ВремяОжиданияСервера;
Возврат ПрофильПочты;
Иначе
ЗаписьЖурналаРегистрации("Не удалось получить учетную запись электронной почты - Отправка сообщений не возможна!", УровеньЖурналаРегистрации.Ошибка, , ,"Уведомление");
Возврат Неопределено;
КонецЕсли;
КонецФункции
Функция ПечатьУведомления(СсылкаНаОбъект,ОтчетПр)
НомерПечать = ОбщегоНазначения.ПолучитьНомерНаПечать(СсылкаНаОбъект);
ТабДокумент = Новый ТабличныйДокумент;
ТабДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_УВЕДОМЛЕНИЕ_ОБ_ОТГРУЗКЕ";
Макет = ПолучитьОбщийМакет("УведомлениеГотовности");
Обл = Макет.ПолучитьОбласть("Шапка");
Обл.Параметры.Заголовок = "Уведомление о готовности к отгрузке " + НомерПечать + " от " + Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy");
Обл.Параметры.Плательщик = "Плательщик: " + СсылкаНаОбъект.Контрагент.Наименование;
Обл.Параметры.Уведомление = "Информируем Вас, что оборудование по Счету №" + НомерПечать + " от " + Формат(СсылкаНаОбъект.Дата, "ДФ=dd.MM.yyyy") + Символы.ПС + "готово к отгрузке по следующим позициям:";
ТабДокумент.Вывести(Обл);
НомерСтроки = 1;
Обл = Макет.ПолучитьОбласть("Строка");
Для Каждого ТекСтрока ИЗ СсылкаНаОбъект.Товары Цикл
Обл.Параметры.НомерСтроки = НомерСтроки;
Обл.Параметры.Товар = ТекСтрока.Номенклатура.НаименованиеПолное + ", расчет " + ТекСтрока.ксРасчет;
Обл.Параметры.Единица = ТекСтрока.ЕдиницаИзмерения;
Обл.Параметры.Количество = ТекСтрока.Количество;
Обл.Параметры.ДатаОтгрузки = Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy");
//Обл.Параметры.ДатаОтгрузки = Формат(ОтчетПр.Дата, "ДФ=dd.MM.yyyy");
ТабДокумент.Вывести(Обл);
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
Обл = Макет.ПолучитьОбласть("Подвал");
Обл.Параметры.УсловияПоставки = СсылкаНаОбъект.ДополнениеКАдресуДоставки;
ТабДокумент.Вывести(Обл);
ТабДокумент.АвтоМасштаб = Истина;
ТабДокумент.ИмяПринтера = "1c_notifyer";
Возврат ТабДокумент;
КонецФункции
Функция ФайлВложенияЙоксель(пСтр,ОтчетПр)
ИмяФайла = "1c_notify.pdf";
ПолноеИмяФайла = КаталогВременныхФайлов() + ИмяФайла;
ИмяФлага = "1c_notify.flg";
ПолноеИмяФлага = КаталогВременныхФайлов() + ИмяФлага;
//СтруктураПараметров = новый структура("ИмяФайла",ПолноеИмяФайла);
ТабДокумент = ПечатьУведомления(пСтр.Ссылка,ОтчетПр);
ПолноеИмяФайла = Йоксель_СохранитьОтчётВПДФ(ТабДокумент,ПолноеИмяФайла);
УдалитьФайлы(ПолноеИмяФлага);
Возврат ПолноеИмяФайла;
КонецФункции
// Функция формирует файлы для отправки по электронной почте с помощью внешней компоненты Yoksel.dll
//
Функция Йоксель_СохранитьОтчётВПДФ(ТабДок, ИмяФайла)//Путь)
Попытка
//ЗагрузитьВнешнююКомпоненту(КаталогПрограммы() + "Yoksel.dll");
Йоксель = ПолучитьCOMОбъект("","Йоксель");
КонвертерPDF = Йоксель.СоздатьГрафическийКонвертерPDF();
Исключение
ЗаписьЖурналаРегистрации(ОписаниеОшибки(), УровеньЖурналаРегистрации.Ошибка, , ,"Уведомление");
//Предупреждение("Не удалось загрузить внешнюю компоненту Yoksel! Сообщите администратору системы!", 20);
Возврат Неопределено;
КонецПопытки;
ТабДок.Записать(КаталогВременныхФайлов()+ "1c_notify.xls", ТипФайлаТабличногоДокумента.XLS97);
// Конвертируем временный файл в формат pdf
Попытка
Таб = Йоксель.СоздатьТабличныйДокумент();
Таб.Открыть(КаталогВременныхФайлов()+ "1c_notify.xls", "2");
КонвертерPDF.Документ = Таб;
КонвертерPDF.КоличествоБитНаПиксел = 24; //1, 4, 8, 24
//КонвертерPDF.ПолеСлева = 1134; // в твипах (1 твип = 1/567 см)
КонвертерPDF.ЗаписатьВФайл(ИмяФайла);
Исключение
УдалитьФайлы(КаталогВременныхФайлов()+ "1c_notify.xls");
ЗаписьЖурналаРегистрации(ОписаниеОшибки(), УровеньЖурналаРегистрации.Ошибка, , ,"Уведомление");
//Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
Возврат Неопределено;
КонецПопытки;
Печать в PDF в фоновом режиме через регламентные задания 1с 8.2 с помощью Yoksel.dll на х64 сервере
12.09.11
Учетные задачи - Логистика, склад и ТМЦ
Была поставлена задача автоматической рассылки документов на почтовые ящики ответственных лиц.
Был опробован виртуальный принтер PDFСreator - результат отрицательный.
Фоновый режим рассылки документов сервером осуществлен с помощью внешней компоненты Yoksel.dll, которая была зарегистрирована на х32 1с-сервере с помощью команды regsvr32 Yoksel.dll
Ниже приведенные процедуры созданы в общем модуле.
Ссылки на документы, печатные формы которых необходимо разослать ответственным лицам накапливаютя в регистре сведений рдУведомлениеГотовности.
В процедурах показана сама идея автоматического формирования PDF-документов на сервере 1с. Если 1с-сервер х64, то в кластер вносится х32 1с сервер и создается рабочий процесс, в который автоматически перекочевывает фоновое задание и Йоксель запускается и работает физически на х32 сервере.
Был опробован виртуальный принтер PDFСreator - результат отрицательный.
Фоновый режим рассылки документов сервером осуществлен с помощью внешней компоненты Yoksel.dll, которая была зарегистрирована на х32 1с-сервере с помощью команды regsvr32 Yoksel.dll
Ниже приведенные процедуры созданы в общем модуле.
Ссылки на документы, печатные формы которых необходимо разослать ответственным лицам накапливаютя в регистре сведений рдУведомлениеГотовности.
В процедурах показана сама идея автоматического формирования PDF-документов на сервере 1с. Если 1с-сервер х64, то в кластер вносится х32 1с сервер и создается рабочий процесс, в который автоматически перекочевывает фоновое задание и Йоксель запускается и работает физически на х32 сервере.