При разработке механизмов журналирования в системе 1С программист часто сталкивается с дилеммой: какой объект метаданных лучше всего подходит для хранения истории операций? С одной стороны, нам нужна простота реализации, с другой — производительность, удобство интерфейса и надежность хранения данных. Разберем по шагам наиболее популярные подходы, проанализируем их сильные и слабые стороны, а также рассмотрим современные методы оптимизации логов.
Справочники часто выбирают для хранения журналов, так как они позволяют логически сгруппировать данные (например, через иерархию) и имеют встроенные табличные части. Однако стандартные реквизиты, такие как Наименование, часто кажутся лишними.
Многие разработчики ошибочно полагают, что длину наименования нельзя установить в 0. Проанализируем ситуацию: если просто поставить длину 0, платформа выдаст ошибку о невозможности использования поля для ввода по строке. Чтобы корректно настроить справочник-журнал, выполним следующие действия:
Наименование в 0.Наименование.После этого справочник станет «анонимным», что идеально подходит для лога. Главное преимущество справочника здесь — наличие табличной части, что позволяет хранить подробности каждой операции в привязке к одной записи «шапки».
С точки зрения методологии 1С, документ — это событие. Лог операции также является событием, поэтому объект Документ кажется наиболее естественным выбором. Рассмотрим особенности этого подхода:
Часто возникает вопрос равноправия дат (например, время начала и время окончания операции). В документе есть стандартный реквизит Дата. Мы можем использовать его как время создания записи (или время окончания), а для времени начала создать отдельный дополнительный реквизит типа Дата (состав даты — Дата и время). Проанализируем преимущества:
Дата индексируется по умолчанию, что ускоряет поиск за период.Если нам требуется «плоский» журнал, где каждая строка операции должна быть видна сразу без захода в карточку объекта, лучше всего использовать Регистры Сведений. Это наиболее производительный вариант для хранения больших объемов данных.
Рассмотрим схему с двумя регистрами, предложенную опытными разработчиками: один регистр хранит заголовки операций (шапку), а второй — детали (строки). Сопоставление идет по уникальному идентификатору (GUID). Это позволяет имитировать структуру «шапка-табличная часть», но с гораздо более высокой скоростью записи.
Пример кода для записи в независимый регистр сведений:
МенеджерЗаписи = РегистрыСведений.ЖурналОпераций.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Период = ТекущаяДата();
МенеджерЗаписи.ИдентификаторОперации = Новый УникальныйИдентификатор();
МенеджерЗаписи.Описание = "Выгрузка данных в ERP";
МенеджерЗаписи.Записать();
Критически важный нюанс при ведении журнала внутри 1С — это поведение системы при ошибках. Если вы записываете лог в справочник или регистр внутри транзакции основной операции, и эта операция завершается ошибкой (происходит ОтменаТранзакции()), то ваш лог также сотрется. Это делает журналирование ошибок бессмысленным.
Выясним причины и способы решения этой проблемы:
ЗаписьТекста позволяет дописывать строки в файл на диске. Файловая система не подчиняется транзакциям 1С, поэтому лог сохранится даже при «падении» базы.ЗаписьЖурналаРегистрации() записывает данные в системный лог 1С. Это быстро, надежно и не раздувает основную базу данных (таблицы SQL).Проанализируем ситуацию, когда журнал начинает занимать слишком много места. Чтобы база не «раздувалась», рассмотрим следующие рекомендации:
Хранение в формате JSON или XML. Вместо создания громоздких табличных частей, которые физически являются отдельными таблицами в СУБД, детали операции можно упаковать в одну строку неограниченной длины в формате JSON. Это значительно ускоряет запись объекта.
// Пример упаковки данных в JSON перед записью в реквизит лога
ПараметрыЛога = Новый Структура;
ПараметрыЛога.Вставить("Статус", "Успех");
ПараметрыЛога.Вставить("КоличествоСтрок", 150);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ПараметрыЛога);
РезультатСтрокой = ЗаписьJSON.Закрыть();
// Записываем РезультатСтрокой в реквизит справочника
Регламентная очистка. Любой журнал должен иметь «срок годности». Проанализируем необходимость создания регламентного задания, которое раз в сутки будет удалять записи старше 30 (или 90) дней. Для регистров сведений с периодом это делается максимально просто через удаление набора записей за период.
Подведем итог нашему анализу:
ЗаписьЖурналаРегистрации() или запись во внешние текстовые файлы.Выбор конкретного инструмента зависит от ваших задач, но помните: хороший журнал — это тот, который не мешает основной работе системы и легко очищается.