Вывод данных во встроенном языке 1С 8.3: от окна сообщений до файла и отчёта на СКД

· 9 мин

Содержание

Быстрее всего вывести значение в 1С командой Сообщить(Переменная) — текст появится в окне сообщений внизу формы. Частое заблуждение: что так можно вывести что угодно. Для таблицы значений, массива или структуры Сообщить покажет только имя типа, например «ТаблицаЗначений», а не содержимое. Коллекцию придётся обойти циклом.

Способ выбирают по задаче. Для отладки хватит сообщения или отладчика. Пользователю — предупреждение, поле формы или печатная форма. Для отчёта — система компоновки данных. Для фоновых заданий и обменов — журнал регистрации или файл. Всё ниже относится к платформе 8.3 с управляемыми формами и одинаково работает в любой конфигурации.

Сообщить и СообщениеПользователю: быстрый вывод значения

Сообщить()

Процедура принимает текст и, необязательно, статус сообщения:

Сумма = 15000.5;
Сообщить("Сумма: " + Формат(Сумма, "ЧДЦ=2; ЧГ=0"));
Сообщить("Остаток отрицательный", СтатусСообщения.Важное);

Что важно знать:

  • 🔹 Работает на клиенте и на сервере. Сообщение с сервера пользователь увидит, когда управление вернётся на клиент.
  • 🔹 Ссылку выводит представлением: Сообщить(Контрагент) покажет наименование.
  • 🔹 Число при склейке со строкой получает разделитель групп разрядов: «15 000,5». Для кодов и номеров используйте Формат(Число, "ЧГ=0").
  • 🔹 Дату форматируют так: Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy").

Для длинных строк с несколькими значениями удобнее СтрШаблон:

Сообщить(СтрШаблон("Документ %1 от %2, сумма %3",
    Документ.Номер,
    Формат(Документ.Дата, "ДФ=dd.MM.yyyy"),
    Формат(Документ.СуммаДокумента, "ЧДЦ=2")));

Объект СообщениеПользователю

Если сообщение нужно привязать к полю формы, используйте объект СообщениеПользователю. Пользователь щёлкнет по сообщению, и курсор встанет в нужное поле, а поле подсветится.

Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не заполнен контрагент";
Сообщение.Поле = "Объект.Контрагент";
Сообщение.Сообщить();

В модуле объекта (например, в ОбработкаПроверкиЗаполнения) вместо Поле = "Объект.Контрагент" указывают Поле = "Контрагент" и вызывают Сообщение.УстановитьДанные(ЭтотОбъект).

В типовых конфигурациях на БСП есть готовая процедура ОбщегоНазначения.СообщитьПользователю(Текст, КлючДанных, Поле, ПутьКДанным, Отказ). Она делает то же самое и сразу умеет выставлять Отказ = Истина. В доработках типовых баз берите её.

Как вывести коллекцию

Массив, структуру и таблицу значений обходят циклом:

// Массив
Для Каждого Элемент Из Массив Цикл
    Сообщить(Элемент);
КонецЦикла;

// Структура или соответствие
Для Каждого КлючИЗначение Из Параметры Цикл
    Сообщить(КлючИЗначение.Ключ + " = " + Строка(КлючИЗначение.Значение));
КонецЦикла;

// Таблица значений: одна строка таблицы — одно сообщение
Для Каждого СтрокаТЗ Из ТаблицаТоваров Цикл
    Части = Новый Массив;
    Для Каждого Колонка Из ТаблицаТоваров.Колонки Цикл
        Части.Добавить(Колонка.Имя + ": " + Строка(СтрокаТЗ[Колонка.Имя]));
    КонецЦикла;
    Сообщить(СтрСоединить(Части, "; "));
КонецЦикла;

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

Окна, оповещения и строка состояния

Сообщение в окне легко пропустить. Когда пользователь обязан прочитать текст, нужен другой способ.

МетодЧто видит пользовательГде вызывается
ПоказатьПредупреждениеОкно с кнопкой «ОК»Клиент
ПоказатьОповещениеПользователяВсплывающее уведомление в углу экранаКлиент
ПоказатьЗначениеФорму объекта по ссылке или окно со значениемКлиент
СостояниеТекст и индикатор в строке состоянияКлиент
СообщитьСтроку в окне сообщенийКлиент и сервер

Примеры:

&НаКлиенте
Процедура ПоказатьИтог(Команда)
    // Неблокирующее окно; первый параметр — описание оповещения, здесь не нужно
    ПоказатьПредупреждение(, "Загружено строк: " + Формат(ЧислоСтрок, "ЧГ=0"), 10, "Загрузка");

    // Уведомление в углу экрана
    ПоказатьОповещениеПользователя("Готово", , "Файл выгружен", БиблиотекаКартинок.Информация);

    // Открыть карточку элемента по ссылке
    ПоказатьЗначение(, Контрагент);
КонецПроцедуры

Третий параметр ПоказатьПредупреждение — таймаут в секундах: окно закроется само.

Модальное Предупреждение() в базах с отключённой модальностью вызывает ошибку. Это режим по умолчанию в современных конфигурациях. Используйте ПоказатьПредупреждение и ПоказатьВопрос с описанием оповещения.

Для долгих циклов на клиенте подходит строка состояния: Состояние("Обработка", Сч / Всего * 100). Второй параметр — процент заполнения индикатора.

Вывод значений в табличный документ

Табличный документ — основной способ показать пользователю много данных в читаемом виде: таблицу, печатную форму, выгрузку для Excel.

Без макета: за пять строк

&НаСервере
Функция ПостроитьТаблицу()
    ТабДок = Новый ТабличныйДокумент;
    ТабДок.Область("R1C1").Текст = "Номенклатура";
    ТабДок.Область("R1C2").Текст = "Количество";
    НомерСтроки = 2;
    Для Каждого СтрокаТЗ Из ТаблицаТоваров Цикл
        ТабДок.Область(НомерСтроки, 1).Текст = Строка(СтрокаТЗ.Номенклатура);
        ТабДок.Область(НомерСтроки, 2).Текст = Формат(СтрокаТЗ.Количество, "ЧГ=0");
        НомерСтроки = НомерСтроки + 1;
    КонецЦикла;
    Возврат ТабДок;
КонецФункции

&НаКлиенте
Процедура Показать(Команда)
    ТабДок = ПостроитьТаблицу();
    ТабДок.Показать("Товары");
КонецПроцедуры

Документ строят на сервере, а показывают на клиенте методом Показать().

С макетом: правильный способ для печатных форм

  1. В конфигураторе добавьте к обработке или документу макет типа «Табличный документ».
  2. Нарисуйте именованные области строк: Шапка, Строка, Подвал.
  3. В ячейках области задайте параметры (свойство заполнения «Параметр»), например Номенклатура, Количество.
  4. Выведите области в коде:
Макет = Обработки.МояОбработка.ПолучитьМакет("Макет");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");

ТабДок = Новый ТабличныйДокумент;
ОбластьШапка.Параметры.Заголовок = "Остатки на " + Формат(ТекущаяДатаСеанса(), "ДФ=dd.MM.yyyy");
ТабДок.Вывести(ОбластьШапка);

Для Каждого СтрокаТЗ Из ТаблицаТоваров Цикл
    ОбластьСтрока.Параметры.Заполнить(СтрокаТЗ);
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

Параметры.Заполнить() переносит в область все значения, у которых имя совпадает с именем параметра. Это экономит десятки строк присваиваний.

Чтобы вывести табличный документ прямо в форму, добавьте реквизит формы типа ТабличныйДокумент, перетащите его на форму и в серверной процедуре заполните: Результат.Очистить(); Результат.Вывести(...).

Вывести данные на управляемую форму

Когда значение должно быть видно постоянно, а не в отдельном окне, его выводят в элемент формы.

Поле с реквизитом формы

  1. В редакторе формы на вкладке «Реквизиты» создайте реквизит, например Итого типа «Число».
  2. Перетащите его в дерево элементов — появится поле.
  3. В модуле формы присвойте значение: Итого = 125400;. Поле обновится само.

Надпись-декорация

Для текстовой подсказки удобна декорация «Надпись». Значение меняют через заголовок:

Элементы.НадписьОстаток.Заголовок = "Остаток: " + Формат(Остаток, "ЧДЦ=2");

Таблица на форме

Реквизит формы типа «ТаблицаЗначений» на сервере заполняют через преобразование:

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

Колонки реквизита должны называться так же, как поля запроса. Обратное преобразование — РеквизитФормыВЗначение("ТаблицаНоменклатуры").

Реквизит формы — данные формы, а не объект. На клиенте у него нет методов таблицы значений вроде Выгрузить или Свернуть. Сложную обработку делайте на сервере.

Вывод значений в отчёт на СКД

Если пользователю нужны отбор, группировки и итоги, пишите отчёт на системе компоновки данных. Обычно хватает конструктора: схема, набор данных-запрос, настройки варианта. Код нужен, когда результат надо получить программно или донастроить перед выводом.

Вывод в табличный документ из кода

Схема = Отчеты.ОстаткиТоваров.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Настройки = Схема.НастройкиПоУмолчанию;
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период", ТекущаяДатаСеанса());

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

ТабДок = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Результат СКД в таблицу значений

Иногда отчёт нужен не человеку, а коду: посчитать, проверить, передать дальше. Тогда меняют генератор макета и процессор вывода:

МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , ,
    Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

Результат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Свой вывод в отчёте

В модуле объекта отчёта есть обработчик ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка). Установите СтандартнаяОбработка = Ложь и выведите в ДокументРезультат то, что нужно: например, добавьте шапку из макета перед результатом СКД. Если передать ДанныеРасшифровки в компоновщик и процессор, у пользователя сохранится расшифровка по двойному щелчку.

Куда выводить значение в вашем случае?

Журнал регистрации и отладчик: вывести значение без участия пользователя

ЗаписьЖурналаРегистрации

В регламентном задании, HTTP-сервисе или обмене сообщение Сообщить() никто не увидит. Значения пишут в журнал регистрации:

ЗаписьЖурналаРегистрации("Обмен с сайтом.Загрузка заказов",
    УровеньЖурналаРегистрации.Информация,
    Метаданные.Документы.ЗаказКлиента,
    ДокументСсылка,
    "Загружено заказов: " + Формат(Количество, "ЧГ=0"));

Параметры по порядку: имя события, уровень, объект метаданных, данные (ссылка), комментарий. Уровни: Информация, Примечание, Предупреждение, Ошибка.

Где смотреть:

  • в конфигураторе — Администрирование → Журнал регистрации;
  • в типовых конфигурациях на БСП в пользовательском режиме — Администрирование → Обслуживание → Журнал регистрации.

В журнале поставьте отбор по имени события. Точка в имени («Обмен с сайтом.Загрузка заказов») — договорённость, удобная для группировки своих событий.

При ошибке в Попытка … Исключение пишите в комментарий ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()) — там будет стек вызовов и номер строки модуля.

Отладчик вместо сообщений

Для разработчика отладчик быстрее десятка Сообщить():

  1. Запустите базу из конфигуратора в режиме отладки.
  2. Поставьте точку останова на нужной строке клавишей F9.
  3. Когда выполнение остановится, выделите переменную и нажмите Shift+F9 — откроется окно «Вычислить выражение». Таблицы значений и структуры там раскрываются полностью.
  4. Чтобы следить за несколькими переменными сразу, добавьте их в «Табло».

Отладочные Сообщить() после работы удаляйте. Забытое сообщение в цикле проведения документа выдаст пользователю сотни строк.

Вывод в файл и во внешние системы

Текстовый файл

ИмяФайла = ПолучитьИмяВременногоФайла("txt");
Запись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8);
Для Каждого СтрокаТЗ Из ТаблицаТоваров Цикл
    Запись.ЗаписатьСтроку(Строка(СтрокаТЗ.Номенклатура) + Символы.Таб
        + Формат(СтрокаТЗ.Количество, "ЧГ=0"));
КонецЦикла;
Запись.Закрыть();

Без Закрыть() последние строки могут не попасть на диск, а файл останется заблокированным.

Excel, PDF, JSON

  • 📊 Табличный документ сохраняется одной строкой: ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX). Для PDF — ТипФайлаТабличногоДокумента.PDF.
  • 🔗 Структуру или массив в JSON выводят через ЗаписьJSON и ЗаписатьJSON():
Данные = Новый Структура("Номер, Сумма", "А-102", 15000);
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Данные);
ТекстJSON = Запись.Закрыть();

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

  • 🌐 Во внешнюю систему значение отправляют через HTTPСоединение и HTTPЗапрос: тело запроса задают методом УстановитьТелоИзСтроки(ТекстJSON).

Код на сервере пишет файл на диск сервера 1С, а не на компьютер пользователя. В клиент-серверной базе и в веб-клиенте файл передают на клиент: помещают во временное хранилище и получают на клиенте (например, ПолучитьФайл или НачатьПолучениеФайлаССервера).

Ошибки при выводе значений

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

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

Чем Сообщить() отличается от СообщениеПользователю?
Сообщить() просто выводит строку. СообщениеПользователю умеет привязать текст к полю формы или объекту: щелчок по сообщению переводит курсор в это поле.
Как вывести значение переменной в запросе?
Внутри текста запроса вывести нельзя. Выполните запрос, выгрузите результат в таблицу значений и посмотрите её в отладчике через «Вычислить выражение» или выведите циклом.
Можно ли вывести сообщение из модуля объекта при записи?
Да. Из обработчиков ПередЗаписью и ОбработкаПроверкиЗаполнения сообщения дойдут до пользователя. При отказе от записи установите Отказ = Истина, иначе объект запишется.
Как вывести значение с переносом строки?
Склейте части через Символы.ПС: Сообщить(“Строка 1” + Символы.ПС + “Строка 2”).
Как очистить окно сообщений из кода?
На клиенте вызовите ОчиститьСообщения(). Это удобно перед повторной проверкой формы, чтобы старые ошибки не путали пользователя.