К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как очистить хранилище значения в 1С

Как очистить ХранилищеЗначения в 1С: обнуление реквизитов, удаление данных в регистрах, типовая обработка группового изменения и примеры кода на встроенном языке.

Хранилище значения (ХранилищеЗначения) в 1С — специальный тип данных, который упаковывает произвольные объекты (картинки, файлы, таблицы значений, сериализуемые структуры) в бинарный формат для сохранения в базе. Со временем такие реквизиты раздувают базу: в них оседают устаревшие версии файлов, временные данные обменов, настройки, которые больше не нужны. Очистка хранилища значений — стандартная задача при оптимизации размера информационной базы и при исправлении ошибок, вызванных повреждёнными или устаревшими данными.

Очистить хранилище значения можно несколькими способами: присвоить реквизиту пустое значение программно, воспользоваться типовой обработкой «Групповое изменение реквизитов», удалить данные в регистрах сведений или выполнить регламентные операции на уровне СУБД. Выбор зависит от того, где расположен реквизит: в справочнике, документе, регистре сведений или константе.

Перед любыми массовыми изменениями обязательно создайте резервную копию базы. Очистка хранилища необратима: если в реквизите хранились прикреплённые файлы или уникальные настройки, восстановить их без копии не получится.

Что такое ХранилищеЗначения и почему его нужно чистить

ХранилищеЗначения — это объект встроенного языка 1С, который сериализует данные в двоичный вид. Конструктор выглядит так: Новый ХранилищеЗначения(Значение), а извлечение данных выполняется методом Получить(). В конфигурациях этот тип используется для реквизитов справочников, документов, ресурсов регистров сведений и констант — например, для хранения фотографий товаров, печатных форм, двоичных данных файлов, настроек обменов.

Проблема в том, что платформа не контролирует размер содержимого. Если механизм обмена пишет в хранилище результаты каждой выгрузки, а старые записи не удаляются, таблица базы растёт на сотни мегабайт без видимой причины. Типичный симптом — база занимает непропорционально много места при небольшом количестве документов, а таблицы с полями типа image/varbinary в SQL оказываются самыми тяжёлыми.

Определяем, где хранилище занимает место

Прежде чем очищать, найдите источник проблемы. В файловой базе ориентируйтесь на общий размер файла 1Cv8.1CD и косвенные признаки: медленное открытие списков присоединённых файлов, долгое выполнение обменов. В клиент-серверном варианте запросите у администратора СУБД размер таблиц — обычно «тяжёлые» таблицы видны сразу.

Программно оценить заполненность можно перебором: выбрать записи, у которых реквизит типа ХранилищеЗначения не пустой, и посчитать их количество. Если в справочнике 50 000 элементов, а хранилище заполнено у 45 000, очистка даст заметный эффект.

База растёт без роста документовВероятно, переполнены хранилища значений

Проверьте регистры сведений с ресурсами типа ХранилищеЗначения и справочники присоединённых файлов

Медленно открываются карточкиВ реквизитах лежат крупные двоичные данные

Проверьте реквизиты с картинками и файлами в проблемном объекте

Ошибка при Получить()Данные в хранилище повреждены или от другой версии

Такие записи — первые кандидаты на очистку

Очистка реквизита объекта программно

Самый прямой способ — обойти нужные объекты и присвоить реквизиту пустое значение. Для единичных объектов это можно сделать вручную через отладку или небольшую внешнюю обработку, для массовой очистки — циклом по выборке.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Товары.Ссылка

|ИЗ

| Справочник.Номенклатура КАК Товары

|ГДЕ

| НЕ Товары.ФайлКартинки ЕСТЬ NULL";

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Объект = Выборка.Ссылка.ПолучитьОбъект();

Объект.ФайлКартинки = Неопределено;

Объект.Записать();

КонецЦикла;

Два важных нюанса. Во-первых, присваивание Неопределено корректно очищает реквизит типа ХранилищеЗначения. Во-вторых, в больших выборках записывайте объекты порциями в транзакции или используйте режим загрузки данных (Объект.ОбменДанными.Загрузка = Истина), если не нужно отрабатывать прикладную логику записи — это ускорит процесс в разы. Но режим загрузки отключает проверки, поэтому применяйте его только когда уверены, что обработчики записи не нужны.

Очистка ресурса регистра сведений

Регистры сведений — самое частое место накопления «мусора»: в них типовые и самописные механизмы складывают данные обменов, истории версий, настройки. Очистка выполняется набором записей: перебираете записи, присваиваете ресурсу пустое значение и записываете набор с замещением.

НаборЗаписей = РегистрыСведений.ДанныеОбмена.СоздатьНаборЗаписей();

НаборЗаписей.Прочитать();

Для Каждого Запись Из НаборЗаписей Цикл

Запись.ХранимыеДанные = Неопределено;

КонецЦикла;

НаборЗаписей.Записать();

Если записей очень много, читать весь набор целиком нельзя — будет нехватка памяти. Обрабатывайте порциями, отбирая записи по измерениям или периоду, либо, если данные не нужны вовсе, просто удалите записи регистра целиком через НаборЗаписей.Записать() с пустым набором и установленными отборами. Полное удаление записей эффективнее очистки ресурса: таблица реально уменьшается, а не просто заполняется пустыми значениями.

Очистка через типовую обработку «Групповое изменение реквизитов»

Если нет возможности писать код, используйте штатный механизм БСП — обработку «Групповое изменение реквизитов» (в типовых конфигурациях находится в разделе «Администрирование» → «Обслуживание», либо вызывается по кнопке «Изменить выделенные» в списках). Она позволяет выбрать объект, наложить отбор и установить реквизиту новое значение, включая пустое.

Порядок действий в обработке
  1. 1
    Откройте «Администрирование» → «Обслуживание» → «Корректировка данных» → «Групповое изменение реквизитов»
  2. 2
    Выберите тип объекта (справочник или документ) и задайте отбор по нужным элементам
  3. 3
    В списке реквизитов найдите реквизит типа ХранилищеЗначения и установите ему пустое значение
  4. 4
    Выполните изменение и проверьте на нескольких элементах, что реквизит очищен
  5. 5
    При большом объёме запускайте обработку порциями, отсекая по дате или по группам

Ограничение способа: обработка работает с реквизитами объектов, но не всегда удобна для регистров сведений и констант. Для них надёжнее программный вариант или удаление записей штатными средствами.

Очистка констант и справочника присоединённых файлов

Константы типа ХранилищеЗначения (например, хранящие логотип организации или настройки) очищаются элементарно: Константы.МояКонстанта.Установить(Неопределено); или вручную через форму настроек, если она предусмотрена конфигурацией.

Отдельный случай — присоединённые файлы в конфигурациях на БСП. Файлы могут храниться в реквизите справочника присоединённых файлов либо в томах на диске. Если файлы в базе, очистка реквизита «ФайлХранилище» уменьшит базу; если в томах — данные в хранилище пусты, и чистить нужно файловую систему. Перед очисткой уточните настройку «Хранить файлы в томах на диске» в параметрах работы с файлами.

Маршрут решения

Как выбрать действие

Нужно очистить несколько объектов разовоИспользуйте «Групповое изменение реквизитов» — безопасно и не требует кода
Нужно очистить тысячи записей регистра сведенийПишите обработку с порционной записью или удаляйте записи наборами
Данные в хранилище повреждены, Получить() падает с ошибкойОчищайте присваиванием Неопределено без чтения содержимого
Цель — уменьшить размер базыПосле очистки выполните сжатие таблиц (ТиИ или шринк СУБД)

Типичные ошибки и проверка результата

Самая частая ошибка — попытка «прочитать, потом очистить» повреждённое хранилище. Вызов Получить() на битых данных вызывает исключение, и обработка прерывается. Очищайте такие записи без чтения, просто присваивая Неопределено, а чтение оборачивайте в попытку/исключение.

Вторая ошибка — забыть про сжатие базы. Пользователь очищает гигабайты данных, а размер файла не меняется, и делает вывод, что «очистка не сработала». На деле данные удалены, но физическое место освобождается только при сжатии таблиц.

Типичные ошибки
01
Чтение хранилища перед очисткой: на повреждённых данных Получить() вызывает исключение и обрывает обработку
02
Очистка без резервной копии: удалённые файлы и настройки невозможно восстановить
03
Отсутствие сжатия после очистки: размер файла базы визуально не меняется, хотя данные удалены
04
Запись объектов по одному без транзакций на больших объёмах: обработка идёт часами вместо минут
05
Очистка хранилища, в котором лежат данные работающего обмена: после очистки обмен начинает выгружать всё заново

Проверить результат просто: повторным запросом убедитесь, что реквизит пуст у целевых записей (условие Реквизит ЕСТЬ NULL или сравнение с пустым значением), а затем сравните размер базы после сжатия. Дополнительно пройдитесь по прикладным сценариям: откройте карточки, запустите обмен, сформируйте печатную форму — убедитесь, что ничего не сломалось.

Контрольные точки

Как проверить результат

Заполненность реквизита
Норма

Запрос показывает пустое значение у целевых записей

Тревожный признак

Часть записей осталась заполненной — отбор в обработке был неполным

Размер базы после сжатия
Норма

Файл 1Cv8.1CD или таблицы СУБД заметно уменьшились

Тревожный признак

Размер прежний — сжатие не выполнялось или чистился не тот объект

Работа прикладных механизмов
Норма

Карточки открываются, обмены и печать работают

Тревожный признак

Ошибки обращения к данным — очищено то, что используется логикой

Итог

Что важно запомнить

Хранилище значения очищается присваиванием Неопределено — программно, через набор записей регистра или обработку группового изменения реквизитов. Перед массовой очисткой делайте резервную копию, повреждённые данные очищайте без чтения, а после очистки выполняйте сжатие таблиц, иначе размер базы не уменьшится.

Частые вопросы

Чем отличается присваивание Неопределено от Новый ХранилищеЗначения(Неопределено)?

Обе конструкции делают данные недоступными для прикладного использования, но первая полностью очищает поле, а вторая записывает «пустую обёртку» — небольшой двоичный объект. Для реальной экономии места используйте Неопределено. Вариант с пустым хранилищем нужен только если прикладной код ожидает именно объект ХранилищеЗначения и падает на Неопределено.

Можно ли очистить хранилище значения без программирования?

Да, если речь о реквизитах справочников и документов — используйте типовую обработку «Групповое изменение реквизитов». Для констант достаточно формы настроек. А вот для регистров сведений без кода или специализированной обработки обойтись сложно.

Почему после очистки размер базы не уменьшился?

Удалённые данные остаются зарезервированными внутри файла базы. В файловом варианте запустите конфигуратор → «Администрирование» → «Тестирование и исправление» с включённым сжатием таблиц. В клиент-серверном варианте выполните сжатие средствами СУБД (shrink для MS SQL, vacuum для PostgreSQL).

Как очистить хранилище, если Получить() выдаёт ошибку?

Не вызывайте Получить() вовсе. Присвойте реквизиту Неопределено напрямую — для очистки читать содержимое не нужно. Если в обработке чтение необходимо для других записей, оберните его в конструкцию Попытка...Исключение и пропускайте проблемные объекты.

Опасно ли очищать хранилища, связанные с обменами данными?

Да. Если в хранилище лежат данные синхронизации (например, кэш выгрузок или история версий), очистка может спровоцировать полную повторную выгрузку или конфликты при следующем сеансе обмена. Сначала изучите документацию конкретного механизма обмена и проверьте очистку на копии базы.

Как найти все реквизиты типа ХранилищеЗначения в конфигурации?

В конфигураторе откройте поиск по метаданным или используйте отчёт по структуре конфигурации, отфильтровав реквизиты по типу «ХранилищеЗначения». Альтернатива — штатная функция «Все функции» → «Стандартные» → поиск ссылок на объекты не подходит; нужен именно анализ состава типов реквизитов в дереве метаданных или через внешние инструменты анализа конфигурации.