Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с MHTMLBody при работе с CDO
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 7.7
Sharzem
Вся 7.7.

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

Приведу кусок кода оформления тела:

лпИмяФайлHTML = "";
лпКодировка = КодировкаТелаПисьма.ПолучитьЗначение(КодировкаТелаПисьма.ТекущаяСтрока());

Если СтильТелаПисьма.ТекущаяСтрока() = 1 Тогда
    лпСписТеги = СоздатьОбъект("СписокЗначений");
    лпСписТеги.ДобавитьЗначение("<html><head>");
    лпСписТеги.ДобавитьЗначение("<meta content=""text/html; charset="+лпКодировка+""" http-equiv=""content-type"">");
    лпСписТеги.ДобавитьЗначение("<title> Post message </title>");
    лпСписТеги.ДобавитьЗначение("</head> <body> <h2>");
    лпСодержаниеТела = "";
    Для лпНомСтр = 1 По лпКвоСтрок Цикл
        лпСтрока = СокрЛП(СтрПолучитьСтроку(Тело,лпНомСтр));
        лпСодержаниеТела = ?(ПустаяСтрока(лпСодержаниеТела) =1,лпСтрока,лпСодержаниеТела+"<br>"+лпСтрока);
    КонецЦикла;
    лпСписТеги.ДобавитьЗначение(лпСодержаниеТела);
    лпСписТеги.ДобавитьЗначение("<br><p></p></h2>");
    лпФайлКартинки = СокрЛП(ФайлКартинки);
    Если ФС.СуществуетФайл(лпФайлКартинки) = 1 Тогда
        лпСписТеги.ДобавитьЗначение("<h3><img src="+лпФайлКартинки+" width=""265"" height=""32""><br></h3>");
    КонецЕсли;
    лпСписТеги.ДобавитьЗначение("</body></html>");
    
    лпФайлHTML = СоздатьОбъект("Текст");
    Для лпСч = 1 По лпСписТеги.РазмерСписка() Цикл
        лпФайлHTML.ДобавитьСтроку(лпСписТеги.ПолучитьЗначение(лпСч));
    КонецЦикла;
    
    Попытка
        лпИмяФайлHTML = СокрЛП(Каталог)+"\index.html";
        лпФайлHTML.Записать(лпИмяФайлHTML);
        loCdoMessage.CreateMHTMLBody(лпИмяФайлHTML);
    Исключение
        loCdoMessage.TextBody = СокрЛП(Тело);/// Не удалось в HTML - то хоть как-то
    КонецПопытки;
Иначе
    loCdoMessage.TextBody = СокрЛП(Тело);
КонецЕсли;

Попытка
    Состояние("Выполняется отправка сообщения...");
    loCdoMessage.Send();
Исключение
       Сообщить("> Ошибка: "+ОписаниеОшибки());
КонецПопытки;

Если ПустаяСтрока(лпИмяФайлHTML) = 0 Тогда
       ФС.УдалитьФайл(лпИмяФайлHTML);
       ///А ВОТ СДЕСЬ У МЕНЯ ПРОБЛЕМКА///
       Если ФС.СуществуетФайл(лпИмяФайлHTML) = 1 Тогда
               Предупреждение("Ошибка: не удалось удалить файл "+лпИмяФайлHTML);
        КонецЕсли;
КонецЕсли;


Вот собственно и просьба, помогите решить как заставить 1 С "отцепиться" от моего лпИмяФайлHTML и удалить его ?
Vofka
Втулить где-то перед удалением
лпФайлHTML = Неопределено;
Acid
файл может быть еще заблокирован loCdoMessage. Не успел уйти.
Надо проверить состояние
loCdoMessage.Send();

а перед удалением файла надо удалить объект из памяти:
loCdoMessage = "";
Sharzem
Vofka @ Вчера, 15:54 необходимо зарегистрироваться для просмотра ссылки,
Не помогло...
Vofka
Попробуйте ещё обнулить переменную, о которой Acid выше написал. В довесок можно ещё паузу на секунду-другую сделать после обнуления переменных и перед попыткой удаления.
Sharzem
Цитата(Acid @ 28.01.16, 16:08) необходимо зарегистрироваться для просмотра ссылки
Надо проверить состояние


Дописал
loCdoMessage.Send();
Предупреждение("Бла-бла-бла",10);
loCdoMessage = 0;//это ведь равносильно loCdoMessage = "";


Отправил сам себе, получил мгновенно, но подождав пока само Предупреждение через 10 сек закроется мой "\index.html" так и остался занятым 1-Ской.

Как вариант можно создавать новые
 "\index"+лпСчетчик+".html"
, но считаю это непрофессиональным подходом.

Может кто-то сможет мне подсказать как правильно написать тег для непосредственного помещения тела не путем создания файла *.html, а использования атрибута HTMLBody
Vofka
Sharzem, сделайте паузу после обнуления переменной.
Sharzem
Vofka @ Сегодня, 9:24 необходимо зарегистрироваться для просмотра ссылки,
Нет, все равно не помогает.
loCdoMessage.Send();
loCdoMessage = 0;
Предупреждение("Бла-бла-бла",10);
Форма.Закрыть();


Вот, даже после удачной отправки форму закрыл, соответственно все переменные должны сами "обнуляться", но файл так и остался занят....
Благо что ни одна из внешних компонент в программе не используется. Абракадабра какая-то, ничего не понимаю.... 19000000.gif
Acid
если уж речь о профессиональности, то для задачи отправки Сообщения не целесообразно работать через внешний файл. Не используйте его. Лишнее телодвижение.
У вас правильные теги. Генерируйте текст сообщения, пополняя его тегами.
Sharzem
Acid @ Сегодня, 10:59 необходимо зарегистрироваться для просмотра ссылки,
Вот именно что проблема с написанием самих тегов.

Пробовал еще так:
Если ФС.СуществуетФайл(лпФайлКартинки) = 1 Тогда
      лпИмяКартинки = "1.jpg"
      loConfig.Fields.Item("urn:schemas:mailheader:Content-ID").Value = лпИмяКартинки;
      лпСписТеги.ДобавитьЗначение("<br><img src=""cid:"""+лпИмяКартинки+""" width=""265"" height=""32""><br>");
      loConfig.Fields.Update();
      loCdoMessage.AddRelatedBodyPart(лпФайлКартинки, лпИмяКартинки, 1);
КонецЕсли;
лпТекстНТМЛ = "";
Для лпСч = 1 По лпСписТеги.РазмерСписка() Цикл
      лпТекстНТМЛ = лпТекстНТМЛ+лпСписТеги.ПолучитьЗначение(лпСч)+РазделительСтрок;
КонецЦикла;
loCdoMessage.HTMLBody = лпТекстНТМЛ;

В результате тело оформлено в HTML, но сама картинка прицеплена как вложение, а нужно что-бы была теле.
Acid
Ой не то...
Файл картинки надо получить через ФС.
файлКартинки = //полученный файл

лпТекстНТМЛ = "<html><body>";
//пишем текст сообщения:
лпТекстНТМЛ = лпТекстНТМЛ +"<h4>Здравствуйте Дорогие Должники!</h4><br><br>";
//дальше сообщение можно заполнять даже в цикле (например долг по каждому документу)
лпТекстНТМЛ = лпТекстНТМЛ +"<p>Если не заплатите, мы сильно обидимся</p><br>";
лпТекстНТМЛ = лпТекстНТМЛ +"<img>"+файлКартинки+ "</img><br>";
лпТекстНТМЛ = лпТекстНТМЛ +"</body></html>";

loCdoMessage.HTMLBody = лпТекстНТМЛ;

Вот и все.

с картинкой надо поиграться, я работал без них.

Чтоб понять структуру такого сообщения с картинкой, надо в реальном сообщении посмотреть его хтмл-структуру.
Sharzem
Сейчас попробую.
Acid
*забыл закрыть теги...
Sharzem
Во, как...
Ув. Acid, увы не получилось согласно Вашим рекомендациям....
Вы правы были правы только в одном
Цитата
Генерируйте текст сообщения, пополняя его тегами


Добавил такую функцию:
Функция ВернутьСимволыСлеваРазделителя(прСтрока,прРазделитель)
    лпСтрДлина = СтрДлина(прСтрока);
    лпЛевыеСимволы = "";
    Для лпСчетчик = 1 По лпСтрДлина Цикл
        лпЛевыеСимволы = Лев(прСтрока,лпСчетчик);
        Если Найти(лпЛевыеСимволы,прРазделитель) > 0 Тогда
            лпЛевыеСимволы = Лев(прСтрока,лпСчетчик-1);
            Прервать;
        КонецЕсли;
    КонецЦикла;
    Возврат лпЛевыеСимволы;
КонецФункции


В рассматриваемой процедуре:

//............
    лпФайлКартинки = СокрЛП(ФайлКартинки);
    Если ФС.СуществуетФайл(лпФайлКартинки) = 1 Тогда
        лпИмяКартинки = ВернутьСимволыСлеваРазделителя(лпФайлКартинки,"\");
        Если СтрДлина(лпИмяКартинки) > 0 Тогда
            loCdoMessage.AddRelatedBodyPart(лпФайлКартинки, лпИмяКартинки, 0);
            лпСписТеги.ДобавитьЗначение("<img src=""cid:"+лпИмяКартинки+"""><br>");//Решил не устанавливать размеры, дабы не искажать саму картинку, но не могу понять почему работает без объявления тегов.
        КонецЕсли;
    КонецЕсли;
    лпСписТеги.ДобавитьЗначение("</body></html>");
    лпТекстНТМЛ = "";
    Для лпСч = 1 По лпСписТеги.РазмерСписка() Цикл
        лпТекстНТМЛ = лпТекстНТМЛ+лпСписТекст.ПолучитьЗначение(лпСч);
    КонецЦикла;
    loCdoMessage.HTMLBody = лпТекстНТМЛ;
//..............

friends.gif жаль что ради такой ерунды потрачено уйму времени...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.