При разработке механизмов логирования для регламентных заданий или других серверных процедур программисты часто сталкиваются с ситуацией, когда код, успешно работающий в локальной обработке, «падает» с ошибкой при выполнении на сервере. Рассмотрим подробнее типичную проблему, когда объект ТекстовыйДокумент внезапно перестает вести себя как объект, и разберем способы её решения.
Проанализируем ситуацию, описанную пользователем. При вызове метода Записать() или ДобавитьСтроку() система выдает исключение: «Значение не является значением объектного типа». Проверка через отладчик показывает, что переменная, в которой должен находиться объект ТекстовыйДокумент, внезапно имеет тип Строка.
Выясним причину. В языке 1С идентификаторы переменных нечувствительны к регистру. Если в заголовке функции или процедуры уже объявлен параметр с именем текст, а внутри тела метода вы пытаетесь создать локальную переменную с тем же именем (например, Текст = Новый ТекстовыйДокумент), возникает конфликт имен. Платформа приоритетно работает с параметром функции.
Посмотрим на пример кода, содержащего ошибку:
Функция ОтправитьОдноПисьмо(Пользователь, Тема, Текст, Вложение = Неопределено)
// Ошибка! Переменная "Текст" уже определена как входящий параметр (строка)
Текст = Новый ТекстовыйДокумент;
Текст.ДобавитьСтроку("Лог отправки...");
Текст.Записать("C:\Logs\log.txt");
КонецФункции
В данном случае переназначение параметра Текст новым объектом может привести к непредсказуемому поведению или путанице в логике программы. Чтобы избежать подобных ситуаций, мы рекомендуем придерживаться стандартов разработки 1С:
пТекст или ОбъектТекст).ТекстовыйЛог, ДокументЛога или ФайлПротокола.Если проблема с именами переменных решена, но файл все равно не записывается, проанализируем контекст выполнения кода. Регламентные задания всегда выполняются на стороне сервера. Это накладывает ряд ограничений:
1. Отсутствие локальных дисков пользователя. Если вы прописываете путь E:\Dmitry\1clog\, вы должны быть уверены, что диск E: физически существует на сервере приложений 1С. Пути, доступные на вашем компьютере, могут быть недоступны серверу.
2. Права доступа службы. Агент сервера 1С:Предприятия (обычно работающий под учетной записью USR1CV8) должен иметь полные права (чтение, запись, изменение) на папку, в которую производится запись лога. По умолчанию у серверной службы нет доступа к профилям пользователей (папки "Рабочий стол", "Документы").
3. Кроссплатформенность. Если сервер 1С работает под управлением ОС Linux, пути вида C:\Temp работать не будут. Разберем, как сделать код универсальным:
Разделитель = ПолучитьРазделительПути();
ПутьКЛогу = "var" + Разделитель + "log" + Разделитель + "1c" + Разделитель + "mylog.log"; // Для Linux
// Либо используйте временный каталог сервера:
ПутьКЛогу = КаталогВременныхФайлов() + "my_process_log.txt";
Рассмотрим техническую сторону вопроса. Объект ТекстовыйДокумент удобен тем, что позволяет легко манипулировать строками, однако он имеет существенный недостаток при логировании: при вызове метода Записать() он перезаписывает файл целиком, предварительно загружая его содержимое в память. Если ваш лог вырастет до 100 Мб, каждое добавление строки будет вызывать значительную нагрузку на сервер.
Для задач логирования правильнее использовать объект ЗаписьТекста. Посмотрим на пример реализации производительного логирования:
Процедура ЗаписатьВЛог(Сообщение)
ПутьФайла = "C:\Logs\service.log";
// Параметр Дописывать = Истина позволяет добавлять данные в конец файла без перечитывания
Запись = Новый ЗаписьТекста(ПутьФайла, КодировкаТекста.UTF8, , Истина);
Запись.ЗаписатьСтроку("" + ТекущаяДата() + ": " + Сообщение);
Запись.Закрыть();
КонецПроцедуры
Преимущества ЗаписьТекста:
UTF8 для корректного отображения кириллицы в любых системах).Вместо создания внешних текстовых файлов, проанализируем возможность использования стандартного механизма 1С — Журнала регистрации. Это избавляет от необходимости следить за правами на папки и структурой дисков.
Используем метод ЗаписьЖурналаРегистрации():
ЗаписьЖурналаРегистрации("МойПроцесс.ОтправкаПисем",
УровеньЖурналаРегистрации.Информация,
,
,
"Письмо пользователю " + пПользователь + " успешно отправлено.");
Такой лог доступен в типовом интерфейсе 1С, его легко фильтровать, и он автоматически обслуживается платформой.
Часто программисты жалуются, что «отладчик молчит». Чтобы точка останова сработала в общем модуле при выполнении регламентного задания, выполним следующие шаги:
-debug.Только после этого вы сможете увидеть реальные значения переменных (например, тип переменной Текст) в момент выполнения кода сервером.
Подведем итог: чаще всего ошибка «ТекстовыйДокумент не работает» в общем модуле связана либо с невнимательностью при именовании переменных (shadowing), либо с отсутствием прав доступа серверной службы к файловой системе. Использование ЗаписьТекста и правильная настройка прав доступа решают эти проблемы в большинстве случаев.