gifts2017

Отправка почты с использованием основного почтового клиента ОС (продолжение)

Опубликовал Дмитрий Семенов (d7k) в раздел Программирование - Практика программирования

В публикации описан фрагмент кода, позволяющий отправлять печатные формы с помощью почтового клиента операционной системы. Дальнейшее развитие публикации http://infostart.ru/public/91206/
Добавлено: 1. Поддержка Mozilla Thunderbird.
2. Автоподстановка адресата письма.

Ознакомился с публикацией http://infostart.ru/public/91206/ уважаемого Администратора1С (http://infostart.ru/profile/138784/), решил улучшить.

После доработки появилась возможность отправлять сообщения при установленном в системе Mozilla Thunderbird и отпала необходимость вручную указывать адресата - адрес используется из профиля контрагента.

Ниже приведены изменения в конфигурации. Тестировалось для 8.2 КА, редакция 1.1 (1.1.31.1).

1. Включить в Конфигураторе возможность изменений (конфигурация - поддержка- настройка поддержки).

2. Добавить общий модуль "_управлениеПочтой", в него скопировать процедуры: "ОтправитьПечатнуюФормуВнешнимТранспортом" и "КорректировкаНаименования" и "Получить получателей2" (приведены ниже см. п. 4).

3. В общем модуле "УправлениеОтчетами" отредактировать процедуру "ОтправитьДокументПоЭлектроннойПочте", закомментировав сообщение и добавив вызов нашей процедуры "ОтправитьПечатнуюФормуВнешнимТранспортом". Редактируемый фрагмент этой процедуры:

    

Если НЕ Константы.ИспользованиеВстроенногоПочтовогоКлиента.Получить() Тогда
        //ОбщегоНазначения.СообщитьОбОшибке("Отправлять документы по электронной почте можно только из встроенного почтового клиента.
        //|В настоящее время в настройках параметров учета установлено использование основного почтового клиента операционной системы.");
        //#Если Клиент Тогда
        //    Предупреждение("Операция не выполнена");
        //#Иначе
        //    Сообщить("Операция не выполнена");
        //#КонецЕсли
        //
        // Начало изменений программиста 19.07.2012г.
        //
        // Получаем список адресатов письма
        //
        СписокПолучателей = Новый СписокЗначений();
        Если ЗначениеЗаполнено(ОбъектПечати) Тогда
            Если ТипЗнч(ОбъектПечати) = Тип("СписокЗначений") Тогда
                Для Каждого ОбъектПечатиЭлементСписка Из ОбъектПечати Цикл
                    Если ЗначениеЗаполнено(ОбъектПечатиЭлементСписка.Значение) Тогда
                        _управлениеПочтой.ПолучитьПолучателей2(ОбъектПечатиЭлементСписка.Значение, СписокПолучателей);
                    КонецЕсли;
                КонецЦикла;
            Иначе
                _управлениеПочтой.ПолучитьПолучателей2(ОбъектПечати, СписокПолучателей);
            КонецЕсли;
            Если СписокПолучателей.Количество() > 0.00 Тогда
                
                Запрос = Новый Запрос();
                Запрос.Текст = "
                |ВЫБРАТЬ РАЗРЕШЕННЫЕ
                |    КонтактнаяИнформация.Объект КАК Объект,
                |    КонтактнаяИнформация.Объект.Наименование КАК НаименованиеОбъекта,
                |    КонтактнаяИнформация.Вид КАК Вид,
                |    КонтактнаяИнформация.Представление КАК Представление,
                |    КонтактнаяИнформация.ЗначениеПоУмолчанию КАК ЗначениеПоУмолчанию
                |ИЗ
                |    РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
                |ГДЕ
                |    КонтактнаяИнформация.Объект В (&СписокПолучателей)
                |    И КонтактнаяИнформация.Тип = &Тип
                |
                |УПОРЯДОЧИТЬ ПО
                |    КонтактнаяИнформация.Объект,
                |    ЗначениеПоУмолчанию УБЫВ
                |ИТОГИ ПО
                |    Объект
                |";
                
                Запрос.УстановитьПараметр("Тип", Перечисления.ТипыКонтактнойИнформации.АдресЭлектроннойПочты);
                Запрос.УстановитьПараметр("СписокПолучателей", СписокПолучателей);
                ВыборкаОбъектыПолучатели = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
                СписокПолучателей.Очистить();
                Пока ВыборкаОбъектыПолучатели.Следующий() Цикл
                    ВыборкаЭлАдресПолучателя = ВыборкаОбъектыПолучатели.Выбрать();
                    Если ВыборкаЭлАдресПолучателя.Следующий() Тогда
                        СписокПолучателей.Добавить(ВыборкаЭлАдресПолучателя.Представление, ВыборкаЭлАдресПолучателя.НаименованиеОбъекта);
                    КонецЕсли;
                КонецЦикла;
            Иначе
                СписокПолучателей.Очистить();
            КонецЕсли;
        КонецЕсли;
        //
        // Приводим список адресатов письма к формату "Строка"
        // 
        Если    ТипЗнч(СписокПолучателей) = Тип("СписокЗначений") Тогда
            ПочтовыйАдресПолучателя = "";
            Для Каждого ЭлементПочтовыйАдрес Из СписокПолучателей Цикл
                Если ЗначениеЗаполнено(ЭлементПочтовыйАдрес.Представление) тогда
                    ПочтовыйАдресПолучателя = ПочтовыйАдресПолучателя
                                            + ЭлементПочтовыйАдрес.Представление
                                            + " <"
                                            + ЭлементПочтовыйАдрес.Значение
                                            + ">; "
                Иначе
                    ПочтовыйАдресПолучателя = ПочтовыйАдресПолучателя 
                                            + ЭлементПочтовыйАдрес.Значение
                                            + "; ";
                КонецЕсли;
            КонецЦикла;
        ИначеЕсли ТипЗнч(СписокПолучателей) = Тип("Строка") Тогда
            ПочтовыйАдресПолучателя = СписокПолучателей;
        КонецЕсли;
        //
        //
        // Вызов альтернативной процедуры отправки почты
        //
        _управлениеПочтой.ОтправитьПечатнуюФормуВнешнимТранспортом(Документ, УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(ПараметрыСеанса.ТекущийПользователь,"ОсновнойКаталогФайлов"),ИмяФайлаВложения,ПочтовыйАдресПолучателя);
        //
        // изменения программиста конец
        Возврат;
    КонецЕсли;

 

4. Текст модуля     _управлениеПочтой:

 

 

Процедура ОтправитьПечатнуюФормуВнешнимТранспортом (ПолеТабличногоДокумента, КаталогФормирования="",имяФайлаВложения,строкаАдресаты) Экспорт 

  Расширение="xls";

   Файл = Новый Файл(КаталогФормирования);
   Если Файл.Существует() Тогда
      ИмяФайла = КаталогФормирования;
   Иначе
     ИмяФайла = КаталогВременныхФайлов();
   КонецЕсли;

  Если Не ПустаяСтрока(ИмяФайла) Тогда
    Если Не Прав(ИмяФайла, 1) = "\" Тогда
      ИмяФайла = ИмяФайла + "\";
    КонецЕсли;
  КонецЕсли;

   ОтносительноеИмя =КорректировкаНаименования(имяФайлаВложения,ложь); 
   ИмяФайлаБезРасширения = ИмяФайла + ОтносительноеИмя;

   ИмяФайла = ИмяФайлаБезРасширения + ".xls";
   ПолеТабличногоДокумента.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLS97);

   ПутьМозиллы = "C:/Program Files/Mozilla Thunderbird/thunderbird.exe";
   КаталогМозиллы = """C:/Program Files/Mozilla Thunderbird""";
   Мозилла = Новый Файл(ПутьМозиллы);
   Если Не Мозилла.Существует() Тогда
       ПутьМозиллы = "C:/Program Files (x86)/Mozilla Thunderbird/thunderbird.exe";
       КаталогМозиллы = """C:/Program Files (x86)/Mozilla Thunderbird""";
       Мозилла = Новый Файл(ПутьМозиллы);
   КонецЕсли;
   Если Мозилла.Существует() Тогда
       Текст = Новый ЗаписьТекста(КаталогВременныхФайлов() + "sendfile"+".bat", КодировкаТекста.OEM);
       Текст.ЗаписатьСтроку("@echo off");
       Текст.ЗаписатьСтроку("@echo Отправка почты");
       Текст.ЗаписатьСтроку("cd " + КаталогМозиллы);
       СтрокаЗапуска = "to='"+строкаАдресаты+"',subject='"+имяФайлаВложения+"',body='',attachment='"+ИмяФайла+"'";
       СтрокаЗапуска = """" + СтрокаЗапуска + """";
       СтрокаЗапуска = " -compose " + СтрокаЗапуска;
       Текст.ЗаписатьСтроку("thunderbird.exe"+СтрокаЗапуска);
       Текст.ЗаписатьСтроку("del " + КаталогВременныхФайлов() + "sendfile" + ".bat");
       Текст.Закрыть();
       ЗапуститьПриложение(КаталогВременныхФайлов()+"sendfile"+".bat",КаталогВременныхФайлов());
   Иначе
       Почта=Новый Почта;
       Почта.Подключиться();
       Сообщ=Новый ПочтовоеСообщение;
       Сообщ.Получатели.Добавить(строкаАдресаты);
       Сообщ.Тема=имяФайлаВложения;
       Сообщ.Текст="";
       ВыбФайл=Новый Файл(ИмяФайла);
       Если ВыбФайл.Существует() Тогда
           Данные=Новый ДвоичныеДанные(ИмяФайла);
           Сообщ.Вложения.Добавить(Данные,ВыбФайл.Имя);
       КонецЕсли;
       Почта.Послать(Сообщ,);
       Почта.Отключиться();
       
       Попытка
           УдалитьФайлы(ИмяФайла);
           Сообщить("Удален файл "+ИмяФайла);
       Исключение
           Сообщить(ОписаниеОшибки());
       КонецПопытки;
       
   КонецЕсли;

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


Функция КорректировкаНаименования(Знач ИсходнаяСтрока, Выводитьсообщения=Истина) 

    Наименование=СокрЛП(ИсходнаяСтрока);    
   ДлиннаНаим=СтрДлина(Наименование);
   СписокЗаменяемыхимволов=новый СписокЗначений;

     Если ДлиннаНаим=0 Тогда
        Сообщение="Не заполнена проверяемая строка!";
       #Если Клиент Тогда
            Если Выводитьсообщения Тогда
                Сообщить(Сообщение);
           КонецЕсли;
      #КонецЕсли 

     КонецЕсли; 
    Для i=0 По ДлиннаНаим-1 Цикл  
          Стр=Прав(Наименование,ДлиннаНаим-i);  
         // руск. алф. 192- 255 англ. алф. мал. 65-90 англ. алф. бол. 97-122 пробел=32 цифры АSCI дес.
        Если (((КодСимвола(Стр)>1039)и(КодСимвола(Стр)64)и(КодСимвола(Стр)96)и(КодСимвола           (Стр)47)и(КодСимвола(Стр)32)) Тогда
        Иначе
         СписокЗаменяемыхимволов.Добавить(Лев(Стр,1));
       КонецЕсли;
   КонецЦикла;

  Для каждого ЭлементСписка Из СписокЗаменяемыхимволов Цикл
  Если ЭлементСписка.Значение=" " Тогда
  Наименование=СтрЗаменить(Наименование,ЭлементСписка.Значение,"_");
  Сообщение="В наименование колонки "+ИсходнаяСтрока+" встречается недопустимый символ (пробел) "+ЭлементСписка.Значение+", он будет заменен на '_'";
  #Если Клиент Тогда
  Если Выводитьсообщения Тогда
  Сообщить(Сообщение);
  КонецЕсли;
  #КонецЕсли 
  Иначе
  Наименование=СтрЗаменить(Наименование,ЭлементСписка.Значение,""); 
  Сообщение="В наименование колонки "+ИсходнаяСтрока+" встречается недопустимый символ "+ЭлементСписка.Значение+", он будет удален";
  #Если Клиент Тогда
  Если Выводитьсообщения Тогда
  Сообщить(Сообщение);
  КонецЕсли;
 #КонецЕсли     
   КонецЕсли
   КонецЦикла;
   Возврат Наименование;    
КонецФункции

Процедура ПолучитьПолучателей2(ПараметрОбъектПечати, СписокПолучателей) Экспорт
    
    Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(ПараметрОбъектПечати))
            И ПараметрОбъектПечати.Метаданные().Реквизиты.Найти("Контрагент") <> Неопределено
    Тогда
        СписокПолучателей.Добавить(ПараметрОбъектПечати.Контрагент);
    Иначе
        Если ТипЗнч(ПараметрОбъектПечати) = Тип("СправочникСсылка.КонтактныеЛица")
            ИЛИ ТипЗнч(ПараметрОбъектПечати) = Тип("СправочникСсылка.ФизическиеЛица")
            ИЛИ ТипЗнч(ПараметрОбъектПечати) = Тип("СправочникСсылка.Пользователи")
            ИЛИ ТипЗнч(ПараметрОбъектПечати) = Тип("СправочникСсылка.КонтактныеЛицаКонтрагентов")
            ИЛИ ТипЗнч(ПараметрОбъектПечати) = Тип("СправочникСсылка.Контрагенты")
            ИЛИ ТипЗнч(ПараметрОбъектПечати) = Тип("СправочникСсылка.Организации")
            ИЛИ ТипЗнч(ПараметрОбъектПечати) = Тип("СправочникСсылка.ЛичныеКонтакты")
        Тогда
            СписокПолучателей.Добавить(ПараметрОбъектПечати);
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры // ПолучитьПолучателей2()

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Ийон Тихий (cool.vlad4) 27.03.13 17:09
куча кода...за качество судить не берусь, но хотя бы то, что используется конкретный путь к буревестнику, уже говорит, что в половине случаев работать не будет. Путь к птичке есть в реестре. Это точно, а иначе как птичку запускает mailto:
2. Доржи Балбаров (Angeros) 28.03.13 04:14
Все здорово. Но попробуйте оформить код чтобы он подсвечивался не как текст.
3. Дмитрий Семенов (d7k) 28.03.13 09:57
2 cool.vlad4:
Системный вызов mailto: из 1С 8.2 КА в случае Mozilla Thunderbird почему-то не работает. 1С игнорирует птичку, вызывая MS Outlook Express. Я применил вызов почтового клиента из командной строки с передачей параметров в виде аргументов. Командная строка MS сурова и беспощадна - ей понятнее путь вида C:\PROGRA~1\MOZILL~3\. Многочисленные эксперименты к успеху не привели. Остановился на том, что есть. Проверено - работает на W7 (x86 и x64). Если кто-то найдет решение - я только за.

2 Angeros:
Это моя первая публикация. Раскрашка я так понял не бесплатна.
"А чтобы продать что-нибудь ненужное, надо купить что-нибудь ненужное, а у нас денег нет" (С) дядя Федор
5. Илья Ткаченко (tka4enk0) 28.03.13 22:08
+ Как раз нужна была идея отправки через консоль.
Пробовал через blat но что-то не взлетел. Завтра попробую через Mozilla Thunderbird...
6. Антон Стеклов (asved.ru) 03.04.13 17:26
Вообще-то существует такая вещь, как CDO. просто не нужно путать процесс отправки почты и процесс сохранения сообщения в отправленных почтового клиента. Это может с успехом сделать почтовый сервер по IMAP, к примеру.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа