diff --git a/src/content/docs/knowledge-base/Примеры, сниппеты/БСП и типовые/Работа с почтой/Блочное формирование HTML-писем.md b/src/content/docs/knowledge-base/Примеры, сниппеты/БСП и типовые/Работа с почтой/Блочное формирование HTML-писем.md
new file mode 100644
index 0000000..696944a
--- /dev/null
+++ b/src/content/docs/knowledge-base/Примеры, сниппеты/БСП и типовые/Работа с почтой/Блочное формирование HTML-писем.md
@@ -0,0 +1,756 @@
+
+```bsl
+#Область ПрограммныйИнтерфейс
+
+// Функция - Сообщение HTML
+//
+// Параметры:
+// Заголовок - Строка - Строка, которая будет отображаться в шапке письма крупным шрифтом
+// МассивБлоковHTMLСообщения - Массив Из Строка - Массив строк, сформированных функциями "БлокHMTLСообщения_..."
+// ПараметрыОформления - Структура - см. ПараметрыОформленияHTMLСообщения. Если неопределено создаются параметры по умолчанию
+//
+// БлокОбъектов = Новый Массив;
+// // Абзац
+// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_Абзац("Скажи-ка, дядя, ведь<>%$"""" ' недаром, Москва..." + Символы.ПС + "tot;ladkflasdhkf;as"));
+//
+// // Абзац с гиперссылкой
+// ПараметрыГиперссылки = Новый Соответствие;
+// ПараметрыГиперссылки.Вставить("с гиперссылкой", "https://www.google.com");
+// ПараметрыГиперссылки.Вставить("еще одной", "https://www.google.com");
+// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_АбзацСГиперссылками("Абзацы можно добавлять [с гиперссылкой] и, если хочется, [еще одной]. Количество не ограничено", ПараметрыГиперссылки));
+//
+// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_Абзац("Так будет выглядеть список. Формируется из массива"));
+//
+// // Список пунктов
+// МассивПунктов = Новый Массив;
+// МассивПунктов.Добавить("Пункт 1");
+// МассивПунктов.Добавить("Пункт 2");
+//
+// МассивПодпунктов = Новый Массив;
+// МассивПодпунктов.Добавить("Подпункт 1");
+// МассивПодпунктов.Добавить("Подпункт 2");
+//
+// МассивПодпунктов1 = Новый Массив;
+// МассивПодпунктов1.Добавить("Подпункт 1");
+// МассивПодпунктов1.Добавить("Подпункт 2");
+// МассивПодпунктов.Добавить(МассивПодпунктов1);
+//
+// МассивПунктов.Добавить(МассивПодпунктов);
+// МассивПунктов.Добавить("Пункт 3");
+//
+// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_СписокНенумерованный(МассивПунктов));
+//
+// // В результате такая структура
+// // Пункт 1
+// // Пункт 2
+// // Подпункт 1
+// // Подпункт 2
+// // Подпункт 1
+// // Подпункт 2
+// // Пункт 3
+//
+//
+// // Таблица
+// ТЗ = Новый ТаблицаЗначений;
+// ТЗ.Колонки.Добавить("НомерПоПорядку", , "№", 5); // ширину задаем, если нужна разная ширина колонок
+// ТЗ.Колонки.Добавить("Номенклатура");
+// ТЗ.Колонки.Добавить("Характеристика");
+// ТЗ.Колонки.Добавить("Количество", , "Кол-во" , 10);
+//
+// НоваяСтрока = ТЗ.Добавить();
+// НоваяСтрока.НомерПоПорядку = "1";
+// НоваяСтрока.Номенклатура = "Номенклатура 1";
+// НоваяСтрока.Характеристика = "";
+// НоваяСтрока.Количество = 10;
+//
+// НоваяСтрока = ТЗ.Добавить();
+// НоваяСтрока.НомерПоПорядку = "2";
+// НоваяСтрока.Номенклатура = "Номенклатура 2";
+// НоваяСтрока.Характеристика = "с характеристикой";
+// НоваяСтрока.Количество = "15";
+//
+// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_Таблица(ТЗ));
+//
+// // Цитата
+// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_Цитата("Это цитата"));
+//
+// Результат = ОбработкаОбъект.СообщениеHTML("Добрый день", БлокОбъектов);
+// Возвращаемое значение:
+// Строка - сообщение, оформленное в HTML
+//
+Функция СообщениеHTML(Заголовок, МассивБлоковHTMLСообщения, ПараметрыОформления = Неопределено) Экспорт
+
+ Шаблон = ШаблонHTMLСообщения(ПараметрыОформления);
+
+ ПараметрыЗаполнения = Новый Структура("ТелоСообщения", СтрСоединить(МассивБлоковHTMLСообщения, Символы.ПС));
+ ПараметрыЗаполнения.Вставить("Заголовок", НормализованныйТекстДляHTML(Заголовок));
+
+ Результат = СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, ПараметрыЗаполнения);
+
+ Возврат Результат;
+
+КонецФункции
+
+// Функция - Параметры оформления HTMLСообщения. Содержит значения плейсхолдеров инлайновых стилей CSS в шаблоне.
+// Обязательны все для формирования работы метода СообщениеHTML.
+//
+// Возвращаемое значение:
+// Структура -
+// ТелоЦветЗаднегоФона - Строка - background. По умолчанию "rgb(245, 245, 245)"
+// ТелоШрифт - Строка - font-family. По умолчанию "Arial, sans-serif"
+//
+// АбзацВнутреннийОтступ - Строка - padding. По умолчанию "2px"
+// АбзацРазмерШрифта - Строка - font-size. По умолчанию "14px"
+// АбзацМежстрочныйИнтервал - Строка - line-height. По умолчанию "1.6"
+// АбзацЦветТекста - Строка - color. По умолчанию "rgb(51, 51, 51)"
+// АбзацВнешнийОтступ - Строка - margin. По умолчанию "5px"
+//
+// КонтейнерВнешнийОтступ - Строка - margin. По умолчанию "40px"
+// КонтейнерЦветФона - Строка - background. По умолчанию "rgb(255, 255, 255)"
+// КонтейнерВнутреннийОтступ - Строка - padding. По умолчанию "20px"
+// КонтейнерСкругление - Строка - border-radius. По умолчанию "6px"
+// КонтейнерТень - Строка - box-shadow. По умолчанию "0 2px 4px rgba(0, 0, 0, 0.1)"
+//
+// ЗаголовокЦветТекста - Строка - color. По умолчанию "rgb(118, 34, 40)"
+// ЗаголовокВнутреннийОтступ - Строка - padding. По умолчанию "0px"
+// ЗаголовокВнешнийОтступ - Строка - margin. По умолчанию "10px"
+//
+// КонтентШирина - Строка - width. По умолчанию "1000"
+// КонтентВнутреннийОтступ - Строка - padding. По умолчанию "5px"
+// КонтентРазмерШрифта - Строка - font-size. По умолчанию "14px"
+// КонтентМежстрочныйИнтервал - Строка - line-height. По умолчанию "1.6"
+// КонтентЦветТекста - Строка - color. По умолчанию "rgb(51, 51, 51)"
+//
+// ТаблицаШирина - Строка - width. По умолчанию "960". ВНИМАНИЕ, Всегда указывайте как строковое представление числа, без "px, em" и пр.
+// ТаблицаВнешнийОтступ - Строка - margin. По умолчанию "10px"
+// ЯчейкаГраница - Строка - border. По умолчанию "1px solid rgb(204, 204, 204)"
+// ТаблицаЦветФонаЗаголовка - Строка - background. По умолчанию "rgb(230, 230, 230)"
+// ТаблицаЦветТекстаЗаголовка - Строка - color. По умолчанию "rgb(118, 34, 40)"
+//
+// СсылкаЦветТекста - Строка - color. По умолчанию "rgb(118, 34, 40)"
+// СсылкаЦветФона - Строка - background. По умолчанию "rgb(249, 249, 249)"
+//
+// ЦитатаВнутреннийОтступ - Строка - padding. По умолчанию "10px"
+// ЦитатаЦветФона - Строка - background. По умолчанию "rgb(249, 249, 249)"
+// ЦитатаГраницаСлева - Строка - border-left. По умолчанию "4px solid rgb(118, 34, 40)"
+//
+// ПодвалОтступСверху - Строка - padding-top. По умолчанию "20px"
+// ПодвалРазмерШрифта - Строка - font-size. По умолчанию "11px"
+// ПодвалЦветТекста - Строка - color. По умолчанию "rgb(119, 119, 119)"
+//
+Функция ПараметрыОформленияHTMLСообщения() Экспорт
+
+
+ ПараметрыОформления = Новый Структура;
+
+ ПараметрыОформления.Вставить("ТелоЦветЗаднегоФона", "rgb(245, 245, 245)");
+ ПараметрыОформления.Вставить("ТелоШрифт", "Arial, sans-serif");
+
+ ПараметрыОформления.Вставить("АбзацВнутреннийОтступ", "2px");
+ ПараметрыОформления.Вставить("АбзацРазмерШрифта", "14px");
+ ПараметрыОформления.Вставить("АбзацМежстрочныйИнтервал", "1.6");
+ ПараметрыОформления.Вставить("АбзацЦветТекста", "rgb(51, 51, 51)");
+ ПараметрыОформления.Вставить("АбзацВнешнийОтступ", "5px");
+
+ ПараметрыОформления.Вставить("КонтейнерВнешнийОтступ", "40px");
+ ПараметрыОформления.Вставить("КонтейнерЦветФона", "rgb(255, 255, 255)");
+ ПараметрыОформления.Вставить("КонтейнерВнутреннийОтступ", "20px");
+ ПараметрыОформления.Вставить("КонтейнерСкругление", "6px");
+ ПараметрыОформления.Вставить("КонтейнерТень", "0 2px 4px rgba(0, 0, 0, 0.1)");
+
+ ПараметрыОформления.Вставить("ЗаголовокЦветТекста", "rgb(118, 34, 40)");
+ ПараметрыОформления.Вставить("ЗаголовокВнутреннийОтступ", "0px");
+ ПараметрыОформления.Вставить("ЗаголовокВнешнийОтступ", "10px");
+
+ ПараметрыОформления.Вставить("КонтентШирина", "1000");
+ ПараметрыОформления.Вставить("КонтентВнутреннийОтступ", "5px");
+ ПараметрыОформления.Вставить("КонтентРазмерШрифта", "14px");
+ ПараметрыОформления.Вставить("КонтентМежстрочныйИнтервал", "1.6");
+ ПараметрыОформления.Вставить("КонтентЦветТекста", "rgb(51, 51, 51)");
+
+ ПараметрыОформления.Вставить("ТаблицаШирина", "960");
+ ПараметрыОформления.Вставить("ТаблицаВнешнийОтступ", "10px auto");
+ ПараметрыОформления.Вставить("ЯчейкаГраница", "1px solid rgb(204, 204, 204)");
+ ПараметрыОформления.Вставить("ТаблицаЦветФонаЗаголовка", "rgb(230, 230, 230)");
+ ПараметрыОформления.Вставить("ТаблицаЦветТекстаЗаголовка", "rgb(118, 34, 40)");
+
+ ПараметрыОформления.Вставить("СсылкаЦветТекста", "rgb(118, 34, 40)");
+ ПараметрыОформления.Вставить("СсылкаЦветФона", "rgb(249, 249, 249)");
+
+ ПараметрыОформления.Вставить("ЦитатаВнутреннийОтступ", "10px");
+ ПараметрыОформления.Вставить("ЦитатаЦветФона", "rgb(249, 249, 249)");
+ ПараметрыОформления.Вставить("ЦитатаГраницаСлева", "4px solid rgb(118, 34, 40)");
+
+ ПараметрыОформления.Вставить("ПодвалОтступСверху", "20px");
+ ПараметрыОформления.Вставить("ПодвалРазмерШрифта", "11px");
+ ПараметрыОформления.Вставить("ПодвалЦветТекста", "rgb(119, 119, 119)");
+
+ Возврат ПараметрыОформления;
+
+КонецФункции
+
+// Функция - Блок HTMLСообщения заголовок
+//
+// Параметры:
+// ТекстЗаголовка - Строка - Текст, выводимый в блоке
+// Уровень - Число - уровень заголовка от 1 до 6. Рекомендуется использовать от 2 до 4.
+// ПараметрыОформления - Структура - см. ПараметрыОформленияHTMLСообщения
+//
+// Возвращаемое значение:
+// Строка - Блок вида
+//
+Функция БлокHTMLСообщения_Заголовок(ТекстЗаголовка, Уровень = 2, ПараметрыОформления = Неопределено) Экспорт
+
+ Если ПараметрыОформления = Неопределено Тогда
+ ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
+ КонецЕсли;
+
+ Если Уровень < 1 Или Уровень > 6 Тогда
+ Уровень = 2;
+ КонецЕсли;
+
+ ШаблонЗаголовка = "%2
+ |";
+ Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонЗаголовка,
+ Формат(Уровень, "ЧДЦ=0; ЧГ="),
+ НормализованныйТекстДляHTML(ТекстЗаголовка));
+
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Результат, ПараметрыОформления);
+
+КонецФункции
+
+// Функция - Блок HTMLСообщения абзац
+//
+// Параметры:
+// ТекстАбзаца - Строка - Текст, который будет выведен в абзаце
+// ПараметрыОформления - Структура, Неопределено - см. ПараметрыОформленияHTMLСообщения().
+// Нормализовать - Булево - Служебный, определяет необходимость экранирования спец.символов
+//
+// Возвращаемое значение:
+// Строка - Блок вида Текст
+//
+Функция БлокHTMLСообщения_Абзац(ТекстАбзаца, ПараметрыОформления = Неопределено, Нормализовать = Истина) Экспорт
+
+ Если ПараметрыОформления = Неопределено Тогда
+ ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
+ КонецЕсли;
+
+ Результат = СтрШаблон("%1
+ |",
+ ?(Нормализовать, НормализованныйТекстДляHTML(ТекстАбзаца), ТекстАбзаца));
+
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Результат, ПараметрыОформления);
+
+КонецФункции
+
+// Функция - Абзац сообщения с гиперссылками
+//
+// Параметры:
+// ШаблонАбзаца - Строка - Шаблон вида "Нажмите [на эту ссылку], чтобы узнать больше". [на эту ссылку] - ключ соответствия СписокСсылок
+// СписокСсылок - Соответствие -
+// * Ключ - Строка - представление ссылки в письме. Т.е. ключ "на эту ссылку" заменит строку "[на эту ссылку]" в шаблоне
+// * Значение - Строка - ссылка для вставки
+// ПараметрыОформления - Структура, Неопределено - см. ПараметрыОформленияHTMLСообщения(). Если неопределено создаются параметры по умолчанию
+//
+// Возвращаемое значение:
+// Строка - Блок вида Текст до ссылки Представление ссылки Текст после ссылки
+//
+Функция БлокHTMLСообщения_АбзацСГиперссылками(Знач ШаблонАбзаца, СписокСсылок, ПараметрыОформления = Неопределено) Экспорт
+
+ Если ПараметрыОформления = Неопределено Тогда
+ ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
+ КонецЕсли;
+
+ ШаблонАбзаца = НормализованныйТекстДляHTML(ШаблонАбзаца);
+
+ Для Каждого КлючЗначение Из СписокСсылок Цикл
+
+ Ключ = КлючЗначение.Ключ;
+ Значение = КлючЗначение.Значение;
+
+ СсылкаДляВставки = СтрШаблон("%2",
+ Значение,
+ Ключ);
+
+ ШаблонАбзаца = СтрЗаменить(ШаблонАбзаца,
+ СтрШаблон("[%1]", Ключ),
+ СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(СсылкаДляВставки, ПараметрыОформления));
+
+ КонецЦикла;
+
+ Возврат БлокHTMLСообщения_Абзац(ШаблонАбзаца, ПараметрыОформления, Ложь);
+
+КонецФункции
+
+// Функция - Список ненумерованный
+//
+// Параметры:
+// МассивЗначений - Массив Из Строка, Массив Из Массив - Список элементов. Если нужен иерархический список, то добавляем не строку, а новый массив строк
+// Например, для массива [Привет, Вася, Как, Дела] будет сформирован список
+// * Привет
+// * Вася
+// * Как
+// * Дела
+// Если в этом массиве будет еще один, то список получится иерархический, Например
+// для массива [Привет, Вася, Как, Дела, [Все, Хорошо]]
+// * Привет
+// * Вася
+// * Как
+// * Дела
+// ** Все
+// ** Хорошо
+//
+// Возвращаемое значение:
+// Строка -
+//
+Функция БлокHTMLСообщения_СписокНенумерованный(МассивЗначений, ПараметрыОформления = Неопределено) Экспорт
+
+ Если ПараметрыОформления = Неопределено Тогда
+ ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
+ КонецЕсли;
+
+ Текст = "";
+
+ СформироватьСписокНенумерованныйHTMLРекурсивно(МассивЗначений, Текст, ПараметрыОформления);
+
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Текст, ПараметрыОформления);
+
+КонецФункции
+
+// Функция - Блок HTMLСообщения цитата
+//
+// Параметры:
+// ТекстЦитаты - Строка - Выводимый текст
+// ПараметрыОформления - Структура, Неопределено - см. ПараметрыОформленияHTMLСообщения(). Если неопределено создаются параметры по умолчанию
+//
+// Возвращаемое значение:
+// Строка - Блок, оформленный в виде цитаты
+//
+Функция БлокHTMLСообщения_Цитата(ТекстЦитаты, ПараметрыОформления = Неопределено) Экспорт
+
+
+ Если ПараметрыОформления = Неопределено Тогда
+ ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
+ КонецЕсли;
+
+ Шаблон = "
+ |
+ |
+ | %1
+ | |
+ |
+ |
";
+
+ Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, НормализованныйТекстДляHTML(ТекстЦитаты));
+
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Результат, ПараметрыОформления);
+
+
+КонецФункции
+
+// Функция - Блок HTMLСообщения таблица
+//
+// Параметры:
+// ТаблицаЗначений - ТаблицаЗначений - Выводимая таблица. Если не заполнен заголовок, в шапке будет выведено имя,
+// если не заполнена ширина, то устанавливается ширина по умолчанию
+//
+// Возвращаемое значение:
+// Строка - Таблица в HTML
+//
+Функция БлокHTMLСообщения_Таблица(ТаблицаЗначений, ПараметрыОформления = Неопределено) Экспорт
+
+
+ Если ПараметрыОформления = Неопределено Тогда
+ ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
+ КонецЕсли;
+
+ ОбщаяШиринаТаблицыСтрокой = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыОформления, "ТаблицаШирина", "960");
+ ОбщаяШиринаТаблицы = Число(ОбщаяШиринаТаблицыСтрокой);
+
+ ЗначениеШириныКолонок = АбсолютнаяШиринаКолонок(ТаблицаЗначений, ОбщаяШиринаТаблицы);
+
+ // Устанавливаем абсолютные значения ширины колонок
+ Для Каждого ЗначениеШирины Из ЗначениеШириныКолонок Цикл
+ ТаблицаЗначений.Колонки[ЗначениеШирины.Колонка].Ширина = ЗначениеШирины.ШиринаПикселей;
+ КонецЦикла;
+
+ // Подготавливаем заголовок таблицы
+ ДанныеЯчеекЗаголовкаТаблицы = Новый Массив;
+ Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
+ ТекстЗаполнения = ?(ЗначениеЗаполнено(Колонка.Заголовок), Колонка.Заголовок, Колонка.Имя);
+ ДанныеЯчеекЗаголовкаТаблицы.Добавить(ЯчейкаЗаголовкаТаблицыHTML(ТекстЗаполнения, Колонка.Ширина));
+ КонецЦикла;
+
+ Заголовок = ЗаголовокТаблицыHTML(ДанныеЯчеекЗаголовкаТаблицы);
+
+ // Подготавливаем строки
+ ДанныеСтрокТаблицы = Новый Массив;
+ Для Каждого Строка Из ТаблицаЗначений Цикл
+
+ ДанныеЯчеекСтроки = Новый Массив;
+ Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
+ ДанныеЯчеекСтроки.Добавить(ЯчейкаСтрокиОсновныхДанныхHTML(Строка[Колонка.Имя], Колонка.Ширина));
+ КонецЦикла;
+
+ ДанныеСтрокТаблицы.Добавить(СтрокаТаблицыHTML(ДанныеЯчеекСтроки));
+
+ КонецЦикла;
+
+ Таблица = ТаблицаHTML(Заголовок, ДанныеСтрокТаблицы);
+
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Таблица, ПараметрыОформления);
+
+
+КонецФункции
+
+#КонецОбласти
+
+#Область СлужебныйПрограммныйИнтерфейс
+
+Функция ШаблонHTMLСообщения(ПараметрыОформления = Неопределено) Экспорт
+
+ Если ПараметрыОформления = Неопределено Тогда
+ ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
+ КонецЕсли;
+
+ Шаблон =
+ "
+ |
+ |
+ |
+ | HTML Email
+ |
+ |
+ // Основной контейнер
+ |
+ |
+ |
+ // Обертка
+ |
+ |
+ |
+ // Начало контента
+ |
+ |
+ |
+ | [Заголовок]
+ | [ТелоСообщения]
+ | |
+ |
+ //
+ // Отчерк
+ |
+ | |
+ |
+ |
+ | |
+ |
+ // Конец отчерка
+ //
+ // Подпись и лого (insert base64 to src img)
+ |
+ |
+ | Это письмо сформировано автоматически. Пожалуйста, не отвечайте на него.
+ | |
+ |
+ |
+ |
+ |
+ | |
+ |
+ // Конец подписи и лого
+ |
+ // Конец контента
+ | |
+ |
+ |
+ | |
+ |
+ |
+ |
+ |";
+
+ Результат = СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, ПараметрыОформления);
+
+ Возврат Результат;
+
+КонецФункции
+
+// Функция - Нормализованный текст для HTML. Исплользуется в методах "БлокHTMLСообщения_.."
+//
+// Параметры:
+// Текст - Строка -
+//
+// Возвращаемое значение:
+// Строка - Текст с экранированными спец.символами
+//
+Функция НормализованныйТекстДляHTML(Знач Текст) Экспорт
+
+ Текст = СтрЗаменить(Текст, "&", "&");
+ Текст = СтрЗаменить(Текст, "<", "<");
+ Текст = СтрЗаменить(Текст, ">", ">");
+ Текст = СтрЗаменить(Текст, """", """);
+ Текст = СтрЗаменить(Текст, "'", "'");
+
+ Текст = СтрЗаменить(Текст, Символы.ПС, "
");
+ Текст = СтрЗаменить(Текст, Символы.ВК, "
");
+ Текст = СтрЗаменить(Текст, Символы.Таб, " ");
+
+ Возврат Текст;
+
+КонецФункции
+
+#КонецОбласти
+
+#Область СлужебныеПроцедурыИФункции
+
+Процедура СформироватьСписокНенумерованныйHTMLРекурсивно(МассивЗначений, ТекстHTML = Неопределено, ПараметрыОформления = Неопределено)
+
+ Если ТекстHTML = Неопределено Тогда
+ ТекстHTML = "";
+ КонецЕсли;
+
+ Если ПараметрыОформления = Неопределено Тогда
+ ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
+ КонецЕсли;
+
+ ТекстHTML = ТекстHTML
+ + СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(НачалоНенумерованногоСпискаHTML(), ПараметрыОформления)
+ + Символы.ПС;
+
+ Для Каждого ЭлементМассива Из МассивЗначений Цикл
+
+ Если ТипЗнч(ЭлементМассива) = Тип("Массив") Тогда
+ СформироватьСписокНенумерованныйHTMLРекурсивно(ЭлементМассива, ТекстHTML, ПараметрыОформления);
+ Иначе
+ ТекстHTML = ТекстHTML + ЭлементНенумерованногоСпискаHTML(ЭлементМассива) + Символы.ПС;
+ КонецЕсли
+
+ КонецЦикла;
+
+ ТекстHTML = ТекстHTML + "" + Символы.ПС;
+
+КонецПроцедуры
+
+Функция НачалоНенумерованногоСпискаHTML()
+ Возврат "";
+КонецФункции
+
+Функция ЭлементНенумерованногоСпискаHTML(ТекстЗаполнения)
+
+
+ Шаблон = "-
+ | [ТекстЗаполнения]
+ |
";
+
+ НормализованныйТекст = НормализованныйТекстДляHTML(ТекстЗаполнения);
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, Новый Структура("ТекстЗаполнения", НормализованныйТекст));
+
+
+КонецФункции
+
+Функция ТаблицаHTML(СтрокаЗаголовкаТаблицы, ДанныеСтрокТаблицы)
+
+ Шаблон =
+ "
+ |
+ |
+ | [СтрокаЗаголовкаТаблицы]
+ |
+ |
+ | [ДанныеСтрокТаблицы]
+ |
+ |
+ |
+ |";
+
+ ТекстЗаполненияСтрокТаблицы = СтрСоединить(ДанныеСтрокТаблицы, Символы.ПС);
+
+ ПараметрыЗаполнения = Новый Структура;
+ ПараметрыЗаполнения.Вставить("СтрокаЗаголовкаТаблицы", СтрокаЗаголовкаТаблицы);
+ ПараметрыЗаполнения.Вставить("ДанныеСтрокТаблицы", ТекстЗаполненияСтрокТаблицы);
+
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, ПараметрыЗаполнения);
+
+
+КонецФункции
+
+Функция ЗаголовокТаблицыHTML(ДанныеЯчеекЗаголовка)
+
+ Шаблон = "
+ | [ДанныеЯчеекЗаголовкаТаблицы]
+ |
";
+
+ ДанныеЗаполнения = Новый Структура;
+ ДанныеЗаполнения.Вставить("ДанныеЯчеекЗаголовкаТаблицы", СтрСоединить(ДанныеЯчеекЗаголовка, Символы.ПС));
+
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, ДанныеЗаполнения);
+
+КонецФункции
+
+Функция ЯчейкаЗаголовкаТаблицыHTML(ТекстЗаголовка, ШиринаКолонкиПикселей)
+
+ ТекстЗаполнения = НормализованныйТекстДляHTML(ТекстЗаголовка);
+
+ Шаблон = "
+ | [ТекстЗаполнения]
+ | | ";
+
+ ПараметрыЗаполнения = Новый Структура;
+ ПараметрыЗаполнения.Вставить("ШиринаКолонкиПикселей", Формат(ШиринаКолонкиПикселей, "ЧДЦ=0; ЧГ="));
+ ПараметрыЗаполнения.Вставить("ТекстЗаполнения", ТекстЗаполнения);
+
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, ПараметрыЗаполнения);
+
+КонецФункции
+
+Функция СтрокаТаблицыHTML(ДанныеЯчеекСтрокиТаблицы)
+
+ Шаблон = "
+ | [ДанныеЯчеекСтрокиТаблицы]
+ |
";
+
+ ТекстЗаполнения = СтрСоединить(ДанныеЯчеекСтрокиТаблицы, Символы.ПС);
+
+ Результат = СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, Новый Структура("ДанныеЯчеекСтрокиТаблицы", ТекстЗаполнения));
+
+ Возврат Результат;
+
+КонецФункции
+
+Функция ЯчейкаСтрокиОсновныхДанныхHTML(ТекстЯчейки, ШиринаКолонкиПикселей)
+
+ ТекстЗаполнения = НормализованныйТекстДляHTML(ТекстЯчейки);
+
+ Шаблон = "
+ | [ЗначениеЯчейкиСтрокиТаблицы]
+ | | ";
+ ПараметрыЗаполнения = Новый Структура;
+ ПараметрыЗаполнения.Вставить("ШиринаКолонкиПикселей", Формат(ШиринаКолонкиПикселей, "ЧДЦ=0; ЧГ="));
+ ПараметрыЗаполнения.Вставить("ЗначениеЯчейкиСтрокиТаблицы", ТекстЗаполнения);
+
+ Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, ПараметрыЗаполнения);
+
+КонецФункции
+
+Функция АбсолютнаяШиринаКолонок(ТаблицаЗначений, ОбщаяШирина)
+
+ Колонки = Новый Массив;
+ Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
+ Колонки.Добавить(Новый Структура("Колонка, Ширина", Колонка.Имя, Колонка.Ширина));
+ КонецЦикла;
+
+ СуммаЗаданных = 0;
+ КоличествоНезаполненных = 0;
+
+ Для Каждого Колонка Из Колонки Цикл
+ Если Колонка.Ширина > 0 Тогда
+ СуммаЗаданных = СуммаЗаданных + Колонка.Ширина;
+ Иначе
+ КоличествоНезаполненных = КоличествоНезаполненных + 1;
+ КонецЕсли;
+ КонецЦикла;
+
+ // Шаг 1: нормализация
+
+ Если СуммаЗаданных = 0 Тогда
+ Для Каждого Колонка Из Колонки Цикл
+ Колонка.Вставить("ШиринаПроцентов", Окр(100 / Колонки.Количество(), 0));
+ КонецЦикла;
+
+ ИначеЕсли СуммаЗаданных <= 100 Тогда
+ Свободно = 100 - СуммаЗаданных;
+ Средняя = ?(КоличествоНезаполненных > 0, Свободно / КоличествоНезаполненных, 0);
+ Для Каждого Колонка Из Колонки Цикл
+ Если Колонка.Ширина = 0 Тогда
+ Колонка.Вставить("ШиринаПроцентов", Окр(Средняя, 0));
+ Иначе
+ Колонка.Вставить("ШиринаПроцентов", Окр(Колонка.Ширина, 0));
+ КонецЕсли;
+ КонецЦикла;
+ Иначе
+ // Масштабирование
+ Для Каждого Колонка Из Колонки Цикл
+ Если Колонка.Ширина > 0 Тогда
+ Пропорция = Колонка.Ширина / СуммаЗаданных * 100;
+ Колонка.Вставить("ШиринаПроцентов", Окр(Пропорция, 0));
+ Иначе
+ Колонка.Вставить("ШиринаПроцентов", 0);
+ КонецЕсли;
+ КонецЦикла;
+
+ // Заполнение оставшихся нулей
+ НовыйСумма = 0;
+ КоличествоНезаполненных = 0;
+ Для Каждого Колонка Из Колонки Цикл
+ Если Колонка.ШиринаПроцентов > 0 Тогда
+ НовыйСумма = НовыйСумма + Колонка.ШиринаПроцентов;
+ Иначе
+ КоличествоНезаполненных = КоличествоНезаполненных + 1;
+ КонецЕсли;
+ КонецЦикла;
+
+ Остаток = 100 - НовыйСумма;
+ Средняя = ?(КоличествоНезаполненных > 0, Остаток / КоличествоНезаполненных, 0);
+ Для Каждого Колонка Из Колонки Цикл
+ Если Колонка.ШиринаПроцентов = 0 Тогда
+ Колонка.ШиринаПроцентов = Окр(Средняя, 0);
+ КонецЕсли;
+ КонецЦикла;
+ КонецЕсли;
+
+ // Шаг 2: корректировка процентов
+
+ ОбщаяСумма = 0;
+ Для Каждого Колонка Из Колонки Цикл
+ ОбщаяСумма = ОбщаяСумма + Колонка.ШиринаПроцентов;
+ КонецЦикла;
+
+ Ошибка = 100 - ОбщаяСумма;
+
+ Пока Ошибка <> 0 Цикл
+ Для Каждого Колонка Из Колонки Цикл
+ Если Ошибка = 0 Тогда
+ Прервать;
+ КонецЕсли;
+ Изменение = ?(Ошибка > 0, 1, -1);
+ Колонка.ШиринаПроцентов = Колонка.ШиринаПроцентов + Изменение;
+ Ошибка = Ошибка - Изменение;
+ КонецЦикла;
+ КонецЦикла;
+
+ // Шаг 3: абсолютная ширина
+
+ ОбщаяПикселей = 0;
+ Для Каждого Колонка Из Колонки Цикл
+ Пикселей = Окр(ОбщаяШирина * Колонка.ШиринаПроцентов / 100, 0);
+ Колонка.Вставить("ШиринаПикселей", Пикселей);
+ ОбщаяПикселей = ОбщаяПикселей + Пикселей;
+ КонецЦикла;
+
+ // Шаг 4: корректировка до точной ширины
+ Остаток = ОбщаяШирина - ОбщаяПикселей;
+ Пока Остаток <> 0 Цикл
+ Для Каждого Колонка Из Колонки Цикл
+ Если Остаток = 0 Тогда
+ Прервать;
+ КонецЕсли;
+ Изменение = ?(Остаток > 0, 1, -1);
+ Колонка.ШиринаПикселей = Колонка.ШиринаПикселей + Изменение;
+ Остаток = Остаток - Изменение;
+ КонецЦикла;
+ КонецЦикла;
+
+ Возврат Колонки;
+
+КонецФункции
+
+#КонецОбласти
+
+#Область СлужебныеПроцедурыИФункции
+
+#КонецОбласти
+```
\ No newline at end of file
diff --git a/src/content/docs/knowledge-base/Примеры, сниппеты/БСП и типовые/Работа с почтой/Модуль для работы с почтой.md b/src/content/docs/knowledge-base/Примеры, сниппеты/БСП и типовые/Работа с почтой/Модуль для работы с почтой.md
index 349438f..04b5dd8 100644
--- a/src/content/docs/knowledge-base/Примеры, сниппеты/БСП и типовые/Работа с почтой/Модуль для работы с почтой.md
+++ b/src/content/docs/knowledge-base/Примеры, сниппеты/БСП и типовые/Работа с почтой/Модуль для работы с почтой.md
@@ -4,17 +4,8 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
---
```bsl
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Модуль для формирования и отправки почтовых сообщений
-// PS. Все особенности верстки из-за своеобразной интерпретации html outlook'ом
-//
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
#Область ПрограммныйИнтерфейс
-#Область ОтправкаСообщений
-
// Процедура - Отправить письмо
//
// Параметры:
@@ -25,13 +16,9 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
//
Процедура ОтправитьПисьмо(АдресЭлектроннойПочты, ТекстСообщения, ТемаСообщения, ДополнительныеПараметрыПисьма = Неопределено) Экспорт
- // { УЗГА, Сине-Никольский А.А. 21.04.2025, CR-542 / TASK-1198
Если ДополнительныеПараметрыПисьма = Неопределено Тогда
ДополнительныеПараметрыПисьма = Новый Структура;
КонецЕсли;
- // } УЗГА, Сине-Никольский А.А. 21.04.2025, CR-542 / TASK-1198
-
- // { УЗГА, Сине-Никольский А.А. 20.01.2025, "CR-240" / Задача "TASK-513"
Если Не ОбщегоНазначенияКлиентСервер.АдресЭлектроннойПочтыСоответствуетТребованиям(АдресЭлектроннойПочты, Ложь) Тогда
ЗаписьЖурналаРегистрации("(УЗГА) Рассылка уведомлений на электронную почту",
@@ -47,9 +34,7 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
ПараметрыПисьма.Вставить("Тема", ТемаСообщения);
ПараметрыПисьма.Вставить("Тело", ТекстСообщения);
- // { УЗГА, Сине-Никольский А.А. 21.04.2025, CR-542 / TASK-1198
ОбщегоНазначенияКлиентСервер.ДополнитьСтруктуру(ПараметрыПисьма, ДополнительныеПараметрыПисьма, Истина);
- // } УЗГА, Сине-Никольский А.А. 21.04.2025, CR-542 / TASK-1198
Письмо = РаботаСПочтовымиСообщениями.ПодготовитьПисьмо(УчетнаяЗапись, ПараметрыПисьма);
@@ -60,8 +45,6 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
УровеньЖурналаРегистрации.Ошибка,,,
СтрШаблон("Ошибка отправки сообщения. Описание ошибки %1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())));
КонецПопытки;
-
- // } УЗГА, Сине-Никольский А.А. 20.01.2025, "CR-240" / Задача "TASK-513"
КонецПроцедуры
@@ -76,8 +59,6 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
// ДополнительныеПараметрыПисьма - Структура - см. описание аргумента "ПараметрыПисьма" из РаботаСПочтовымиСообщениями.ПодготовитьПисьмо
//
Процедура ОтправитьПисьмоПользователю(Пользователь, ТекстСообщения, ТемаСообщения, ДобавитьОбращение = Ложь, ДополнительныеПараметрыПисьма = Неопределено) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 20.01.2025, "CR-240" / Задача "TASK-513"
АдресЭлектроннойПочты = УЗГА_УправлениеКонтактнойИнформацией.АдресЭлектроннойПочтыПользователя(Пользователь);
@@ -93,8 +74,6 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
КонецЕсли;
ОтправитьПисьмо(АдресЭлектроннойПочты, ТекстСообщения, ТемаСообщения, ДополнительныеПараметрыПисьма);
-
- // } УЗГА, Сине-Никольский А.А. 20.01.2025, "CR-240" / Задача "TASK-513"
КонецПроцедуры
@@ -108,15 +87,11 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
// Используйте, если тело сообщения - простой текст. HTML сломает
// ДополнительныеПараметрыПисьма - Структура - см. описание аргумента "ПараметрыПисьма" из РаботаСПочтовымиСообщениями.ПодготовитьПисьмо
Процедура ОтправитьПисьмоСпискуПользователей(СписокПользователей, ТекстСообщения, ТемаСообщения, ДобавитьОбращение = Ложь, ДополнительныеПараметрыПисьма = Неопределено) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 20.01.2025, "CR-240" / Задача "TASK-513"
Для Каждого Пользователь Из СписокПользователей Цикл
ОтправитьПисьмоПользователю(Пользователь, ТекстСообщения, ТемаСообщения, ДобавитьОбращение, ДополнительныеПараметрыПисьма);
КонецЦикла;
- // } УЗГА, Сине-Никольский А.А. 20.01.2025, "CR-240" / Задача "TASK-513"
-
КонецПроцедуры
// Процедура - Отправить HTMLПисьмо пользователю
@@ -128,7 +103,6 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
// ДополнительныеПараметрыПисьма - Структура - см. описание аргумента "ПараметрыПисьма" из РаботаСПочтовымиСообщениями.ПодготовитьПисьмо
Процедура ОтправитьHTMLПисьмоПользователю(Пользователь, HTMLТекстСообщения, ТемаСообщения, ДополнительныеПараметрыПисьма = Неопределено) Экспорт
- // { УЗГА, Сине-Никольский А.А. 22.04.2025, CR-542 / TASK-1198
Если ДополнительныеПараметрыПисьма = Неопределено Тогда
ДополнительныеПараметрыПисьма = Новый Структура;
КонецЕсли;
@@ -140,7 +114,6 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
ОбщегоНазначенияКлиентСервер.ДополнитьСтруктуру(ДополнительныеПараметрыПисьма, ПараметрыHTMLПисьма, Истина);
ОтправитьПисьмоПользователю(Пользователь, HTMLТекстСообщения, ТемаСообщения, Ложь, ДополнительныеПараметрыПисьма);
- // } УЗГА, Сине-Никольский А.А. 22.04.2025, CR-542 / TASK-1198
КонецПроцедуры
@@ -153,11 +126,9 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
// ДополнительныеПараметрыПисьма - Структура - см. описание аргумента "ПараметрыПисьма" из РаботаСПочтовымиСообщениями.ПодготовитьПисьмо
Процедура ОтправитьHTMLПисьмоПоСпискуПользователей(СписокПользователей, HTMLТекстСообщения, ТемаСообщения, ДополнительныеПараметрыПисьма = Неопределено) Экспорт
- // { УЗГА, Сине-Никольский А.А. 22.04.2025, CR-542 / TASK-1198
Для Каждого Пользователь Из СписокПользователей Цикл
ОтправитьHTMLПисьмоПользователю(Пользователь, HTMLТекстСообщения, ТемаСообщения, ДополнительныеПараметрыПисьма);
КонецЦикла;
- // } УЗГА, Сине-Никольский А.А. 22.04.2025, CR-542 / TASK-1198
КонецПроцедуры
@@ -171,17 +142,11 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
// Если не удается определить пол, возвращается "Уважаемый(ая)...",
// если не удается распарсить ФИО, вместо <Фамилия Имя Отчество> выводится "пользователь"
Функция ОбращениеКПользователю(Пользователь) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 20.01.2025, "CR-240" / Задача "TASK-513"
Обращение = "Уважаемый(ая)";
ФИО = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Пользователь, "Наименование", Истина);
- Если Не ЗначениеЗаполнено(ФИО) Тогда
- ФИО = "пользователь";
- КонецЕсли;
-
Если ЗначениеЗаполнено(ФИО) Тогда
ЧастиИмени = СтрРазделить(ФИО, " ", Ложь);
@@ -197,800 +162,30 @@ slug: primery-snippety-bsp-i-tipovye-rabota-s-pochtoy/biblioteka-dlya-raboty-s-p
КонецЕсли;
КонецЕсли;
-
+ Иначе
+ ФИО = "пользователь";
КонецЕсли;
Возврат СтрШаблон("%1 %2!", Обращение, ФИО);
- // } УЗГА, Сине-Никольский А.А. 20.01.2025, "CR-240" / Задача "TASK-513"
-
-КонецФункции
-
-#КонецОбласти
-
-#Область ПодготовкаHTMLСообщения
-
-// Функция - Сообщение HTML
-//
-// Параметры:
-// Заголовок - Строка - Строка, которая будет отображаться в шапке письма крупным шрифтом
-// МассивБлоковHTMLСообщения - Массив Из Строка - Массив строк, сформированных функциями "БлокHMTLСообщения_..."
-// ПараметрыОформления - Структура - см. ПараметрыОформленияHTMLСообщения. Если неопределено создаются параметры по умолчанию
-//
-// БлокОбъектов = Новый Массив;
-// // Абзац
-// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_Абзац("Скажи-ка, дядя, ведь<>%$"""" ' недаром, Москва..." + Символы.ПС + "tot;ladkflasdhkf;as"));
-//
-// // Абзац с гиперссылкой
-// ПараметрыГиперссылки = Новый Соответствие;
-// ПараметрыГиперссылки.Вставить("с гиперссылкой", "https://www.google.com");
-// ПараметрыГиперссылки.Вставить("еще одной", "https://www.google.com");
-// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_АбзацСГиперссылками("Абзацы можно добавлять [с гиперссылкой] и, если хочется, [еще одной]. Количество не ограничено", ПараметрыГиперссылки));
-//
-// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_Абзац("Так будет выглядеть список. Формируется из массива"));
-//
-// // Список пунктов
-// МассивПунктов = Новый Массив;
-// МассивПунктов.Добавить("Пункт 1");
-// МассивПунктов.Добавить("Пункт 2");
-//
-// МассивПодпунктов = Новый Массив;
-// МассивПодпунктов.Добавить("Подпункт 1");
-// МассивПодпунктов.Добавить("Подпункт 2");
-//
-// МассивПодпунктов1 = Новый Массив;
-// МассивПодпунктов1.Добавить("Подпункт 1");
-// МассивПодпунктов1.Добавить("Подпункт 2");
-// МассивПодпунктов.Добавить(МассивПодпунктов1);
-//
-// МассивПунктов.Добавить(МассивПодпунктов);
-// МассивПунктов.Добавить("Пункт 3");
-//
-// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_СписокНенумерованный(МассивПунктов));
-//
-// // В результате такая структура
-// // Пункт 1
-// // Пункт 2
-// // Подпункт 1
-// // Подпункт 2
-// // Подпункт 1
-// // Подпункт 2
-// // Пункт 3
-//
-//
-// // Таблица
-// ТЗ = Новый ТаблицаЗначений;
-// ТЗ.Колонки.Добавить("НомерПоПорядку", , "№", 5); // ширину задаем, если нужна разная ширина колонок
-// ТЗ.Колонки.Добавить("Номенклатура");
-// ТЗ.Колонки.Добавить("Характеристика");
-// ТЗ.Колонки.Добавить("Количество", , "Кол-во" , 10);
-//
-// НоваяСтрока = ТЗ.Добавить();
-// НоваяСтрока.НомерПоПорядку = "1";
-// НоваяСтрока.Номенклатура = "Номенклатура 1";
-// НоваяСтрока.Характеристика = "";
-// НоваяСтрока.Количество = 10;
-//
-// НоваяСтрока = ТЗ.Добавить();
-// НоваяСтрока.НомерПоПорядку = "2";
-// НоваяСтрока.Номенклатура = "Номенклатура 2";
-// НоваяСтрока.Характеристика = "с характеристикой";
-// НоваяСтрока.Количество = "15";
-//
-// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_Таблица(ТЗ));
-//
-// // Цитата
-// БлокОбъектов.Добавить(ОбработкаОбъект.БлокHTMLСообщения_Цитата("Это цитата"));
-//
-// Результат = ОбработкаОбъект.СообщениеHTML("Добрый день", БлокОбъектов);
-// Возвращаемое значение:
-// Строка - сообщение, оформленное в HTML
-//
-Функция СообщениеHTML(Заголовок, МассивБлоковHTMLСообщения, ПараметрыОформления = Неопределено) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
- Шаблон = ШаблонHTMLСообщения(ПараметрыОформления);
-
- ПараметрыЗаполнения = Новый Структура("ТелоСообщения", СтрСоединить(МассивБлоковHTMLСообщения, Символы.ПС));
- ПараметрыЗаполнения.Вставить("Заголовок", НормализованныйТекстДляHTML(Заголовок));
-
- Результат = СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, ПараметрыЗаполнения);
-
- Возврат Результат;
- // } УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
-КонецФункции
-
-// Функция - Параметры оформления HTMLСообщения. Содержит значения плейсхолдеров инлайновых стилей CSS в шаблоне.
-// Обязательны все для формирования работы метода СообщениеHTML.
-//
-// Возвращаемое значение:
-// Структура -
-// ТелоЦветЗаднегоФона - Строка - background. По умолчанию "rgb(245, 245, 245)"
-// ТелоШрифт - Строка - font-family. По умолчанию "Arial, sans-serif"
-//
-// АбзацВнутреннийОтступ - Строка - padding. По умолчанию "2px"
-// АбзацРазмерШрифта - Строка - font-size. По умолчанию "14px"
-// АбзацМежстрочныйИнтервал - Строка - line-height. По умолчанию "1.6"
-// АбзацЦветТекста - Строка - color. По умолчанию "rgb(51, 51, 51)"
-// АбзацВнешнийОтступ - Строка - margin. По умолчанию "5px"
-//
-// КонтейнерВнешнийОтступ - Строка - margin. По умолчанию "40px"
-// КонтейнерЦветФона - Строка - background. По умолчанию "rgb(255, 255, 255)"
-// КонтейнерВнутреннийОтступ - Строка - padding. По умолчанию "20px"
-// КонтейнерСкругление - Строка - border-radius. По умолчанию "6px"
-// КонтейнерТень - Строка - box-shadow. По умолчанию "0 2px 4px rgba(0, 0, 0, 0.1)"
-//
-// ЗаголовокЦветТекста - Строка - color. По умолчанию "rgb(118, 34, 40)"
-// ЗаголовокВнутреннийОтступ - Строка - padding. По умолчанию "0px"
-// ЗаголовокВнешнийОтступ - Строка - margin. По умолчанию "10px"
-//
-// КонтентШирина - Строка - width. По умолчанию "1000"
-// КонтентВнутреннийОтступ - Строка - padding. По умолчанию "5px"
-// КонтентРазмерШрифта - Строка - font-size. По умолчанию "14px"
-// КонтентМежстрочныйИнтервал - Строка - line-height. По умолчанию "1.6"
-// КонтентЦветТекста - Строка - color. По умолчанию "rgb(51, 51, 51)"
-//
-// ТаблицаШирина - Строка - width. По умолчанию "960". ВНИМАНИЕ, Всегда указывайте как строковое представление числа, без "px, em" и пр.
-// ТаблицаВнешнийОтступ - Строка - margin. По умолчанию "10px"
-// ЯчейкаГраница - Строка - border. По умолчанию "1px solid rgb(204, 204, 204)"
-// ТаблицаЦветФонаЗаголовка - Строка - background. По умолчанию "rgb(230, 230, 230)"
-// ТаблицаЦветТекстаЗаголовка - Строка - color. По умолчанию "rgb(118, 34, 40)"
-//
-// СсылкаЦветТекста - Строка - color. По умолчанию "rgb(118, 34, 40)"
-// СсылкаЦветФона - Строка - background. По умолчанию "rgb(249, 249, 249)"
-//
-// ЦитатаВнутреннийОтступ - Строка - padding. По умолчанию "10px"
-// ЦитатаЦветФона - Строка - background. По умолчанию "rgb(249, 249, 249)"
-// ЦитатаГраницаСлева - Строка - border-left. По умолчанию "4px solid rgb(118, 34, 40)"
-//
-// ПодвалОтступСверху - Строка - padding-top. По умолчанию "20px"
-// ПодвалРазмерШрифта - Строка - font-size. По умолчанию "11px"
-// ПодвалЦветТекста - Строка - color. По умолчанию "rgb(119, 119, 119)"
-//
-Функция ПараметрыОформленияHTMLСообщения() Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
- ПараметрыОформления = Новый Структура;
-
- ПараметрыОформления.Вставить("ТелоЦветЗаднегоФона", "rgb(245, 245, 245)");
- ПараметрыОформления.Вставить("ТелоШрифт", "Arial, sans-serif");
-
- ПараметрыОформления.Вставить("АбзацВнутреннийОтступ", "2px");
- ПараметрыОформления.Вставить("АбзацРазмерШрифта", "14px");
- ПараметрыОформления.Вставить("АбзацМежстрочныйИнтервал", "1.6");
- ПараметрыОформления.Вставить("АбзацЦветТекста", "rgb(51, 51, 51)");
- ПараметрыОформления.Вставить("АбзацВнешнийОтступ", "5px");
-
- ПараметрыОформления.Вставить("КонтейнерВнешнийОтступ", "40px");
- ПараметрыОформления.Вставить("КонтейнерЦветФона", "rgb(255, 255, 255)");
- ПараметрыОформления.Вставить("КонтейнерВнутреннийОтступ", "20px");
- ПараметрыОформления.Вставить("КонтейнерСкругление", "6px");
- ПараметрыОформления.Вставить("КонтейнерТень", "0 2px 4px rgba(0, 0, 0, 0.1)");
-
- ПараметрыОформления.Вставить("ЗаголовокЦветТекста", "rgb(118, 34, 40)");
- ПараметрыОформления.Вставить("ЗаголовокВнутреннийОтступ", "0px");
- ПараметрыОформления.Вставить("ЗаголовокВнешнийОтступ", "10px");
-
- ПараметрыОформления.Вставить("КонтентШирина", "1000");
- ПараметрыОформления.Вставить("КонтентВнутреннийОтступ", "5px");
- ПараметрыОформления.Вставить("КонтентРазмерШрифта", "14px");
- ПараметрыОформления.Вставить("КонтентМежстрочныйИнтервал", "1.6");
- ПараметрыОформления.Вставить("КонтентЦветТекста", "rgb(51, 51, 51)");
-
- ПараметрыОформления.Вставить("ТаблицаШирина", "960");
- ПараметрыОформления.Вставить("ТаблицаВнешнийОтступ", "10px auto");
- ПараметрыОформления.Вставить("ЯчейкаГраница", "1px solid rgb(204, 204, 204)");
- ПараметрыОформления.Вставить("ТаблицаЦветФонаЗаголовка", "rgb(230, 230, 230)");
- ПараметрыОформления.Вставить("ТаблицаЦветТекстаЗаголовка", "rgb(118, 34, 40)");
-
- ПараметрыОформления.Вставить("СсылкаЦветТекста", "rgb(118, 34, 40)");
- ПараметрыОформления.Вставить("СсылкаЦветФона", "rgb(249, 249, 249)");
-
- ПараметрыОформления.Вставить("ЦитатаВнутреннийОтступ", "10px");
- ПараметрыОформления.Вставить("ЦитатаЦветФона", "rgb(249, 249, 249)");
- ПараметрыОформления.Вставить("ЦитатаГраницаСлева", "4px solid rgb(118, 34, 40)");
-
- ПараметрыОформления.Вставить("ПодвалОтступСверху", "20px");
- ПараметрыОформления.Вставить("ПодвалРазмерШрифта", "11px");
- ПараметрыОформления.Вставить("ПодвалЦветТекста", "rgb(119, 119, 119)");
-
- Возврат ПараметрыОформления;
- // } УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
-КонецФункции
-
-// Функция - Блок HTMLСообщения заголовок
-//
-// Параметры:
-// ТекстЗаголовка - Строка - Текст, выводимый в блоке
-// Уровень - Число - уровень заголовка от 1 до 6. Рекомендуется использовать от 2 до 4.
-// ПараметрыОформления - Структура - см. ПараметрыОформленияHTMLСообщения
-//
-// Возвращаемое значение:
-// Строка - Блок вида
-//
-Функция БлокHTMLСообщения_Заголовок(ТекстЗаголовка, Уровень = 2, ПараметрыОформления = Неопределено) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 24.04.2025, "CR-529" / Задача "TASK-1447"
- Если ПараметрыОформления = Неопределено Тогда
- ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
- КонецЕсли;
-
- Если Уровень < 1 Или Уровень > 6 Тогда
- Уровень = 2;
- КонецЕсли;
-
- ШаблонЗаголовка = "%2
- |";
- Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонЗаголовка,
- Формат(Уровень, "ЧДЦ=0; ЧГ="),
- НормализованныйТекстДляHTML(ТекстЗаголовка));
-
- Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Результат, ПараметрыОформления);
- // } УЗГА, Сине-Никольский А.А. 24.04.2025, "CR-529" / Задача "TASK-1447"
-
-КонецФункции
-
-// Функция - Блок HTMLСообщения абзац
-//
-// Параметры:
-// ТекстАбзаца - Строка - Текст, который будет выведен в абзаце
-// ПараметрыОформления - Структура, Неопределено - см. ПараметрыОформленияHTMLСообщения().
-// Нормализовать - Булево - Служебный, определяет необходимость экранирования спец.символов
-//
-// Возвращаемое значение:
-// Строка - Блок вида Текст
-//
-Функция БлокHTMLСообщения_Абзац(ТекстАбзаца, ПараметрыОформления = Неопределено, Нормализовать = Истина) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
- Если ПараметрыОформления = Неопределено Тогда
- ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
- КонецЕсли;
-
- Результат = СтрШаблон("%1
- |",
- ?(Нормализовать, НормализованныйТекстДляHTML(ТекстАбзаца), ТекстАбзаца));
-
- Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Результат, ПараметрыОформления);
- // } УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
-КонецФункции
-
-// Функция - Абзац сообщения с гиперссылками
-//
-// Параметры:
-// ШаблонАбзаца - Строка - Шаблон вида "Нажмите [на эту ссылку], чтобы узнать больше". [на эту ссылку] - ключ соответствия СписокСсылок
-// СписокСсылок - Соответствие -
-// * Ключ - Строка - представление ссылки в письме. Т.е. ключ "на эту ссылку" заменит строку "[на эту ссылку]" в шаблоне
-// * Значение - Строка - ссылка для вставки
-// ПараметрыОформления - Структура, Неопределено - см. ПараметрыОформленияHTMLСообщения(). Если неопределено создаются параметры по умолчанию
-//
-// Возвращаемое значение:
-// Строка - Блок вида Текст до ссылки Представление ссылки Текст после ссылки
-//
-Функция БлокHTMLСообщения_АбзацСГиперссылками(Знач ШаблонАбзаца, СписокСсылок, ПараметрыОформления = Неопределено) Экспорт
- // { УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
- Если ПараметрыОформления = Неопределено Тогда
- ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
- КонецЕсли;
-
- ШаблонАбзаца = НормализованныйТекстДляHTML(ШаблонАбзаца);
-
- Для Каждого КлючЗначение Из СписокСсылок Цикл
-
- Ключ = КлючЗначение.Ключ;
- Значение = КлючЗначение.Значение;
-
- СсылкаДляВставки = СтрШаблон("%2",
- Значение,
- Ключ);
-
- ШаблонАбзаца = СтрЗаменить(ШаблонАбзаца,
- СтрШаблон("[%1]", Ключ),
- СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(СсылкаДляВставки, ПараметрыОформления));
-
- КонецЦикла;
-
- Возврат БлокHTMLСообщения_Абзац(ШаблонАбзаца, ПараметрыОформления, Ложь);
-
- // } УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-КонецФункции
-
-// Функция - Список ненумерованный
-//
-// Параметры:
-// МассивЗначений - Массив Из Строка, Массив Из Массив - Список элементов. Если нужен иерархический список, то добавляем не строку, а новый массив строк
-// Например, для массива [Привет, Вася, Как, Дела] будет сформирован список
-// * Привет
-// * Вася
-// * Как
-// * Дела
-// Если в этом массиве будет еще один, то список получится иерархический, Например
-// для массива [Привет, Вася, Как, Дела, [Все, Хорошо]]
-// * Привет
-// * Вася
-// * Как
-// * Дела
-// ** Все
-// ** Хорошо
-//
-// Возвращаемое значение:
-// Строка -
-//
-Функция БлокHTMLСообщения_СписокНенумерованный(МассивЗначений, ПараметрыОформления = Неопределено) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
- Если ПараметрыОформления = Неопределено Тогда
- ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
- КонецЕсли;
-
- Текст = "";
-
- СформироватьСписокНенумерованныйHTMLРекурсивно(МассивЗначений, Текст, ПараметрыОформления);
-
- Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Текст, ПараметрыОформления);
- // } УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
-КонецФункции
-
-// Функция - Блок HTMLСообщения цитата
-//
-// Параметры:
-// ТекстЦитаты - Строка - Выводимый текст
-// ПараметрыОформления - Структура, Неопределено - см. ПараметрыОформленияHTMLСообщения(). Если неопределено создаются параметры по умолчанию
-//
-// Возвращаемое значение:
-// Строка - Блок, оформленный в виде цитаты
-//
-Функция БлокHTMLСообщения_Цитата(ТекстЦитаты, ПараметрыОформления = Неопределено) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
- Если ПараметрыОформления = Неопределено Тогда
- ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
- КонецЕсли;
-
- Шаблон = "
- |
- |
- | %1
- | |
- |
- |
";
-
- Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, НормализованныйТекстДляHTML(ТекстЦитаты));
-
- Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Результат, ПараметрыОформления);
-
- // } УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
-КонецФункции
-
-// Функция - Блок HTMLСообщения таблица
-//
-// Параметры:
-// ТаблицаЗначений - ТаблицаЗначений - Выводимая таблица. Если не заполнен заголовок, в шапке будет выведено имя,
-// если не заполнена ширина, то устанавливается ширина по умолчанию
-//
-// Возвращаемое значение:
-// Строка - Таблица в HTML
-//
-Функция БлокHTMLСообщения_Таблица(ТаблицаЗначений, ПараметрыОформления = Неопределено) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
- Если ПараметрыОформления = Неопределено Тогда
- ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
- КонецЕсли;
-
- ОбщаяШиринаТаблицыСтрокой = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыОформления, "ТаблицаШирина", "960");
- ОбщаяШиринаТаблицы = Число(ОбщаяШиринаТаблицыСтрокой);
-
- ЗначениеШириныКолонок = АбсолютнаяШиринаКолонок(ТаблицаЗначений, ОбщаяШиринаТаблицы);
-
- // Устанавливаем абсолютные значения ширины колонок
- Для Каждого ЗначениеШирины Из ЗначениеШириныКолонок Цикл
- ТаблицаЗначений.Колонки[ЗначениеШирины.Колонка].Ширина = ЗначениеШирины.ШиринаПикселей;
- КонецЦикла;
-
- // Подготавливаем заголовок таблицы
- ДанныеЯчеекЗаголовкаТаблицы = Новый Массив;
- Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
- ТекстЗаполнения = ?(ЗначениеЗаполнено(Колонка.Заголовок), Колонка.Заголовок, Колонка.Имя);
- ДанныеЯчеекЗаголовкаТаблицы.Добавить(ЯчейкаЗаголовкаТаблицыHTML(ТекстЗаполнения, Колонка.Ширина));
- КонецЦикла;
-
- Заголовок = ЗаголовокТаблицыHTML(ДанныеЯчеекЗаголовкаТаблицы);
-
- // Подготавливаем строки
- ДанныеСтрокТаблицы = Новый Массив;
- Для Каждого Строка Из ТаблицаЗначений Цикл
-
- ДанныеЯчеекСтроки = Новый Массив;
- Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
- ДанныеЯчеекСтроки.Добавить(ЯчейкаСтрокиОсновныхДанныхHTML(Строка[Колонка.Имя], Колонка.Ширина));
- КонецЦикла;
-
- ДанныеСтрокТаблицы.Добавить(СтрокаТаблицыHTML(ДанныеЯчеекСтроки));
-
- КонецЦикла;
-
- Таблица = ТаблицаHTML(Заголовок, ДанныеСтрокТаблицы);
-
- Возврат СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Таблица, ПараметрыОформления);
-
- // } УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
-КонецФункции
-
-#КонецОбласти
-
-#КонецОбласти
-
-#Область СлужебныйПрограммныйИнтерфейс
-
-Функция ШаблонHTMLСообщения(ПараметрыОформления = Неопределено) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
- Если ПараметрыОформления = Неопределено Тогда
- ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
- КонецЕсли;
-
- Шаблон =
- "
- |
- |
- |
- | HTML Email
- |
- |
- // Основной контейнер
- |
- |
- |
- // Обертка
- |
- |
- |
- // Начало контента
- |
- |
- |
- | [Заголовок]
- | [ТелоСообщения]
- | |
- |
- //
- // Отчерк
- |
- | |
- |
- |
- | |
- |
- // Конец отчерка
- //
- // Подпись и лого (insert base64 to src img)
- |
- |
- | Это письмо сформировано автоматически. Пожалуйста, не отвечайте на него.
- | |
- |
- |
- |
- |
- | |
- |
- // Конец подписи и лого
- |
- // Конец контента
- | |
- |
- |
- | |
- |
- |
- |
- |";
-
- Результат = СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(Шаблон, ПараметрыОформления);
-
- Возврат Результат;
- // } УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
-КонецФункции
-
-// Функция - Нормализованный текст для HTML. Исплользуется в методах "БлокHTMLСообщения_.."
-//
-// Параметры:
-// Текст - Строка -
-//
-// Возвращаемое значение:
-// Строка - Текст с экранированными спец.символами
-//
-Функция НормализованныйТекстДляHTML(Знач Текст) Экспорт
-
- // { УЗГА, Сине-Никольский А.А. 24.04.2025, "CR-529" / Задача "TASK-1447"
- Текст = СтрЗаменить(Текст, "&", "&");
- Текст = СтрЗаменить(Текст, "<", "<");
- Текст = СтрЗаменить(Текст, ">", ">");
- Текст = СтрЗаменить(Текст, """", """);
- Текст = СтрЗаменить(Текст, "'", "'");
-
- Текст = СтрЗаменить(Текст, Символы.ПС, "
");
- Текст = СтрЗаменить(Текст, Символы.ВК, "
");
- Текст = СтрЗаменить(Текст, Символы.Таб, " ");
-
- Возврат Текст;
- // } УЗГА, Сине-Никольский А.А. 24.04.2025, "CR-529" / Задача "TASK-1447"
-
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
-Процедура СформироватьСписокНенумерованныйHTMLРекурсивно(МассивЗначений, ТекстHTML = Неопределено, ПараметрыОформления = Неопределено)
+Функция АдресЭлектроннойПочтыПользователя(Пользователь)
- // { УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
- Если ТекстHTML = Неопределено Тогда
- ТекстHTML = "";
- КонецЕсли;
-
- Если ПараметрыОформления = Неопределено Тогда
- ПараметрыОформления = ПараметрыОформленияHTMLСообщения();
- КонецЕсли;
-
- ТекстHTML = ТекстHTML
- + СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(НачалоНенумерованногоСпискаHTML(), ПараметрыОформления)
- + Символы.ПС;
-
- Для Каждого ЭлементМассива Из МассивЗначений Цикл
-
- Если ТипЗнч(ЭлементМассива) = Тип("Массив") Тогда
- СформироватьСписокНенумерованныйHTMLРекурсивно(ЭлементМассива, ТекстHTML, ПараметрыОформления);
- Иначе
- ТекстHTML = ТекстHTML + ЭлементНенумерованногоСпискаHTML(ЭлементМассива) + Символы.ПС;
- КонецЕсли
-
- КонецЦикла;
-
- ТекстHTML = ТекстHTML + "
" + Символы.ПС;
- // } УЗГА, Сине-Никольский А.А. 23.04.2025, "CR-529" / Задача "TASK-1447"
-
-КонецПроцедуры
-
-Функция НачалоНенумерованногоСпискаHTML()
- // { УЗГА, Сине-Никольский А.А. 25.04.2025, "CR-529" / Задача "TASK-1447"
- Возврат "