Как правильно вести лог созданных документов в управляемых формах 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ проблемы: почему перезаписывается файл лога?

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


Функция ЗаписатьЛог(Лог) Экспорт
    Если НЕ Лог = "" Тогда
        ТекДокумент = Новый ТекстовыйДокумент;
        ТекДокумент.УстановитьТекст("НАЧАЛО:" + Символы.ПС + Лог);
        ТекДокумент.УстановитьТипФайла(КодировкаТекста.UTF8);   
        ТекДокумент.Записать("c:\55.txt");
    КонецЕсли;
КонецФункции

При таком подходе в файле на диске всегда остается только одна строка — о последнем созданном документе. Выясним причину этого поведения. Дело в том, что метод УстановитьТекст() полностью очищает объект ТекстовыйДокумент и заполняет его переданной строкой с нуля. А метод Записать() перезаписывает физический файл на диске заново. Таким образом, при каждом новом вызове функции предыдущие записи просто уничтожаются.

Кроме того, в коде присутствует критическая архитектурная ошибка: запись файла по абсолютному пути "c:\55.txt" происходит на стороне сервера (директива &НаСервере). В клиент-серверном варианте работы системы этот файл будет создаваться на жестком диске сервера приложений 1С, а не на локальном компьютере пользователя. Пользователь-бухгалтер этот файл у себя просто не найдет, а у службы сервера 1С может не хватить прав на запись в корень диска С, что вызовет аварийное завершение работы программы.

Давайте разберем по шагам, как исправить эти ошибки и сделать логирование надежным и удобным.

Решение 1. Правильная дозапись в текстовый файл на сервере

Если вам обязательно нужно сохранять лог именно в текстовый файл, то вместо объекта ТекстовыйДокумент гораздо эффективнее использовать объект ЗаписьТекста в режиме добавления данных.

Проанализируем пример функции дозаписи, которая корректно добавляет новые строки в конец файла, не затирая старые:


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

Если же вы используете объект ТекстовыйДокумент, то перед добавлением новой строки файл необходимо сначала прочитать с диска:


&НаСервере
Процедура ЗаписатьВЛогЧерезТекстовыйДокумент(ТекстЛога, ПутьКФайлу)
    ТекДокумент = Новый ТекстовыйДокумент;
    
    // Проверяем наличие файла на диске перед чтением
    ФайлНаДиске = Новый Файл(ПутьКФайлу);
    Если ФайлНаДиске.Существует() Тогда
        ТекДокумент.Прочитать(ПутьКФайлу, КодировкаТекста.UTF8);
    КонецЕсли;
    
    // Добавляем новую строку в конец документа
    ТекДокумент.ДобавитьСтроку("" + ТекущаяДата() + " | " + ТекстЛога);
    ТекДокумент.Записать(ПутьКФайлу, КодировкаТекста.UTF8);
КонецПроцедуры

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

Решение 2. Оптимальный вариант для УФ — вывод лога в таблицу на форме

Запись лога в текстовый файл — это устаревший подход, который неудобен для конечного пользователя. Бухгалтеру гораздо удобнее сразу увидеть список созданных документов на экране компьютера и иметь возможность кликнуть по ним, чтобы открыть форму документа.

Посмотрим, как реализовать интерактивный лог с использованием реквизитов управляемой формы. Поскольку серверные процедуры создания документов выполняются в контексте формы, они имеют прямой доступ к ее реквизитам.

Выполним следующие шаги:

  1. В редакторе управляемой формы перейдем на вкладку Реквизиты и добавим новый реквизит формы с типом ТаблицаЗначений. Назовем его ЛогДокументов.
  2. Добавим в созданную таблицу две колонки:
    • ДокументСсылка (тип: ДокументСсылка или ЛюбаяСсылка) — для хранения ссылки на созданный документ;
    • Сообщение (тип: Строка) — для описания результата операции.
  3. Перетащим таблицу ЛогДокументов в окно элементов формы. Система автоматически создаст элемент управления "Таблица". Настроим у поля ссылки отображение в виде гиперссылки, чтобы пользователь мог открывать созданные объекты одним кликом.

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


&НаКлиенте
Процедура СформироватьДокументы(Команда)
    
    // Очищаем лог перед новым запуском
    ЛогДокументов.Очистить();
    
    // Запускаем последовательное создание документов на сервере
    СформироватьДокументыНаСервере();
    
КонецПроцедуры

&НаСервере
Процедура СформироватьДокументыНаСервере()
    
    // 1. Создание договора ГПХ
    СсылкаГПХ = СформироватьДокументГПХНаСервере();
    ДобавитьЗаписьВЛог(СсылкаГПХ, "Успешно создан документ Договор ГПХ");
    
    // 2. Создание начисления
    СсылкаНачисление = СформироватьДокументНачислениеНаСервере();
    ДобавитьЗаписьВЛог(СсылкаНачисление, "Успешно создан документ Начисление по договорам");
    
    // 3. Создание ведомости
    СсылкаВедомость = СформироватьДокументВедомостьНаСервере();
    ДобавитьЗаписьВЛог(СсылкаВедомость, "Успешно создан документ Ведомость на выплату");
    
КонецПроцедуры

&НаСервере
Процедура ДобавитьЗаписьВЛог(СсылкаНаОбъект, ТекстСообщения)
    
    // Добавляем строку непосредственно в реквизит формы типа ТаблицаЗначений
    НоваяСтрока = ЛогДокументов.Добавить();
    НоваяСтрока.ДокументСсылка = СсылкаНаОбъект;
    НоваяСтрока.Сообщение = ТекстСообщения;
    
КонецПроцедуры

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

Решение 3. Использование механизмов БСП (Библиотеки стандартных подсистем)

Если ваша конфигурация разработана на базе типовых решений 1С (например, 1С:ERP, КА, УТ или ЗУП), вы можете использовать встроенные механизмы оповещения пользователей. Это позволит сократить объем вашего кода и сделать интерфейс более стандартным.

Интерактивные сообщения пользователю:

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


// Пример использования в серверном коде
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
    "Создан документ: " + Строка(НовыйДокумент.Ссылка),
    НовыйДокумент.Ссылка
);

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

Всплывающие уведомления (оповещения):

В завершение процедуры на стороне клиента мы можем показать красивое всплывающее уведомление в правом нижнем углу экрана:


&НаКлиенте
Процедура СформироватьДокументы(Команда)
    
    СформироватьДокументыНаСервере();
    
    // Показываем стандартное оповещение операционной системы
    ПоказатьОповещениеПользователя(
        "Загрузка завершена успешно!", 
        , 
        "Все документы созданы и проведены", 
        БиблиотекаКартинок.Информация
    );
    
КонецПроцедуры

Подведем итоги. Для ведения технического лога (для администраторов) лучше использовать стандартный ЖурналРегистрации или запись в файл методом ЗаписьТекста с флагом дозаписи. Для вывода бизнес-информации конечным пользователям (бухгалтерам) оптимальным и наиболее дружелюбным решением является использование реквизита формы в виде таблицы или использование интерактивных сообщений БСП.

← На главную