Как свернуть регистр «Цены номенклатуры» и удалить цены по товарам без остатков в 1С

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Проанализируем основные причины этой проблемы и разберем практические способы очистки регистра цен от записей по номенклатурным позициям с нулевыми остатками.

Причины зависания и большого размера базы

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

  1. Комбинаторный взрыв серий и цен: Если для каждого изделия создается отдельная серия (или характеристика) и на нее рассчитывается по 5–7 видов цен, количество записей в периодическом регистре сведений растет экспоненциально.
  2. Медленная работа виртуальных таблиц: При попытке получить срез последних по табличной части с сотнями тысяч серий и характеристик база начинает зависать.
  3. Ограничения интерфейсных механизмов: Заполнение документа УстановкаЦенНоменклатуры через форму на клиенте с выбором всего склада блокирует сеанс из-за переполнения оперативной памяти.

Способ 1. Порционное формирование установки цен по остаткам

Чтобы не перегружать систему обработкой сразу всех товаров и складов, разберем подход с разбивкой данных на небольшие порции. Взамен монолитной обработки всего справочника сформируем документы установки цен по группам номенклатуры.

  1. Создадим документ ИнвентаризацияТоваровНаСкладе с отбором не по всему складу, а по конкретной группе товаров (или списку из нескольких партий).
  2. На основании инвентаризации сформируем документ УстановкаЦенНоменклатуры. Это позволит записать срез последних цен только для тех позиций, которые реально числятся в остатках на дату свертки.
  3. Повторим операцию для остальных групп (например, разбивая 40 групп товаров на 4–5 отдельных документов).
  4. Все исторические документы установки цен, введенные до даты свертки, пометем на удаление.

Способ 2. Программная очистка регистра через набор записей

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

Рассмотрим пример кода для порционного удаления неактуальных записей из регистра сведений:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	Цены.Номенклатура КАК Номенклатура,
    |	Цены.ХарактеристикаНоменклатуры КАК Характеристика,
    |	Цены.СерияНоменклатуры КАК Серия
    |ИЗ
    |	РегистрСведений.ЦеныНоменклатуры КАК Цены
    |	ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(&ДатаСвертки, ) КАК Остатки
    |		ПО Цены.Номенклатура = Остатки.Номенклатура
    |		И Цены.ХарактеристикаНоменклатуры = Остатки.ХарактеристикаНоменклатуры
    |		И Цены.СерияНоменклатуры = Остатки.СерияНоменклатуры
    |ГДЕ
    |	ЕСТЬНУЛЛ(Остатки.КоличествоОстаток, 0) <= 0";

Запрос.УстановитьПараметр("ДатаСвертки", ТекущаяДата());
РезультатЗапроса = Запрос.Выполнить().Выгрузить();

Для Каждого Стр Из РезультатЗапроса Цикл
    НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Номенклатура.Установить(Стр.Номенклатура);
    НаборЗаписей.Отбор.ХарактеристикаНоменклатуры.Установить(Стр.Характеристика);
    НаборЗаписей.Отбор.СерияНоменклатуры.Установить(Стр.Серия);
    
    // Очищаем набор и записываем (удаляем записи по комбинации)
    НаборЗаписей.Записать();
КонецЦикла;

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

Способ 3. Перенос остатков и цен в чистую базу

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

  1. Выгружаем из исходной базы структуры справочников (Номенклатура, Склады, Серии и т. д.).
  2. С помощью внешних обработок или правил конвертации выгружаем остатки товаров по регистру ТоварыНаСкладах на дату свертки.
  3. Для полученных позиций с остатками выгружаем актуальный срез последних из регистра ЦеныНоменклатуры.
  4. Загружаем данные в новую чистую базу. Товары без остатков и их исторические цены в новую базу не попадают, что существенно уменьшает ее объем.

Обязательные действия после очистки регистра

Помним, что после физического удаления документов или записей из таблиц размер файла базы данных (для файлового варианта 1Cv8.1CD) или файлов СУБД SQL автоматически не уменьшается.

Чтобы освободить диск и переиндексировать физические таблицы, выполним следующие шаги:

  1. Сделаем резервную копию базы данных.
  2. Запустим режим Тестирование и исправление в Конфигураторе 1С.
  3. Установим флажки Реиндексация таблиц информационной базы и Сжатие таблиц информационной базы.
  4. В случае использования MS SQL Server выполним процедуру сжатия (Shrink) базы данных и обслуживание индексов средствами SQL.
← На главную