Что делать, если в серверном коде 1С нужно увидеть значение или текст
Содержание
Вывести сообщение на сервере 1С можно пятью способами: Новый СообщениеПользователю (или Сообщить()), запись в журнал регистрации через ЗаписьЖурналаРегистрации(), ВызватьИсключение, возврат значения в клиентскую процедуру и запись в текстовый лог-файл. Первый работает только тогда, когда серверный код вызван с клиента: сообщения копятся на сервере и показываются пользователю, как только вызов вернётся на клиент.
Если код выполняется без клиента — регламентное задание, HTTP-сервис, веб-сервис, обработчик обмена, — окна сообщений нет. Там отладочный вывод пишут в журнал регистрации или в файл. Всё ниже относится к платформе 8.3 и управляемому приложению; в файловом варианте «сервер» живёт внутри клиентского процесса, но правила видимости сообщений те же.
Куда уходит сообщение из серверного кода
Серверная процедура не может открыть окно. Предупреждение(), ПоказатьПредупреждение(), Вопрос() — методы клиента, на сервере их вызов даст ошибку ещё при компиляции модуля или при выполнении.
Зато объект СообщениеПользователю на сервере создать можно:
&НаСервере
Процедура ПроверитьОстаткиНаСервере()
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = СтрШаблон("Обработано строк: %1", Формат(Объект.Товары.Количество(), "ЧГ=0"));
Сообщение.Поле = "Объект.Товары";
Сообщение.Сообщить();
КонецПроцедуры
Что происходит с таким сообщением в разных контекстах:
| Где выполняется код | Увидит ли пользователь | Как прочитать |
|---|---|---|
| Серверная процедура формы, общий модуль с вызовом сервера | Да, после возврата на клиент | В окне сообщений формы |
| Фоновое задание | Не сразу | ФоновоеЗадание.ПолучитьСообщенияПользователю() |
| Регламентное задание | Нет | Журнал регистрации или файл |
| HTTP-сервис, веб-сервис | Нет | Журнал регистрации или файл |
| Обработчик проведения при программной записи из фона | Нет | Журнал регистрации |
💡 Сообщения не появляются по одному «в реальном времени». Если серверная процедура крутится 10 минут и пишет 500 сообщений, пользователь увидит их пачкой через 10 минут.
В типовых конфигурациях на БСП удобнее вызывать ОбщегоНазначения.СообщитьПользователю(Текст, КлючДанных, Поле, ПутьКДанным, Отказ). Он работает и на клиенте, и на сервере, а через параметр Поле привязывает сообщение к реквизиту формы: пользователь щёлкает по тексту — курсор встаёт в нужное поле.
Отладка через журнал регистрации
Журнал регистрации — главный инструмент, когда кода «у клиента» нет. Запись делается одной строкой и переживает перезапуск сервера.
ЗаписьЖурналаРегистрации("Обмен.ЗагрузкаЗаказов",
УровеньЖурналаРегистрации.Информация,
Метаданные.Документы.ЗаказКлиента,
ДокументСсылка,
СтрШаблон("Загружено позиций: %1", Формат(КоличествоСтрок, "ЧГ=0")));
Параметры по порядку:
- 📝 Имя события — строка. Задавайте его через точку:
Подсистема.Действие. Потом по нему удобно фильтровать. - 🚦 Уровень —
Информация,Предупреждение,ОшибкаилиПримечание. - 🗂 Метаданные — объект конфигурации, к которому относится запись. Можно не указывать.
- 🔗 Данные — ссылка на объект. Из журнала по ней можно открыть документ.
- 💬 Комментарий — сам текст отладочного вывода. Сюда кладите значения переменных.
В англоязычном синтаксисе метод называется WriteLogEvent. В поиске его часто ищут как «WriteToLog», но такого метода в платформе нет.
Как найти запись
- В Конфигураторе:
Администрирование → Журнал регистрации. - В пользовательском режиме «Такси»:
Главное меню → Все функции → Стандартные → Журнал регистрации(команда «Все функции» включается в параметрах программы). - В БП 3.0, ЗУП 3.1, УТ 11: раздел
Администрирование → Обслуживание, группа с протоколами работы программы.
В форме журнала поставьте отбор по имени события и по уровню. Без отбора свою строку среди тысяч записей о входах пользователей не найти.
Запись внутри транзакции
У метода есть шестой параметр — режим транзакции. По умолчанию запись независимая: она остаётся в журнале, даже если транзакция откатилась. Для отладки это ровно то, что нужно: вы увидите, до какого шага дошёл код перед ошибкой.
Транзакционный режим (РежимТранзакцииЗаписиЖурналаРегистрации.Транзакционная) пишет запись только при успешной фиксации транзакции. Для поиска причины отката он бесполезен.
Не превращайте журнал в свалку. Запись в цикле на 100 000 строк раздувает журнал на сотни мегабайт и замедляет его открытие для всех. Пишите итог и выборочные значения, а после отладки удаляйте вызовы или переводите их под флаг.
Исключение как способ остановить код и показать текст
ВызватьИсключение прерывает выполнение и поднимает текст наверх. Если серверный вызов шёл с клиента, пользователь увидит окно с ошибкой и вашим текстом, а транзакция откатится.
Если Не ЗначениеЗаполнено(Контрагент) Тогда
ВызватьИсключение СтрШаблон("Не заполнен контрагент в строке %1", НомерСтроки);
КонецЕсли;
Где это уместно:
- 🛑 проверка входных данных, после которой продолжать бессмысленно;
- 🔍 быстрая «точка останова для бедных»: вставили
ВызватьИсключение Строка(Сумма);и посмотрели значение; - 📦 код в транзакции, который должен откатиться целиком.
Перехват с подробностями выглядит так:
Попытка
ЗагрузитьФайл(ИмяФайла);
Исключение
Инфо = ИнформацияОбОшибке();
ЗаписьЖурналаРегистрации("Обмен.Ошибка", УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(Инфо));
ВызватьИсключение КраткоеПредставлениеОшибки(Инфо);
КонецПопытки;
Подробное представление со стеком вызовов уходит в журнал, а пользователю — короткий текст без строк модулей. Голое ВызватьИсключение; без текста внутри блока Исключение пробрасывает исходную ошибку дальше без изменений.
💡 В регламентном задании необработанное исключение тоже попадает в журнал регистрации, вместе со стеком. Поэтому иногда достаточно не глушить ошибки пустым Исключение КонецПопытки.
Возврат результата на клиент
Самый чистый способ для форм: сервер ничего не «выводит», а возвращает данные. Клиент сам решает, как их показать — сообщением, предупреждением или вопросом.
&НаКлиенте
Процедура Проверить(Команда)
Результат = ПроверитьНаСервере();
Если Не Результат.Успех Тогда
ПоказатьПредупреждение(, Результат.Текст);
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПроверитьНаСервере()
Результат = Новый Структура("Успех, Текст", Истина, "");
Если Объект.Товары.Количество() = 0 Тогда
Результат.Успех = Ложь;
Результат.Текст = "Табличная часть пуста";
КонецЕсли;
Возврат Результат;
КонецФункции
Плюсы такого подхода:
- ✅ на клиенте доступны модальные и немодальные окна, которых нет на сервере;
- ✅ серверная функция легко тестируется и вызывается из других мест;
- ✅ в структуру можно сложить массив ошибок и показать их списком.
Ограничение одно: возвращать можно только сериализуемые значения. Структура, массив, строка, число, ссылка — да. ТаблицаЗначений на клиент не передаётся: преобразуйте её в массив структур или положите во временное хранилище через ПоместитьВоВременноеХранилище() и верните адрес.
Лог-файл на стороне сервера
Когда нужен длинный протокол — например, построчный разбор загрузки на 20 000 строк, — удобнее файл. Его можно открыть любым редактором и искать в нём по тексту.
ИмяЛога = КаталогВременныхФайлов() + "debug_obmen.log";
Лог = Новый ЗаписьТекста(ИмяЛога, КодировкаТекста.UTF8, , Истина);
Лог.ЗаписатьСтроку(СтрШаблон("%1 | %2 | %3",
Формат(ТекущаяДатаСеанса(), "ДФ='dd.MM.yyyy HH:mm:ss'"),
НомерСтроки, Артикул));
Лог.Закрыть();
Четвёртый параметр Истина — режим дополнения: каждая запись добавляется в конец, а не перезаписывает файл.
Что учесть:
- 🖥 В клиент-серверном варианте файл появится на компьютере сервера 1С, а не у вас. Путь
C:\Tempв коде — это диск сервера. - 🔐 Писать в каталог должна иметь право учётная запись службы агента сервера (по умолчанию
USR1CV8). Нет прав — получите ошибку записи файла. - 👥 Если код выполняют несколько сеансов, они пишут в один файл одновременно. Добавляйте в имя файла номер сеанса или идентификатор, чтобы строки не перемешивались.
- 🧹
КаталогВременныхФайлов()на сервере чистят. Для протокола, который нужен завтра, укажите постоянную папку.
Файловый вариант базы
В файловой базе серверный код выполняется в том же процессе, что и клиент. Поэтому лог-файл окажется на компьютере пользователя, который запустил операцию, а права на запись — права его учётной записи Windows. Код, который «работает у программиста» на файловой копии, после переноса в клиент-серверную базу может упасть с ошибкой доступа к каталогу. Проверяйте путь и права на той машине, где реально крутится рабочий процесс 1С.
Чтобы включать протокол без правки кода, заведите константу или параметр сеанса «Режим отладки» и пишите в файл только при включённом флаге. Тогда в рабочей базе вывод выключен, а при разборе проблемы его включают на час и отключают обратно.
Не оставляйте файловое логирование в рабочей базе после отладки. Файл растёт без ограничений и может занять весь диск сервера, после чего встанут все базы на нём.
Фоновые задания, отладчик и технологический журнал
Сообщения из фонового задания
Сообщения, сформированные в фоне через СообщениеПользователю, никуда не пропадают — они копятся в самом задании. Клиент забирает их так:
Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
Если Задание <> Неопределено Тогда
Для Каждого Сообщение Из Задание.ПолучитьСообщенияПользователю(Истина) Цикл
Сообщение.Сообщить();
КонецЦикла;
КонецЕсли;
Параметр Истина удаляет полученные сообщения, чтобы при следующем опросе не показывать их повторно. В БСП это уже сделано в механизме длительных операций: прогресс и сообщения выводятся автоматически.
Отладчик вместо сообщений
Часто «вывести сообщение» хотят, потому что не работает
остановка в серверном коде. В клиент-серверном варианте сервер отладки нужно разрешить: агент сервера запускается с ключом -debug в параметрах службы. Без него точки останова на сервере не срабатывают.
Чтобы добавить ключ, службу агента перезапускают. Все сеансы пользователей на этом сервере оборвутся — делайте это вне рабочего времени или на тестовом сервере.
После этого в Конфигураторе подключитесь к предметам отладки (сервер, фоновые задания) и ставьте точки останова прямо в общих модулях. Это быстрее, чем вставлять и удалять вывод.
Технологический журнал
Для проблем, которые воспроизводятся только на рабочем сервере, есть технологический журнал платформы. Он настраивается файлом logcfg.xml в каталоге настроек сервера и пишет события: исключения (EXCP), долгие запросы, блокировки. Свой текст туда не выведешь, зато видно, где упал код, даже если программист ничего не логировал.
Какой способ выбрать
| Способ | Когда применять | Где читать | Риски |
|---|---|---|---|
СообщениеПользователю | Сервер вызван из формы | Окно сообщений | Не виден в регламентных заданиях и сервисах |
| Журнал регистрации | Регламентные задания, обмены, сервисы | Форма журнала, отбор по событию | Разрастание журнала при записи в цикле |
ВызватьИсключение | Нужно прервать выполнение | Окно ошибки, журнал | Откатывает транзакцию, останавливает процесс |
| Возврат значения | Формы, проверки перед действием | Клиентский код | Только сериализуемые типы |
| Лог-файл | Длинный построчный протокол | Файл на сервере 1С | Права, конкурентная запись, рост диска |
| Сообщения фонового задания | Длительные операции | Клиент опрашивает задание | Без опроса сообщения не увидит никто |
Короткое правило: в интерактивном коде — сообщение или возврат значения, в неинтерактивном — журнал регистрации, для разбора больших объёмов — файл.
Ошибки при отладке серверного кода
- ❌ Ищут лог-файл у себя на диске. В клиент-серверном варианте он на сервере 1С. Попросите администратора или пишите в общую сетевую папку, куда у службы есть права.
- ❌ Ждут сообщения посреди долгой операции. До возврата на клиент их не будет. Для прогресса нужен фон и опрос задания.
- ❌ Пишут в журнал транзакционно. При откате записи исчезают вместе с данными, и кажется, что код до этого места не дошёл.
- ❌ Глушат ошибку пустым
Исключение КонецПопытки. Код «работает», но молча ничего не делает. Минимум — записьПодробноеПредставлениеОшибки()в журнал. - ❌ Склеивают числа со строкой без
Формат. Сумма1500000превращается в1 500 000с неразрывными пробелами, и поиск по журналу перестаёт находить значение. ИспользуйтеФормат(Число, "ЧГ=0"). - ❌ Забывают убрать отладочный вывод. Сотни записей «отладка 1», «отладка 2» в рабочем журнале мешают искать настоящие ошибки.