При свертке информационной базы в конфигурациях 1С (например, «Управление торговлей») часто возникает проблема с неограниченным ростом регистра сведений ЦеныНоменклатуры. В специфических отраслях — таких как ювелирная торговля, где каждая единица товара имеет уникальную серию и характеристику — комбинация серий и нескольких видов цен приводит к созданию миллионов записей. В результате даже после проведения штатной свертки база данных может весить гигабайты из-за устаревших цен на товары, которых давно нет на складе.
Проанализируем основные причины этой проблемы и разберем практические способы очистки регистра цен от записей по номенклатурным позициям с нулевыми остатками.
Выясним, почему стандартные механизмы не всегда справляются со сверткой цен в индивидуальном учете:
УстановкаЦенНоменклатуры через форму на клиенте с выбором всего склада блокирует сеанс из-за переполнения оперативной памяти.Чтобы не перегружать систему обработкой сразу всех товаров и складов, разберем подход с разбивкой данных на небольшие порции. Взамен монолитной обработки всего справочника сформируем документы установки цен по группам номенклатуры.
ИнвентаризацияТоваровНаСкладе с отбором не по всему складу, а по конкретной группе товаров (или списку из нескольких партий).УстановкаЦенНоменклатуры. Это позволит записать срез последних цен только для тех позиций, которые реально числятся в остатках на дату свертки.Если требуется очистить независимый или подчиненный регистр программно, напишем обработку, которая сопоставляет записи регистра сведений с фактическими остатками из регистра накопления (например, ТоварыНаСкладах). Все записи цен по товарам и сериям с нулевым остатком удаляются порциями.
Рассмотрим пример кода для порционного удаления неактуальных записей из регистра сведений:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Цены.Номенклатура КАК Номенклатура,
| Цены.ХарактеристикаНоменклатуры КАК Характеристика,
| Цены.СерияНоменклатуры КАК Серия
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК Цены
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаСвертки, ) КАК Остатки
| ПО Цены.Номенклатура = Остатки.Номенклатура
| И Цены.ХарактеристикаНоменклатуры = Остатки.ХарактеристикаНоменклатуры
| И Цены.СерияНоменклатуры = Остатки.СерияНоменклатуры
|ГДЕ
| ЕСТЬНУЛЛ(Остатки.КоличествоОстаток, 0) <= 0";
Запрос.УстановитьПараметр("ДатаСвертки", ТекущаяДата());
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Для Каждого Стр Из РезультатЗапроса Цикл
НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Номенклатура.Установить(Стр.Номенклатура);
НаборЗаписей.Отбор.ХарактеристикаНоменклатуры.Установить(Стр.Характеристика);
НаборЗаписей.Отбор.СерияНоменклатуры.Установить(Стр.Серия);
// Очищаем набор и записываем (удаляем записи по комбинации)
НаборЗаписей.Записать();
КонецЦикла;
Важное примечание: Запись набора необходимо выполнять небольшими порциями в транзакциях, чтобы не вызывать эскалацию блокировок СУБД и не переполнять журнал транзакций.
Когда размер базы данных слишком велик и штатная свертка выполняется нестабильно, самым эффективным решением является перенос остатков в чистую базу данных:
ТоварыНаСкладах на дату свертки.ЦеныНоменклатуры.Помним, что после физического удаления документов или записей из таблиц размер файла базы данных (для файлового варианта 1Cv8.1CD) или файлов СУБД SQL автоматически не уменьшается.
Чтобы освободить диск и переиндексировать физические таблицы, выполним следующие шаги: