При разработке и доработке типовых конфигураций на платформе 1С:Предприятие 8.3 (в частности, в «Бухгалтерии предприятия 3.0») программисты часто сталкиваются с ситуацией: в коде модуля менеджера пишется метод Сообщить() или создается объект СообщениеПользователю, однако при нажатии кнопки заполнения на форме никаких сообщений на экране не появляется. Более того, точка останова в конфигураторе упорно игнорируется, хотя на клиенте и в модуле объекта отладка работает штатно.
Разберем детально, почему это происходит и какими способами можно гарантированно получить и проанализировать сформированный текст запроса.
Проанализируем техническую сторону выполнения операций заполнения в современных конфигурациях на управляемых формах:
Сообщить() или СообщениеПользователю внутри фонового задания, не отправляются напрямую на клиент. Они перехватываются платформой и сохраняются во внутреннем буфере фонового задания. Если вызывающий процедуру клиентский код явно не считывает массив сообщений из фонового задания, пользователь их не увидит.ОчиститьСообщения(), стирающий все накопленные уведомления.Если необходимо остановить выполнение кода на сервере внутри модуля менеджера и посмотреть значение переменной с текстом запроса в табло отладчика, настроим конфигуратор следующим образом:
Запрос.Текст = ТекстЗапросаИнвентаризация;
Возврат Запрос; // Точка останова здесь
После включения этой настройки повторим действие на клиенте (например, нажмем кнопку «Заполнить по остаткам»). Конфигуратор автоматически перехватит инициализированный сервером фоновый поток и выполнит остановку на указанной строке, после чего переменную ТекстЗапросаИнвентаризация можно будет изучить в окне «Вычислить выражение» (Shift+F9).
Если нет возможности перенастраивать отладку или сеанс выполняется на удаленном сервере без прямого доступа к отладчику, самым простым и надежным способом является аварийная остановка алгоритма с выводом интересующего текста. Ошибка серверного метода передается на клиент в виде диалогового окна даже при работе через фоновое задание.
Разберем пример вызова исключения перед выполнением запроса:
Запрос.Текст = ТекстЗапросаИнвентаризация;
// Принудительно вызываем ошибку и передаем текст запроса в описание
ВызватьИсключение ТекстЗапросаИнвентаризация;
Возврат Запрос;
В момент вызова функции выполнение алгоритма прервется, а на экране откроется стандартное окно с текстом исключения, откуда сформированный запрос можно скопировать для проверки в консоли запросов.
Когда требуется увидеть итоговый запрос без остановки бизнес-процесса и без изменения поведения программы для пользователя, используем запись события в системный журнал регистрации.
Посмотрим на пример кода:
Запрос.Текст = ТекстЗапросаИнвентаризация;
// Фиксируем текст запроса на сервере
ЗаписьЖурналаРегистрации(
"ОтладкаЗапроса",
УровеньЖурналаРегистрации.Информация,
,
,
ТекстЗапросаИнвентаризация
);
Возврат Запрос;
После отработки кнопки заполнения перейдем в раздел Администрирование → Обслуживание → Журнал регистрации, отфильтруем события по событию ОтладкаЗапроса и прочитаем полный текст запроса со всеми подставленными условиями.
Если запрос содержит огромный объем данных, объединений или временных таблиц, текст может быть неудобно просматривать через окно ошибки или журнал. В этом случае выгрузим его в текстовый файл на диске сервера 1С:
Запрос.Текст = ТекстЗапросаИнвентаризация;
// Записываем результат формирования текста на диск
ТекстовыйФайл = Новый ЗаписьТекста("C:\temp\query_debug.txt", КодировкаТекста.UTF8);
ТекстовыйФайл.Записать(ТекстЗапросаИнвентаризация);
ТекстовыйФайл.Закрыть();
Возврат Запрос;
Важно: убедимся, что каталог, указанный в пути (в данном примере C:\temp\), реально существует на стороне сервера 1С, а у пользователя операционной системы, от имени которого запущена служба ragent (сервер 1С), есть права на запись в эту папку.
Если мы хотим использовать штатный механизм сообщений, учитываем, что объекту СообщениеПользователю при вызове с сервера часто требуется указание целевого контекста (идентификатора формы или поля). В простом серверном коде без привязки к форме сообщение может теряться платформой:
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ТекстЗапросаИнвентаризация;
// Если процедура вызвана из формы, передается ИдентификаторНазначения
Сообщение.Сообщить();
Однако в случаях, когда алгоритм обернут в длительную операцию БСП, использование СообщениеПользователю все равно не выведет текст на форму до тех пор, пока процедура ожидания завершения фонового задания на клиенте не распакует накопленный массив сообщений. По этой причине для задач отладки гораздо эффективнее применять настройку подключения к фоновым заданиям или метод ВызватьИсключение.