Вывод табличного документа пользователю: окно, поле формы, печать и файл

· 9 мин

Содержание

Чтобы показать табличный документ пользователю в 1С 8.3, сформируйте его на сервере, верните на клиент и вызовите ТабДок.Показать("Заголовок"). Откроется отдельное окно с документом, где его можно просмотреть, распечатать и сохранить в файл. Тема общая для платформы: код одинаково работает в БП 3.0, ЗУП 3.1, УТ 11 и в своих обработках.

Способов вывода четыре, и выбирают их по задаче. Нужен быстрый просмотр результата — метод Показать(). Отчёт или печатная форма живёт внутри своей формы — поле табличного документа. Документ нужен на бумаге без участия пользователя — Напечатать(). Нужен файл для почты или архива — Записать().

СпособГде вызываетсяКогда выбирать
Показать()на клиентеразовый просмотр, отладка, простая обработка
Поле табличного документа на формезаполнение на сервереотчёт с параметрами, повторное формирование
Напечатать()на клиентепакетная печать, печать по кнопке без окна
Записать()на сервере (или клиенте, кроме веб)выгрузка в PDF, XLSX, MXL для отправки

Как собрать табличный документ перед показом

Табличный документ почти всегда собирается из макета. Макет — это заготовка с именованными областями: «Шапка», «Строка», «Подвал». Код берёт область, заполняет её параметры и выводит в документ столько раз, сколько нужно.

Порядок такой:

  1. В конфигураторе добавьте макет типа «Табличный документ» к обработке, отчёту или документу.
  2. Выделите строки и задайте им имена областей через свойства (Шапка, Строка).
  3. В ячейках, куда подставляются значения, поставьте свойство «Заполнение» = «Параметр» и задайте имя параметра.
  4. В модуле объекта или формы напишите код вывода.

Пример для обработки. Процедура выполняется на сервере, потому что ПолучитьМакет и чтение данных доступны там:

&НаСервере
Функция СформироватьТабДок()

    ТабДок = Новый ТабличныйДокумент;
    Макет = Обработки.ВыводСписка.ПолучитьМакет("Макет");

    ОбластьШапка  = Макет.ПолучитьОбласть("Шапка");
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");

    ОбластьШапка.Параметры.ДатаОтчета = ТекущаяДатаСеанса();
    ТабДок.Вывести(ОбластьШапка);

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Номенклатура.Код КАК Код,
    |    Номенклатура.Наименование КАК Наименование
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    НЕ Номенклатура.ЭтоГруппа";

    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        ОбластьСтрока.Параметры.Заполнить(Выборка);
        ТабДок.Вывести(ОбластьСтрока);
    КонецЦикла;

    Возврат ТабДок;

КонецФункции

Параметры.Заполнить(Выборка) подставляет значения по совпадению имён: колонка запроса «Наименование» уйдёт в параметр «Наименование». Если имена разные, присвойте вручную: ОбластьСтрока.Параметры.Товар = Выборка.Наименование.

Для отчёта с колонками по месяцам или складам области выводят не только вниз, но и вправо. Вывести() добавляет область новой строкой под предыдущей, а Присоединить() ставит её справа от последней выведенной. Типичная схема: вывести область с названием строки, затем в цикле присоединить к ней области-ячейки по каждому периоду.

Макет можно хранить и как общий. Тогда его получают так: ПолучитьОбщийМакет("ИмяМакета").

Табличный документ можно построить и без макета: ТабДок.Область(1, 1).Текст = "Итого". Так удобно выводить отладочную таблицу на пару колонок. Для печатной формы с рамками и шрифтами макет всё равно удобнее.

Настройки до показа

Свойства задают внешний вид окна и печати. Их выставляют до вызова Показать():

ТабДок.ОтображатьСетку     = Ложь;   // скрыть серую сетку ячеек
ТабДок.ОтображатьЗаголовки = Ложь;   // скрыть номера строк и колонок
ТабДок.ТолькоПросмотр      = Истина; // запретить правку
ТабДок.ОриентацияСтраницы  = ОриентацияСтраницы.Ландшафт;
ТабДок.АвтоМасштаб         = Истина; // вписать по ширине листа
ТабДок.КлючПараметровПечати = "ВыводСписка_Номенклатура";

КлючПараметровПечати сохраняет настройки принтера и полей для конкретного пользователя. Задали поля один раз — при следующей печати 1С подставит их сама.

Показ в отдельном окне: тонкий и толстый клиент

Самый короткий путь — метод Показать(). В управляемом приложении он вызывается на клиенте, поэтому документ формируется серверной функцией и возвращается в клиентскую процедуру:

&НаКлиенте
Процедура Сформировать(Команда)

    ТабДок = СформироватьТабДок();
    ТабДок.Показать("Список номенклатуры");

КонецПроцедуры

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

Что получает пользователь:

  • 🪟 отдельное немодальное окно с заголовком из параметра;
  • 🖨️ печать и предварительный просмотр через меню окна;
  • 💾 сохранение в файл через стандартную команду «Сохранить как»;
  • ✏️ возможность править ячейки, если не задано ТолькоПросмотр = Истина.

В толстом клиенте обычного приложения (8.3 в режиме совместимости или старые самописные конфигурации) метод тот же. Разница в том, что там нет разделения на клиент и сервер в модуле формы, и весь код может выполняться в одной процедуре.

Вызов Показать() в процедуре с директивой &НаСервере завершится ошибкой: на сервере нет окон. Показ всегда идёт из клиентского контекста.

Если в конфигурации есть БСП

В типовых конфигурациях печатные формы выводятся через подсистему «Печать» Библиотеки стандартных подсистем. Она открывает общую форму печати с кнопками «Печать», «Сохранить», «Отправить» и выбором количества копий. Для новой печатной формы в типовой лучше подключиться к этой подсистеме через модуль менеджера объекта, а не вызывать Показать() напрямую: пользователь получит привычное окно и все команды.

Для внешней обработки или отладочного вывода Показать() вполне достаточно.

Особенности вывода в веб-клиенте и браузере

Метод Показать() работает и в веб-клиенте. Документ открывается во внутреннем окне приложения, внутри вкладки браузера. Отличия начинаются, когда пользователь хочет напечатать или сохранить его.

ДействиеТонкий клиентВеб-клиент
Просмотрокно 1Сокно внутри вкладки браузера
Печатьдиалог печати Windowsпечать через средства браузера
Сохранение в файлдиалог сохранениязагрузка через браузер
ТабДок.Записать() на клиентедоступеннедоступен, писать на сервере

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

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

Ещё одно отличие: широкие документы (40 и больше колонок) в браузере прокручиваются медленнее. Для отчётов на тысячи строк включайте ТолькоПросмотр и не выводите лишнее оформление.

Табличный документ в поле формы

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

Как добавить:

  1. Откройте форму обработки в конфигураторе.
  2. На вкладке «Реквизиты» добавьте реквизит, например Результат, с типом ТабличныйДокумент.
  3. Перетащите реквизит в дерево элементов. Платформа создаст поле табличного документа.
  4. В свойствах элемента при необходимости включите «Только просмотр» и отключите отображение сетки.

Код формирования пишется на сервере и заполняет реквизит формы напрямую:

&НаКлиенте
Процедура Сформировать(Команда)
    СформироватьНаСервере();
КонецПроцедуры

&НаСервере
Процедура СформироватьНаСервере()

    Результат.Очистить();

    Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет("Макет");
    Область = Макет.ПолучитьОбласть("Шапка");
    Область.Параметры.ДатаОтчета = ТекущаяДатаСеанса();
    Результат.Вывести(Область);

    Результат.ОтображатьСетку = Ложь;

КонецПроцедуры

Не забывайте Очистить() перед выводом — иначе при повторном нажатии новые строки допишутся под старыми, и отчёт удвоится.

Признак «отчёт не сформирован»

Поле умеет показывать поверх себя статус. Это полезно, когда пользователь сменил параметры, а таблица ещё старая:

Элементы.Результат.ОтображениеСостояния.Видимость = Истина;
Элементы.Результат.ОтображениеСостояния.ДополнительныйРежимОтображения =
    ДополнительныйРежимОтображения.Неактуальность;
Элементы.Результат.ОтображениеСостояния.Текст = "Отчёт не сформирован. Нажмите «Сформировать».";

После формирования снимите статус: Элементы.Результат.ОтображениеСостояния.Видимость = Ложь. Этот код относится к элементам формы и может выполняться как на клиенте, так и на сервере.

Открыть готовый документ в своей форме

Иногда документ уже сформирован, и его нужно показать в форме с дополнительными кнопками. Тогда передайте его в параметрах:

ПараметрыФормы = Новый Структура("ТабДок", ТабДок);
ОткрытьФорму("Обработка.ВыводСписка.Форма.ФормаПросмотра", ПараметрыФормы);

В обработчике ПриСозданииНаСервере открываемой формы присвойте реквизиту значение: Результат = Параметры.ТабДок. Параметр с именем ТабДок нужно добавить в параметры формы в конфигураторе.

Печать и экспорт без открытия окна

Печать сразу на принтер

&НаКлиенте
Процедура ПечатьБезДиалога(Команда)
    ТабДок = СформироватьТабДок();
    ТабДок.КоличествоЭкземпляров = 2;
    ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
КонецПроцедуры

Документ уйдёт на принтер по умолчанию. Если нужен конкретный принтер, задайте его имя в свойстве ИмяПринтера до печати. С параметром РежимИспользованияДиалогаПечати.Использовать пользователь увидит диалог выбора принтера и копий.

Пакетная печать без диалога удобна, но ошибка в цикле может отправить на принтер сотню листов. Сначала проверьте вывод на одном объекте через Показать().

Запись в PDF, XLSX и другие форматы

Метод Записать(ИмяФайла, Тип) сохраняет документ в файл. Тип задаётся системным перечислением ТипФайлаТабличногоДокумента:

ЗначениеЧто получится
MXLродной формат 1С, открывается в 1С и в «Файл → Открыть»
PDFдля отправки по почте и архива
XLSXдля работы в Excel
DOCXдля правки в Word
HTMLдля публикации или вставки в письмо
TXTпростой текст без оформления

Запись на сервере с передачей файла пользователю — универсальный вариант, он работает и в веб-клиенте:

&НаСервере
Функция ПодготовитьФайл()

    ТабДок = СформироватьТабДок();
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("pdf");
    ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.PDF);

    Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ИмяВременногоФайла), УникальныйИдентификатор);
    УдалитьФайлы(ИмяВременногоФайла);

    Возврат Адрес;

КонецФункции

&НаКлиенте
Процедура Выгрузить(Команда)
    Адрес = ПодготовитьФайл();
    НачатьПолучениеФайлаССервера(Адрес, "Номенклатура.pdf");
КонецПроцедуры

НачатьПолучениеФайлаССервера есть в платформе 8.3.18 и новее. На более ранних версиях используйте НачатьПолучениеФайлов с описанием передаваемого файла.

Если документ нужен только как вложение письма или запись в присоединённые файлы, клиент не нужен вовсе: формируйте, записывайте и прикрепляйте всё на сервере, хоть из регламентного задания.

Почему табличный документ не выводится: ошибки и отладка

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

Приёмы отладки

  • 🔍 Остановитесь точкой останова после ТабДок.Вывести() и посмотрите ТабДок.ВысотаТаблицы и ТабДок.ШиринаТаблицы. Ноль — значит, ничего не выведено.
  • 🧪 На время отладки добавьте в серверную функцию запись в файл: ТабДок.Записать("C:\Temp\debug.mxl"). Файл откроете в конфигураторе и увидите, что реально сформировалось. Путь должен существовать на том компьютере, где работает серверный код: в клиент-серверной базе это сервер 1С.
  • 📐 Если выводится только часть колонок, проверьте, что область в макете охватывает все нужные колонки. Область по строкам берёт строку целиком, а именованная прямоугольная — только выделенный диапазон.
  • 🐢 Отчёт формируется минутами — вынесите запрос из цикла. Один запрос на все данные и обход выборки работают на порядок быстрее, чем запрос на каждую строку.

Ошибки в макете проще ловить, когда у каждой области и параметра понятное имя. Строка и ТоварНаименование читаются лучше, чем R3 и Параметр1.

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

Можно ли показать табличный документ модально, чтобы код ждал закрытия окна?
Метод Показать() открывает немодальное окно, и код идёт дальше сразу. Если нужно дождаться закрытия, выведите документ в поле своей формы и откройте её с описанием оповещения о закрытии.
Как показать табличный документ из фонового задания?
Напрямую никак: у фонового задания нет клиента. Поместите документ во временное хранилище по адресу, переданному в задание, а после его завершения получите на клиенте и вызовите Показать().
Как начать следующий раздел документа с нового листа?
Перед выводом области вызовите ТабДок.ВывестиГоризонтальныйРазделительСтраниц(). Так собирают несколько печатных форм в один документ: каждая начинается с новой страницы.
Как открыть ранее сохранённый файл MXL?
На сервере создайте новый табличный документ и вызовите у него Прочитать(ИмяФайла). Затем верните документ на клиент и покажите обычным способом.
Почему в XLSX съезжает оформление?
Excel не поддерживает часть возможностей макета: объединения с переносом, картинки в ячейках, некоторые рамки. Для точного внешнего вида отправляйте PDF, а XLSX оставьте для данных.