Как формировать и показывать HTML-разметку в 1С 8.3

· 9 мин

Содержание

HTML в 1С работает через три механизма: реквизит формы с видом «Поле HTML-документа» показывает разметку пользователю, встроенный язык собирает её как обычную строку, а табличный документ умеет сохраняться в HTML методом Записать() с типом ТипФайлаТабличногоДокумента.HTML5. Всё остальное — шаблоны, стили, печать, XSLT — надстройки над этими тремя вещами.

Разметку правят в конфигураторе как текст макета или прямо в модуле. Отдельного визуального редактора HTML-отчётов в платформе нет, поэтому сложные отчёты удобнее сначала сверстать в обычном редакторе, а потом перенести в макет.

Где HTML реально нужен в 1С

HTML — не замена табличному документу и СКД. Он выигрывает там, где нужна свободная вёрстка, ссылки и интерактив.

Типовые сценарии:

  • 📊 Информационные панели на начальной странице: карточки с цифрами, цветные индикаторы, мини-графики на CSS.
  • 📄 Справки и инструкции внутри формы: текст с заголовками, списками и ссылками.
  • 🔗 Интерактивные отчёты: клик по строке открывает документ 1С через обработчик нажатия.
  • 📧 Письма: тело HTML-письма для рассылки счетов и уведомлений.
  • 🌐 HTTP-сервисы: простая веб-страница со статусом заказа или остатками, которую отдаёт сама база.
  • 💾 Выгрузка отчёта в файл, который откроется в любом браузере без 1С.

Когда HTML не нужен:

ЗадачаЧем лучше решатьПочему
Печатная форма документаТабличный документТочная печать, поля страницы, привычный механизм
Отчёт с группировками и отборамиСКДПользователь сам меняет настройки
Форма ввода данныхОбычные элементы формыПроверки, привязка к реквизитам
Дашборд, справка, письмоHTMLСвободная вёрстка и стили

Поле HTML-документа на управляемой форме

Это главный способ показать разметку пользователю. Настройка в конфигураторе:

  1. Откройте форму, на вкладке «Реквизиты» добавьте реквизит, например ТекстHTML, тип Строка, длина 0 (неограниченная).
  2. Перетащите реквизит в дерево элементов.
  3. В свойствах элемента установите Вид = «Поле HTML-документа».
  4. Для отчётов включите свойство ТолькоПросмотр, чтобы пользователь не редактировал разметку.
  5. Растяните поле: задайте РастягиватьПоГоризонтали и РастягиватьПоВертикали.

Заполнять реквизит можно на сервере — значение просто передаётся строкой:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ТекстHTML = "<html><head><meta charset=""utf-8""></head>"
        + "<body><h2>Остатки на складе</h2><p>Данные загружаются…</p></body></html>";
КонецПроцедуры

Как обработать клик по ссылке

У поля есть событие ПриНажатии. В него приходит объект ДанныеСобытия с адресом ссылки (Href) и элементом, по которому кликнули (Element). Приём практиков — кодировать команду в адресе и отменять стандартный переход:

&НаКлиенте
Процедура ТекстHTMLПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
    Адрес = ДанныеСобытия.Href;
    Если СтрНайти(Адрес, "#doc:") > 0 Тогда
        СтандартнаяОбработка = Ложь;
        ИдСтрокой = Сред(Адрес, СтрНайти(Адрес, "#doc:") + 5);
        ОткрытьДокументПоИд(ИдСтрокой);
    КонецЕсли;
КонецПроцедуры

В разметке ссылка выглядит так: <a href="#doc:5f2c...">Реализация №125</a>. Процедура ОткрытьДокументПоИд — ваша: на сервере она получает ссылку по Новый УникальныйИдентификатор(ИдСтрокой) и возвращает её на клиент для ПоказатьЗначение().

Не ставьте в href ссылки на внешние сайты без СтандартнаяОбработка = Ложь и явного ЗапуститьПриложение(): иначе страница откроется прямо внутри поля и пользователь потеряет отчёт.

Обращение к странице из кода

После загрузки страницы срабатывает событие ДокументСформирован. Только после него можно обращаться к DOM через свойство элемента Документ, например менять текст блока без перерисовки всего поля. До этого события объект документа может быть ещё не готов — частая причина ошибок «Значение не является значением объектного типа ».

Как собирать HTML кодом 1С

Разметка — обычная строка. Но сложение строк в цикле на тысячах записей работает медленно. Надёжнее копить фрагменты в массив и склеивать один раз через СтрСоединить() (есть с 8.3.6).

Экранирование данных

Главное правило: любое значение из базы перед вставкой в HTML экранируйте. Наименование контрагента ООО "Рога & Копыта" без экранирования сломает вёрстку, а текст со скобками < может превратиться в тег или скрипт.

Функция ЭкранироватьHTML(Знач Текст) Экспорт
    Текст = СтрЗаменить(Текст, "&", "&amp;");   // первым — амперсанд
    Текст = СтрЗаменить(Текст, "<", "&lt;");
    Текст = СтрЗаменить(Текст, ">", "&gt;");
    Текст = СтрЗаменить(Текст, """", "&quot;");
    Возврат Текст;
КонецФункции

Амперсанд заменяйте первым, иначе уже готовые &lt; превратятся в &amp;lt; и на экране появятся служебные символы.

Полный пример: таблица остатков

&НаСервере
Функция СформироватьHTMLОстатков()
    Запрос = Новый Запрос(
    "ВЫБРАТЬ
    |    Номенклатура.Наименование КАК Товар,
    |    Остатки.КоличествоОстаток КАК Количество
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
    |УПОРЯДОЧИТЬ ПО
    |    Товар");
    Выборка = Запрос.Выполнить().Выбрать();

    Части = Новый Массив;
    Части.Добавить("<html><head><meta charset=""utf-8"">");
    Части.Добавить(СтилиОтчета());
    Части.Добавить("</head><body><table><thead><tr><th>Товар</th><th>Количество</th></tr></thead><tbody>");

    Пока Выборка.Следующий() Цикл
        Класс = ?(Выборка.Количество <= 0, " class=""zero""", "");
        Части.Добавить(СтрШаблон("<tr%1><td>%2</td><td class=""num"">%3</td></tr>",
            Класс,
            ЭкранироватьHTML(Выборка.Товар),
            Формат(Выборка.Количество, "ЧДЦ=3; ЧН=0")));
    КонецЦикла;

    Части.Добавить("</tbody></table></body></html>");
    Возврат СтрСоединить(Части, "");
КонецФункции

Имя регистра в запросе подставьте своё: в БП 3.0 остатки хранятся иначе, чем в УТ 11. Пример показывает приём, а не готовый отчёт под конфигурацию.

Что здесь важно:

  • 🔢 Числа выводятся через Формат(), а не склейкой — так не появятся неразрывные пробелы-разделители там, где они не нужны, и нули не превратятся в пустоту.
  • 🎨 Подсветка задаётся классом, а не встроенным style в каждой строке: разметка короче, стиль меняется в одном месте.
  • 🧩 Стили вынесены в отдельную функцию СтилиОтчета() — о ней ниже.

Таблицы и CSS в HTML-отчётах 1С

Стили держите в одном блоке <style> в <head>. Пример, который хорошо смотрится и на экране, и при печати:

body  { font-family: Arial, sans-serif; font-size: 13px; color: #222; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ccc; padding: 4px 8px; }
th    { background: #f3f3f3; text-align: left; }
td.num { text-align: right; white-space: nowrap; }
tr.zero td { color: #b00; }
tbody tr:nth-child(even) { background: #fafafa; }

@media print {
  thead { display: table-header-group; }   /* шапка на каждой странице */
  tr    { page-break-inside: avoid; }      /* строка не рвётся между листами */
  .no-print { display: none; }             /* кнопки и фильтры не печатаются */
}

Как вернуть этот CSS из кода — функция СтилиОтчета() просто возвращает строку "<style>…</style>". Если стилей много, храните их в макете (см. раздел про шаблоны).

Несколько практических наблюдений:

  • 📏 Ширины колонок задавайте в процентах или через <colgroup>, а не пикселями: поле на форме меняет размер вместе с окном.
  • 🧮 Итоговую строку кладите в <tfoot> — при печати браузерный движок понимает её как подвал таблицы.
  • 🖼️ Внешние файлы картинок и стилей поле HTML не найдёт по относительному пути. Картинку встраивайте как data: URI: "<img src=""data:image/png;base64," + Base64Строка(Данные) + """>". Из результата Base64Строка() уберите переносы строк через СтрЗаменить() по Символы.ПС и Символы.ВК.
  • 🧪 Современные CSS-возможности (flex, grid) работают, только если движок поля их поддерживает. В актуальных версиях 8.3 поле использует движок на основе WebKit, но на старых платформах в Windows встраивался Internet Explorer — проверяйте вёрстку на той версии, что стоит у пользователей.

Экспорт HTML-отчёта в PDF и Excel

Здесь главное решение — откуда экспортировать: из готовой HTML-строки или из табличного документа.

СпособЧто получитсяКогда выбирать
Табличный документ → Записать() с типом PDFТочный PDF с полями страницыНужен печатный документ для отправки
Табличный документ → Записать() с типом XLSXНастоящая книга Excel с числамиПользователь будет считать в Excel
Табличный документ → Записать() с типом HTML5Страница для браузераНужен лёгкий файл без 1С
HTML-строка → файл .htmlВаша вёрстка как естьОтчёт целиком на HTML
HTML-строка → печать из поляPDF через виртуальный принтерРазовый вывод, без автоматизации

Платформа не умеет конвертировать произвольный HTML в PDF или XLSX штатными средствами. Поэтому для отчётов, которые регулярно уходят в PDF или Excel, практичнее строить табличный документ (или СКД) и уже его сохранять в нужный формат. HTML оставьте для экрана.

Запись HTML-строки в файл с правильной кодировкой:

Текст = Новый ТекстовыйДокумент;
Текст.УстановитьТекст(СтрокаHTML);
Текст.Записать(ИмяФайла, КодировкаТекста.UTF8);

Старый приём «сохранить HTML-таблицу с расширением .xls» Excel откроет, но с предупреждением о несоответствии формата и расширения. Числа при этом часто становятся текстом. Для обмена с бухгалтерией используйте XLSX из табличного документа.

Шаблоны, XSLT и связь с вебом

Когда отчётов становится больше двух-трёх, держать разметку в строках модуля неудобно. Три уровня решения — от простого к сложному.

1. Шаблон в макете

Создайте макет типа «Текстовый документ», вставьте в него HTML с метками вида %1, %2 или {{Организация}}. В коде получите текст и подставьте значения:

Макет = Обработки.ИнформационнаяПанель.ПолучитьМакет("ШаблонПанели");
Шаблон = Макет.ПолучитьТекст();
Результат = СтрЗаменить(Шаблон, "{{Организация}}", ЭкранироватьHTML(НаименованиеОрганизации));

Плюс: вёрстку правит дизайнер или аналитик, не трогая код. В типовой конфигурации такой макет лучше добавлять через расширение, чтобы обновления не затирали правки.

2. XSLT-преобразование

Если данные уже есть в XML (выгрузка, ответ веб-сервиса), объект ПреобразованиеXSL превращает их в HTML по таблице стилей:

Преобразование = Новый ПреобразованиеXSL;
Преобразование.ЗагрузитьТаблицуСтилейXSLИзСтроки(ТекстXSL);
СтрокаHTML = Преобразование.ПреобразоватьИзСтроки(ТекстXML);

Таблицу стилей XSL удобно хранить в том же текстовом макете. XSLT хорош для единообразных документов из обмена — например, для человекочитаемого просмотра XML-файла электронного документа.

3. HTTP-сервис, отдающий страницу

База может сама отдавать HTML в браузер. В HTTP-сервисе обработчик метода возвращает ответ с нужным заголовком:

Функция СтатусЗаказаGET(Запрос)
    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.Заголовки.Вставить("Content-Type", "text/html; charset=utf-8");
    Ответ.УстановитьТелоИзСтроки(СформироватьСтраницу(Запрос), КодировкаТекста.UTF8);
    Возврат Ответ;
КонецФункции

Сервис публикуется на веб-сервере вместе с базой. Доступ закрывайте аутентификацией: страница работает с правами пользователя, под которым идёт подключение.

Обмен с JavaScript внутри поля

Из JavaScript в 1С проще всего передавать команды через ссылки и событие ПриНажатии (приём с #doc: выше). Это работает одинаково в тонком клиенте и веб-клиенте, без зависимостей от движка. Обратное направление — вызов функции страницы из 1С — делается через объект Документ элемента после события ДокументСформирован, но его поведение зависит от движка поля, так что проверяйте в нужном клиенте.

Частые ошибки при работе с HTML в 1С

Диагностика: выберите симптом

Отдельно про безопасность: если в HTML попадает текст, который вводят пользователи или присылают контрагенты (комментарии, назначения платежа), без экранирования в поле может выполниться чужой скрипт. Экранирование — не косметика, а защита.

Частые вопросы

Можно ли редактировать HTML прямо в поле на форме?
Да, если снять у элемента флаг «Только просмотр». Но для редактирования форматированного текста пользователем удобнее «Поле форматированного документа»: у него есть панель форматирования, а HTML из него получают методом ПолучитьHTML.
Чем HTML-поле отличается от форматированной строки?
Форматированная строка — это объект 1С для надписей с выделением и ссылками, без тегов и CSS. HTML даёт полную вёрстку, но требует отдельного поля на форме.
Работает ли поле HTML-документа в веб-клиенте?
Работает: разметка выводится во фрейме браузера пользователя. Поэтому вёрстку проверяйте и в браузерах, через которые сотрудники заходят в базу.
Как сохранить готовый отчёт СКД в HTML?
Выведите результат компоновки в табличный документ и вызовите Записать с типом ТипФайлаТабличногоДокумента.HTML5. Пользователь то же самое делает через команду сохранения табличного документа, выбрав формат HTML.
Нужно ли закрывать все теги в HTML для 1С?
Движок прощает незакрытые теги, но таблица без закрытых tr и td может развалиться при печати. Пишите валидную разметку и проверяйте её в обычном браузере.