Разработка и Конфигурация · 11 мин
Как программно очистить сообщения в 1С
Как программно удалить сообщения в 1С: очистка системы взаимодействия, журнала регистрации и сообщений пользователю. Готовый код, риски и проверка результата.
Под «сообщениями» в 1С обычно понимают три разных объекта: сообщения системы взаимодействия (чат внутри базы), записи журнала регистрации и служебные сообщения пользователю, которые формируются кодом через объект СообщениеПользователю. Подход к очистке у каждого из них свой, и смешивать их нельзя: то, что работает для чата, не применимо к журналу регистрации.
Программная очистка нужна, когда база разрослась из-за истории переписки, когда журнал регистрации занимает гигабайты и замедляет выгрузку, или когда тестовая база должна быть очищена от служебного мусора перед передачей. Ниже разобраны конкретные методы для каждого сценария с готовым кодом на встроенном языке 1С.
Все операции удаления необратимы. Перед запуском любого кода на рабочей базе сделайте выгрузку .dt или резервную копию средствами СУБД — это единственный способ откатить ошибку.
Определяем, какие именно сообщения нужно очистить
Прежде чем писать код, уточните, где физически хранятся данные, которые вы хотите удалить. Сообщения системы взаимодействия хранятся в отдельном механизме платформы и доступны через объект СообщенияСистемыВзаимодействия. Журнал регистрации — это файлы .lgd (в файловой базе) или таблица EventLog (в клиент-серверной). Сообщения пользователю существуют только в рамках сеанса и вообще не хранятся в базе.
Отдельный случай — «сообщения» как прикладные данные: например, регистры сведений или справочники, в которых конфигурация хранит историю уведомлений, очередь рассылок или логи обменов. Они очищаются как обычные данные — через набор записей или удаление объектов.
Очистка сообщений системы взаимодействия
Для работы с сообщениями чата используется менеджер СообщенияСистемыВзаимодействия. Чтобы удалить конкретное сообщение, нужно знать его идентификатор. Типовой сценарий — получить выборку сообщений обсуждения за период и удалить их по одному.
Функция ОчиститьСообщенияОбсуждения(ИдентификаторОбсуждения, ЗаПериодДо = Неопределено) Экспорт
Отбор = Новый ОтборСообщенийСистемыВзаимодействия;
Отбор.Обсуждение = ИдентификаторОбсуждения;
Выборка = СообщенияСистемыВзаимодействия.ВыбратьСообщения(Отбор);
Удалено = 0;
Для Каждого Сообщение Из Выборка Цикл
Если ЗаПериодДо <> Неопределено
И Сообщение.Дата > ЗаПериодДо Тогда
Продолжить;
КонецЕсли;
Попытка
СообщенияСистемыВзаимодействия.УдалитьСообщение(Сообщение.Идентификатор);
Удалено = Удалено + 1;
Исключение
ЗаписьЖурналаРегистрации("ОчисткаСообщений",
УровеньЖурналаРегистрации.Ошибка, , ,
ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Возврат Удалено;
КонецФункции
Обратите внимание на ограничения: удалять сообщения может пользователь с административными правами на систему взаимодействия, а удаление чужих сообщений может быть запрещено настройками сервера взаимодействия. Если база подключена к внешнему серверу взаимодействия (например, 1С:Диалог), учитывайте, что удаление происходит на сервере, а не только в локальной базе.
Массовую очистку лучше запускать порциями и вне часов активной работы пользователей: при большом количестве сообщений операция выполняется не мгновенно и создаёт нагрузку на сервер взаимодействия.
Сокращение журнала регистрации
Журнал регистрации — самая частая причина разрастания файловых баз. Платформа предоставляет метод СократитьЖурналРегистрации, который удаляет записи до указанной даты и записывает остаток в новый файл. Это единственный корректный способ программной очистки журнала.
Процедура СократитьЖурнал() Экспорт
ДатаОтсечки = ДобавитьМесяц(ТекущаяДатаСеанса(), -3);
Попытка
СократитьЖурналРегистрации(ДатаОтсечки,
КаталогВременныхФайлов() + "log_backup.lgd");
Исключение
ВызватьИсключение "Не удалось сократить журнал регистрации: "
+ ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Второй параметр метода — путь к файлу, куда будут сохранены удаляемые записи. Это удобно: старая история не теряется безвозвратно, а складывается в архивный файл, который можно хранить отдельно. Если архив не нужен, параметр можно опустить, но тогда записи старше даты отсечки будут удалены безвозвратно.
В клиент-серверном варианте сокращение журнала требует монопольного доступа к базе или выполняется в моменты минимальной активности — уточните поведение для вашей версии платформы. Никогда не удаляйте файлы .lgd вручную из каталога базы: это может привести к повреждению журнала и ошибкам при открытии.
Очистка сообщений пользователю в коде
Сообщения, которые код выводит через СообщениеПользователю, не хранятся в базе — они живут в контексте сеанса до момента показа. Однако бывает нужно программно очистить накопленную очередь, например, чтобы не показывать пользователю сотню технических сообщений после пакетной обработки.
// Получить и одновременно удалить все накопленные сообщения
МассивСообщений = ПолучитьСообщенияПользователю(Истина);
// Если нужно оставить только важные — фильтруем
Для Каждого Сообщение Из МассивСообщений Цикл
Если СтрНайти(Сообщение.Текст, "Ошибка") > 0 Тогда
Сообщение.Сообщить(); // показываем только ошибки
КонецЕсли;
КонецЦикла;
Параметр Истина в ПолучитьСообщенияПользователю означает, что полученные сообщения удаляются из очереди. Это удобно в длительных фоновых операциях: промежуточные сообщения очищаются, а пользователю выводится только итоговый результат.
Очистка прикладных регистров и очередей сообщений
Во многих конфигурациях есть собственные механизмы сообщений: регистры сведений с историей уведомлений, очереди исходящих писем, логи обмена данными. Их очистка выполняется стандартными средствами работы с данными. Для регистра сведений без измерений или с отбором по периоду удобнее всего писать через набор записей.
Процедура ОчиститьСтарыеУведомления(СрокХраненияДней = 30) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Уведомления.Период КАК Период
|ИЗ
| РегистрСведений.ИсторияУведомлений КАК Уведомления
|ГДЕ
| Уведомления.Период < &ДатаОтсечки";
Запрос.УстановитьПараметр("ДатаОтсечки",
ТекущаяДатаСеанса() - СрокХраненияДней * 86400);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
НаборЗаписей = РегистрыСведений.ИсторияУведомлений.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Период.Установить(Выборка.Период);
НаборЗаписей.Записать(Истина); // пустой набор = удаление записей
КонецЦикла;
КонецПроцедуры
Приём «записать пустой набор с отбором» работает быстрее, чем удаление записей по одной, и выполняется одной транзакцией на каждую порцию. Для очень больших таблиц удаляйте порциями по периодам, чтобы не блокировать работу пользователей длинной транзакцией.
- 1Сделайте выгрузку базы .dt или резервную копию СУБД
- 2Определите тип сообщений: система взаимодействия, журнал регистрации или прикладные данные
- 3Протестируйте код на копии базы и проверьте результат отбора
- 4Запустите очистку на рабочей базе вне пиковой нагрузки
- 5Проверьте результат и зафиксируйте, что и когда было удалено
Организация регулярной очистки через регламентное задание
Разовая очистка решает проблему сейчас, но не предотвращает повторного разрастания. Практичный вариант — оформить процедуру очистки как регламентное задание с расписанием, например, раз в неделю в ночное время. Для этого метод размещают в общем модуле с признаком «Сервер» и добавляют в список регламентных заданий конфигурации или подключают через механизм дополнительных обработок.
В коде регламентной очистки обязательно предусмотрите: запись результата в журнал регистрации (сколько удалено, сколько времени заняло), обработку ошибок без прерывания всего задания и ограничение глубины хранения через параметр, а не зашитую константу. Это позволит менять политику хранения без изменения кода.
Удобно хранить срок хранения сообщений в константе или в настройках хранилища общих настроек, а не в коде. Тогда администратор может изменить политику хранения через интерфейс, не обращаясь к разработчику и не обновляя конфигурацию.
Проверка результата и частые проблемы
После очистки убедитесь, что данные действительно удалены и система работает корректно. Для системы взаимодействия откройте обсуждение и проверьте, что старые сообщения исчезли. Для журнала регистрации откройте его в конфигураторе и установите отбор по дате до отсечки — записей быть не должно. Для прикладных регистров выполните контрольный запрос по количеству записей.
Если после сокращения журнала размер базы не уменьшился — это нормально для клиент-серверного варианта: файлы СУБД не сжимаются автоматически, место освобождается внутри файла и будет переиспользовано. Для физического уменьшения файлов потребуется сжатие средствами СУБД, что уже задача администратора баз данных.
Как проверить результат
Записи старше даты отсечки отсутствуют, журнал открывается без ошибок
Ошибка при открытии журнала или записи остались — операция не завершилась
Старые сообщения не отображаются в обсуждениях
Сообщения на месте — проверьте права и корректность идентификаторов
Количество записей уменьшилось согласно отбору
Записи остались — проверьте условия отбора и права на объект
Часто задаваемые вопросы
Можно ли восстановить удалённые сообщения системы взаимодействия?
Штатных средств восстановления нет. Единственный вариант — восстановить базу из резервной копии, сделанной до удаления. Поэтому перед массовой очисткой копия обязательна.
Почему СократитьЖурналРегистрации завершается с ошибкой?
Чаще всего причины две: недостаточно прав (нужны административные права на информационную базу) или активные сеансы пользователей в клиент-серверном варианте. Также проверьте, что путь к файлу-архиву доступен для записи от имени учётной записи сервера 1С.
Как удалить все сообщения конкретного пользователя, а не обсуждения?
В отборе сообщений системы взаимодействия укажите автора: Отбор.Автор = ПользовательСистемыВзаимодействия. Затем пройдите по выборке и удаляйте сообщения по идентификаторам, как в примере с обсуждением. Учитывайте, что для удаления чужих сообщений нужны соответствующие права.
Безопасно ли очищать журнал регистрации полностью?
Технически — да, но с точки зрения аудита и расследования инцидентов это плохая практика. Обычно оставляют историю за последние один–три месяца, а удаляемую часть сохраняют в архивный файл через второй параметр метода СократитьЖурналРегистрации.
Можно ли выполнять очистку из внешней обработки без изменения конфигурации?
Да. Весь приведённый код работает во внешней обработке, запускаемой через «Файл — Открыть» в режиме предприятия, если у пользователя достаточно прав. Для регулярного запуска удобнее подключить обработку через механизм дополнительных отчётов и обработок с назначением расписания.
Уменьшится ли размер файловой базы после очистки сообщений?
Не сразу. Файл 1Cv8.1CD физически не сжимается при удалении данных — место освобождается внутри файла. Для реального уменьшения размера выполните тестирование и исправление базы с включённой реструктуризацией и сжатием таблиц.
Что важно запомнить
Выберите метод очистки по типу данных: УдалитьСообщение для системы взаимодействия, СократитьЖурналРегистрации для журнала, набор записей для прикладных регистров. Перед любым удалением делайте резервную копию, тестируйте код на копии и сохраняйте архив удаляемых данных. Для регулярной чистоты оформите очистку как регламентное задание с настраиваемым сроком хранения.