Вдохнем вторую жизнь во встроенный почтовый клиент из 1С:Управление торговлей 10.3

25.12.18

Функциональные - Управление взаимоотношениями с клиентами (CRM)

Хотели было воспользоваться почтовым клиентом из Управление торговлей 10.3, да не тут-то было. К сожалению, фирма "1С" почти совсем ее забросила и если Ваш респондент отправляет Вам письма, содержащие HTML, то Вас ждут матюки... Ну что же, как говорится: "Спасение утопающих - дело рук самих утопающих".

Недавно возникла необходимость воспользоваться почтовым клиентом в Управление торговлей 10.3. Собирались получать письма из почтового ящика на Яндексе. Новый почтовый ящик - на нем лежало-то всего-ничего - пара писем от Яндекса с благодарностью за регистрацию. И каково же было удивление когда выяснилось, что даже эти несчастные письма мы получить не можем. Если письма содержали HTML то попытка получения этих писем приводила к ошибке:

{ОбщийМодуль.УправлениеЭлектроннойПочтой.Модуль(205)}: Метод объекта не обнаружен (tags)
        ТегиКартинок = НовыйHTMLДокумент.all.tags("img");
 

Если погуглить данную ошибку, то в ответ тишина. О ней рапортуют на разных форумах, но решений так и нет.

В результате не мудрствуя лукаво (возможно у кого-то будет более красивое решение) отключил код с ошибкой. В модуле "УправлениеЭлектроннойПочтой" в процедуре "УстановитьТекстПисьма" закомментировал кусок кода и вставил под ним строку для обхода:

//НовыйHTMLДокумент = Новый COMОбъект("HtmlFile");
//НовыйHTMLДокумент.open("text/html");
//НовыйHTMLДокумент.write(ХТМЛ_Текст);
//НовыйHTMLДокумент.close();
//ТегиКартинок = НовыйHTMLДокумент.all.tags("img");
//Для а = 0 По ТегиКартинок.length - 1 Цикл
//	ИсточникКартинки = ТегиКартинок.item(а).src;
//	Если Найти(ИсточникКартинки, "cid:") = 1 Тогда
//		ИсточникКартинки = Сред(ИсточникКартинки, 5);
//		ТегиКартинок.item(а).src = ИсточникКартинки;
//	КонецЕсли;
//КонецЦикла;
//ПисьмоОбъект.ТекстПисьма = НовыйHTMLДокумент.all.tags("html").item(0).outerHTML;
ПисьмоОбъект.ТекстПисьма = ХТМЛ_Текст;

На этом дело не закончилось. При попытке просмотра некоторых писем вываливалось аналогичное сообщение об ошибке:

{ОбщийМодуль.УправлениеЭлектроннойПочтой.Модуль(3095)}: Поле объекта не обнаружено (innerText)
    Возврат СтрЗаменить(НовыйHTMLДокумент.all.item(0).innerText, Символ(13), "");
 

Тут на помощь нам приходит более современная конфигурация УНФ, разработчикам которой есть дело до того как в ней работает встроенный почтовый клиент. Все в том же модуле "УправлениеЭлектроннойПочтой" в процедуре "ПреобразоватьТекстИзХТМЛФорматаВПростой" закомментировал кусок кода и вставил под ним строки для обхода:

//НовыйHTMLДокумент = Новый COMОбъект("HtmlFile");
//НовыйHTMLДокумент.open("text/html");
//НовыйHTMLДокумент.write(ТекстВФорматеХТМЛ);
//НовыйHTMLДокумент.close();
	
//Возврат СтрЗаменить(НовыйHTMLДокумент.all.item(0).innerText, Символ(13), "");

ПереводСтроки = Символы.ВК + Символы.ПС;

ТекстВФорматеХТМЛ = СтрЗаменить(ТекстВФорматеХТМЛ, "</o:p>", "</o:p>" + ПереводСтроки);
ТекстВФорматеХТМЛ = СтрЗаменить(ТекстВФорматеХТМЛ, "</o:p>" + ПереводСтроки + ПереводСтроки, "</o:p>" + ПереводСтроки);
ТекстВФорматеХТМЛ = СтрЗаменить(ТекстВФорматеХТМЛ, "</p>", "</p>" + ПереводСтроки);
ТекстВФорматеХТМЛ = СтрЗаменить(ТекстВФорматеХТМЛ, "</p>" + ПереводСтроки + ПереводСтроки, "</p>" + ПереводСтроки);
ТекстВФорматеХТМЛ = СтрЗаменить(ТекстВФорматеХТМЛ, "</div>", "</div>" + ПереводСтроки);
ТекстВФорматеХТМЛ = СтрЗаменить(ТекстВФорматеХТМЛ, "</div>" + ПереводСтроки + ПереводСтроки, "</div>" + ПереводСтроки);
ТекстВФорматеХТМЛ = СтрЗаменить(ТекстВФорматеХТМЛ, "<br>", ПереводСтроки + ПереводСтроки);

Построитель = Новый ПостроительDOM;
ЧтениеHTML = Новый ЧтениеHTML;
ЧтениеHTML.УстановитьСтроку(ТекстВФорматеХТМЛ);

ДокументHTML = Построитель.Прочитать(ЧтениеHTML);

УдалитьТегиИзЭлементаHTML(ДокументHTML, "style");

Если ДокументHTML.Тело = Неопределено Тогда
	Возврат "";
КонецЕсли;

Возврат ДокументHTML.Тело.ТекстовоеСодержимое;

И добавить процедуру:

Процедура УдалитьТегиИзЭлементаHTML(ЭлементHTML, Тег)
	
	Для каждого Узел Из ЭлементHTML.ДочерниеУзлы Цикл
		Если НРег(Узел.ИмяУзла) = НРег(Тег) Тогда
			ЭлементHTML.УдалитьДочерний(Узел);
		Иначе
			// Рекурсия
			УдалитьТегиИзЭлементаHTML(Узел, Тег);
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

Я же вообще вставил туда вызов функции "ПолучитьТекстИзHTML" из модуля "Гипертекст" из последних релизов УНФ. Подумалось что может еще что-нибудь оттуда пригодится. Правда придется немного обработать его "напильником" (дело в том что там активно используются новые функции "СтрШаблон" и "Найти").

Так как организация, для которой это делалось, активно использовала механизм событий (собственно из-за чего и начался весь сырбор с интеграцией почты в 1С) то само собой возник вопрос почему документ "Электронное письмо" не тождественен событию. Так например в той же УНФ разрабы реализовали электронное письмо как один из вариантов события (т.е. у них нет в принципе такой отдельной от события сущности как "Электронное письмо").

Вообщем в итоге решили генерировать документы "Событие" при отправке и получении электронных писем. Для создания документа "Событие" при отправки электронного письма все в том же модуле "УправлениеЭлектроннойПочтой" в процедуре "ПолучениеОтправкаПисем" добавил кусок кода:

НовоеСобытие = Документы.Событие.СоздатьДокумент();
Если (Письма <> Неопределено) И (Письма.Получить(Письмо) <> Неопределено) Тогда
	НовоеСобытие.Заполнить(Письма[Письмо].Ссылка);
Иначе
	НовоеСобытие.Заполнить(Письмо.Ссылка);
КонецЕсли;
НовоеСобытие.Дата				= ТекущаяДата();
НовоеСобытие.ТипСобытия			= Перечисления.ВходящееИсходящееСобытие.Исходящее;
НовоеСобытие.СостояниеСобытия	= Перечисления.СостоянияСобытий.Завершено;
НовоеСобытие.Записать(РежимЗаписиДокумента.Проведение);

Вставить его нужно сразу после кода отправки:

 

Аналогично для создания документа "Событие" при получении электронного письма все в том же модуле "УправлениеЭлектроннойПочтой" в той же процедуре "ПолучениеОтправкаПисем" добавил кусок кода:

НовоеСобытие = Документы.Событие.СоздатьДокумент();
НовоеСобытие.Заполнить(Письмо.Ссылка);
НовоеСобытие.Дата				= Письмо.ДатаОтправления;
НовоеСобытие.ТипСобытия			= Перечисления.ВходящееИсходящееСобытие.Входящее;
НовоеСобытие.СостояниеСобытия	= Перечисления.СостоянияСобытий.Завершено;
НовоеСобытие.Записать(РежимЗаписиДокумента.Проведение);

Вставить его нужно сразу после кода получения:

 

Сразу хочу заметить что поле "СодержаниеСобытия" не заполнялось нами по просьбе заказчика. Предполагается что там не будет содержаться текст электронного письма, а будут вноситься пометки менеджерами характеризующие кратко суть написанного.

Если же Вы решите не идти путем автоматического дублирования событий на основе электронных писем, но все же вводить события на основании будете интерактивно Вы наткнетесь на те же грабли:

{Документ.Событие.МодульОбъекта(416)}: Поле объекта не обнаружено (innerText)
        НовоеСобытие.Заполнить(ЭлементыФормы.ЭлектронныеПисьмаСписок.ТекущиеДанные.Ссылка);
 

Соответственно идем в модуль объекта документа "Событие" в процедуру "ОбработкаЗаполнения", комментируем кусок кода и вставляем под ним строку для обхода (при условии конечно что Вы вносили в него правки, которые я приводил во втором фрагменте кода):

//НовыйHTMLДокумент = Новый COMОбъект("HtmlFile");
//НовыйHTMLДокумент.open("text/html");
//НовыйHTMLДокумент.write(ДокОснование.ТекстПисьма);
//НовыйHTMLДокумент.close();
//СодержаниеСобытия = СтрЗаменить(НовыйHTMLДокумент.all.item(0).innerText, Символ(13), "");
СодержаниеСобытия = УправлениеЭлектроннойПочтой.ПреобразоватьТекстИзХТМЛФорматаВПростой(ДокОснование.ТекстПисьма);

Итак, друзья мои, кто осилил дочитать до этого места не буду Вас больше утомлять кодом настало время картинок :)

Решили что гораздо красивее внешний вид формы обработки "Менеджер контактов" (именно она отображает почту) будет выглядеть (мониторы то нонче у всех широкие):

Вместо типового вида (который как в ширину не тяни - все равно ни списка писем толком не видно, да и само письмо отображается куцо):

Последние манипуляции с формой выполнялись при помощи активно используемого мною механизма программной модификации формы. Если очень коротко, то суть в том, что программно осуществляются действия по добавлению новых, изменению имеющихся элементов формы, установка событий и привязок. Список действий хранится в справочнике "Команды модификации форм". Визуально настройки для этой формы выглядят так:

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

P.S. Все вышесказанное справедливо (тестировалось) на Управление торговлей 10.3.35.1 и 10.3.40.1 но думаю что будет работать плюс минус десяток версий т.к. туда давненько никто из 1С не лазил.

встроенный почтовый клиент письма в формате HTML

См. также

Взаиморасчеты Email рассылки Акт сверки Бухгалтер Пользователь Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бухгалтерский учет Платные (руб)

Внешняя обработка для Бухгалтерии 3.0 - позволяет автоматически формировать документы «Акт сверки расчетов» с контрагентами за выбранный период с последующей фоновой отправкой на почту контрагента.

3000 руб.

25.11.2020    24055    225    8    

194

Управление взаимоотношениями с клиентами (CRM) Оптовая торговля Розничная торговля Пользователь Платформа 1С v8.3 Оперативный учет Управляемые формы 1С:Управление торговлей 10 1С:Розница 2 Россия Управленческий учет Платные (руб)

Подсистема призвана упростить и автоматизировать процесс расчета и начисления бонусов покупателей. Бонусная система работает с конфигурациями 1С:УТ 10.3, 1С:Розница. Механизм реализован в начале 2013г. и работает до сих пор с постоянными совершенствованиями.

30000 руб.

02.11.2015    111844    99    87    

182

Рабочее место Управление взаимоотношениями с клиентами (CRM) Оптовая торговля Розничная торговля Пользователь Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

Данная обработка - удобный инструмент в 1С для менеджеров по продажам для повседневной работы с клиентами. Позволяет упростить весь цикл работы с клиентом: первичная консультация по наличию товара, быстрое оформление нового заказа, контроль исполнения заказов. Обработка будет особенно актуальна для компаний, работающих, в основном, с юридическими лицами.

18000 руб.

08.11.2016    60935    39    22    

61

Email рассылки Программист Пользователь Платформа 1С v8.3 Конфигурации 1cv8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Платные (руб)

Решение для массовой рассылки печатных форм (в том числе и дополнительных) любых документов, и произвольных файлов. Рассылка возможна посредством электронной почты, Telegram и файловой системы. Рассылка пакета документов. Добавление факсимильных печати и подписи. Произвольные шаблоны HTML/Simple text с автозаполнением любыми полями документа. Любые форматы файлов. Упаковка вложений в архив. Транслитерация имен файлов. Разбиение рассылки на произвольные порции. Обход спам-фильтров. Журналирование рассылок.

4920 руб.

30.06.2022    10630    70    94    

32
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. lunjio 67 25.12.18 06:02 Сейчас в теме
Ну уж если вдыхаете вторую жизнь, давайте сделаем и возможность получения писем с любых почтовых серверов, по любым протоколам. У меня есть внешняя база на 8.3, которая работает как прослойка, она принимает данные с УТ 10.3, в виде - данные для авторизации, дата начала получения писем, возвращает на клиент идентификаторы писем, там стандартной процедурой по уже полученным письмам отсекаются полученные, затем по оставшимся не имеющимся идентификаторам идет получение писем. В этой конфигурации - проводнике, получение идет по протоколу IMAP, засчет чего работают фильтры, при этом при наличии большого количества писем в ящике, проблема деградации по времени получения отпадает. На днях выложу конфигурацию, если кому интересно, обмен правда происходит через веб-сервисы.
Nikola_N; +1 Ответить
3. 1c.pro.fun 188 25.12.18 09:55 Сейчас в теме
(1) Безусловно было бы интересно посмотреть - выкладывайте. Думаю что работа по IMAP будет востребована тем у кого "старые" ящики. Мне было бы интересно посмотреть.
2. 1c-intelligence 12844 25.12.18 08:29 Сейчас в теме
Вдохнем вторую жизнь во ...

с этой фразы, наверное, начинается карьера некромантов :)
4. nyam-nyam 25.12.18 10:35 Сейчас в теме
(2)Да ладно, если 7.7 ещё живёт и по слухам 6 даже где-то... 1С стоит старые версии OpenSource в перевести, вдруг заживёт усилиями энтузиастов. И будут на форумах спрашивать какой форк УТ лучше поставить... :)
5. ice-net 19 26.12.18 08:59 Сейчас в теме
(4) Кто тогда будет покупать новые?
6. nyam-nyam 26.12.18 09:25 Сейчас в теме
(5)Те же кто покупает прочий коммерческий софт.
7. RustIG 1729 15.02.19 09:03 Сейчас в теме
при получении писем база сильно разрастается - я в свое время сразу отказался от этой идеи - и теперь я использую ут 10.3 только для оперативной отправки счетов и заказов, для приемки писем не использую. поэтому проблем с тегами ни разу не испытывал. ставлю + за рассмотрение проблемы.
8. 1c.pro.fun 188 15.02.19 10:07 Сейчас в теме
(7) В случае этого клиента один из трендов создание на базе УТ 10.3 полноценной CRM системы. Основные признаки уже налицо - телефонные звонки принимаются прямо в базе и автоматически регистрируются в событиях... Потому переписка по электронной почте (по сути ведь тоже события) должна в базу падать... понятно что с переходом в такой режим работы база будет пухнуть :( но тут боюсь ничего не поделаешь.
9. Andrey01012016 25.05.20 17:34 Сейчас в теме
Подсажите, а почему у меня не получилось? УТ 10.3.61.2 8.3.15.1656 {ОбщийМодуль.УправлениеЭлектроннойПочтой.Модуль(3175)}: Поле объекта недоступно для записи (ТекстПисьма)
ТекстВФорматеХТМЛ = СтрЗаменить(ТекстВФорматеХТМЛ, "</o:p>", "</o:p>" + ПереводСтроки);
Оставьте свое сообщение