Как исправить некорректный перенос строк при отправке писем из 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При программном формировании и отправке электронных писем из конфигураций 1С (например, 1С:Управление производственным предприятием) часто возникает проблема, когда список документов или позиций выводится «вразнобой»: некоторые строки переносятся корректно, а другие склеиваются в один сплошной текст. Рассмотрим причинно-следственные связи этой проблемы и разберем эффективные способы ее решения.

Анализ ошибки в коде формирования строки

Проанализируем распространенную ошибку, возникающую при цикловом обходе строк. При добавлении текста к переменной важно соблюдать порядок объединения строк. Посмотрим на некорректный вариант записи:


// Некорректный вариант конкатенации строки
ТекстПисьма = Символы.ВК + ТекстПисьма + " " + Строка(ПодчиненнаяСтрокаДетальныеЗаписи.Документ) + ... + Символы.ВК;

В приведенном фрагменте переменная ТекстПисьма подставляется в середину выражения. На каждом шаге цикла весь ранее накопленный текст переносится внутрь нового выражения, что приводит к сбою структуры и хаотичному расположению переносов. Для исправления этого фрагмента необходимо добавлять новые данные строго в конец накопительной переменной:


// Корректный вариант конкатенации строки
ТекстПисьма = ТекстПисьма + " " + Строка(ПодчиненнаяСтрокаДетальныеЗаписи.Документ) 
    + ТекстСтатусПросрочен + ", инициатор " + Строка(ПодчиненнаяСтрокаДетальныеЗаписи.Инициатор) 
    + ", отправлен " + Строка(ПодчиненнаяСтрокаДетальныеЗаписи.ДатаВозникновения) 
    + Символы.ВК + Символы.ПС;

Особенности работы почтовых клиентов с обычным текстом (Plain Text)

Даже при исправлении логики конкатенации строк текстовые письма большого объема могут отображаться с нарушениями. Это связано с работой алгоритмов почтовых клиентов (в частности, Microsoft Outlook):

  1. Эвристическое склеивание строк: Почтовые программы по умолчанию стараются удалять «лишние» разрывы строк в текстовых сообщениях, объединяя идущие подряд короткие строки в один абзац, если не находят явных знаков препинания или двойного переноса.
  2. Стандарт спецсимволов переноса (CRLF): В протоколе SMTP для корректного переноса требуется парная комбинация спецсимволов Символы.ВК + Символы.ПС (коды ASCII 13 и 10). Использование лишь одного из спецсимволов (только Символы.ВК или только Символы.ПС) может приводить к сбоям на стороне почтового сервера или клиента.

Для предотвращения склеивания строк в формате Plain Text можно использовать разделитель из двух переносов (Символы.ВК + Символы.ПС) * 2 или добавлять символ табуляции Символы.Таб в начале каждой строки списка.

Основное решение: Переход на формат HTML

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

Разберем по шагам, как сформировать письмо в формате HTML:

  1. Используем HTML-теги разрыва строки <br> или параграфы <p> вместо спецсимволов Символы.ВК.
  2. Для оформления списков документов применим HTML-таблицы (теги <table>, <tr>, <td>), что обеспечит ровные колонки.
  3. При вызове функции формирования письма укажем тип текста сообщения как HTML.

Посмотрим на пример кода формирования HTML-письма:


ТекстПисьма = "<html><body style='font-family: Arial; font-size: 12px;'>";
ТекстПисьма = ТекстПисьма + "<h3>Уведомление о документах на утверждение</h3>";

Для Каждого ПодчиненнаяСтрокаВидДокумента Из ПодчиненнаяСтрокаПроект.Строки Цикл
    ТекстПисьма = ТекстПисьма + "<b>" + ПодчиненнаяСтрокаВидДокумента.Группировка + "</b><hr/>";
    
    ТекстПисьма = ТекстПисьма + "<table border='1' cellpadding='4' cellspacing='0'>";
    ТекстПисьма = ТекстПисьма + "<tr bgcolor='#f0f0f0'><td>Документ</td><td>Инициатор</td><td>Дата</td></tr>";
    
    Для Каждого ПодчиненнаяСтрокаДетальныеЗаписи Из ПодчиненнаяСтрокаВидДокумента.Строки Цикл
        ТекстПисьма = ТекстПисьма + "<tr>";
        ТекстПисьма = ТекстПисьма + "<td>" + Строка(ПодчиненнаяСтрокаДетальныеЗаписи.Документ) + "</td>";
        ТекстПисьма = ТекстПисьма + "<td>" + Строка(ПодчиненнаяСтрокаДетальныеЗаписи.Инициатор) + "</td>";
        ТекстПисьма = ТекстПисьма + "<td>" + Строка(ПодчиненнаяСтрокаДетальныеЗаписи.ДатаВозникновения) + "</td>";
        ТекстПисьма = ТекстПисьма + "</tr>";
    КонецЦикла;
    
    ТекстПисьма = ТекстПисьма + "</table><br/>";
КонецЦикла;

ТекстПисьма = ТекстПисьма + "</body></html>";

Использование верстки HTML полностью гарантирует сохранение структуры письма, корректный вывод группировок документов и читаемый вид уведомлений на любых почтовых клиентах и мобильных устройствах.

← На главную