В платформе 1С 7.7 одной из самых болезненных проблем является чрезмерный рост таблицы итогов регистров (файл RG*.dbf или соответствующая таблица в SQL). Особенно часто это встречается в конфигурациях с "тяжелым наследством", где логика движений по регистру остатков нарушена: приход осуществляется по одним измерениям, а расход — по другим или не в полном объеме. В результате записи в таблице итогов "зависают" навсегда, копируясь из месяца в месяц и замедляя пересчет итогов до нескольких часов или даже дней.
Разберем детально, как диагностировать и решить эту проблему на примере регистра накопленных скидок, проанализируем архитектурные ошибки и выберем оптимальную стратегию оптимизации.
Проанализируем механику работы 1С 7.7. Регистр остатков хранит итоги в разрезе уникальных комбинаций всех своих измерений на конец каждого месяца. Если в документе прихода указано измерение Номенклатура, а в документе расхода (списания) это измерение пустое или вообще отсутствует в структуре документа, 1С никогда не "схлопнет" эти записи. Для системы Товар А и Пустое значение — это разные аналитические разрезы.
В итоге в таблице RG образуются "хвосты". Поскольку 1С 7.7 при закрытии месяца переносит все ненулевые остатки в следующий период, однажды возникшая ошибка дублируется ежемесячно. Если у вас 3000 клиентов и по каждому "зависла" хотя бы одна некорректная строка, через год в таблице будет уже 36 000 записей только по этому случаю. При активной розничной торговле объем таблицы RG начинает расти в геометрической прогрессии, достигая сотен мегабайт и гигабайт, что критично для DBF-версий.
Если задача регистра — хранить накопленную сумму покупок клиента для расчета процента скидки, то использование регистра остатков архитектурно неоправданно. Рассмотрим вариант замены его на оборотный регистр.
Преимущества оборотного регистра:
Рассмотрим, как быстро получить накопленный итог по оборотному регистру. Многие опасаются, что расчет "с начала времен" будет медленным. Однако в 1С 7.7 итоги оборотных регистров хранятся помесячно. Чтобы получить сумму за 5 лет, системе нужно сложить всего 60 чисел из таблицы итогов для конкретного клиента. Это происходит мгновенно.
Для получения данных можно использовать прямой запрос к таблице итогов или стандартный объект Запрос:
// Пример получения накопленной суммы через стандартный запрос
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|Период с '01.01.10' по РабочаяДата();
|Клиент = Регистр.СкидкиОбороты.Клиент;
|Сумма = Регистр.СкидкиОбороты.СуммаКупли;
|Функция СуммаНакоплено = Сумма(Сумма);
|Группировка Клиент без групп;
|Условие(Клиент = ВыбКлиент);";
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
Пока Запрос.Группировка(1) = 1 Цикл
Накоплено = Запрос.СуммаНакоплено;
КонецЦикла;
КонецЕсли;
Если вы решили оставить регистр остатков (например, из-за глубокой интеграции с фронт-офисными системами, требующими метода СводныйОстаток), необходимо радикально пересмотреть его структуру. Выясним причину незакрытия: скорее всего, в регистре слишком много лишних измерений, таких как Номенклатура, Склад или ККМ.
Рассмотрим шаги по оптимизации структуры:
Клиент.Номенклатуру и Склад реквизитами регистра, а не измерениями. Реквизиты не участвуют в формировании итогов и не раздувают таблицу RG.После изменения структуры в метаданных (MD) необходимо очистить старые "кривые" итоги. Для этого можно воспользоваться следующим алгоритмом:
Выполним действия в конфигураторе:
RA и RG).Если база данных работает на MS SQL Server, проблему можно решить "хирургическим" путем, не меняя структуру конфигурации, но исправив данные движений. Проанализируем ситуацию: если документ списания не содержит измерения Номенклатура, мы можем программно "подставить" туда нужные значения в таблице движений RA, чтобы они соответствовали приходу.
Однако более правильным подходом будет использование прямых запросов для свертки регистра. Проанализируем пример логики: 1. Находим все незакрытые остатки по регистру на определенную дату. 2. Формируем "виртуальный" документ списания, который обнуляет все остатки в разрезе детальной аналитики (номенклатура, склад). 3. Этим же документом приходуем общую сумму накоплений на ту же дату, но уже с пустыми "лишними" измерениями.
Это позволит "схлопнуть" записи в RG до одной строки на клиента, что уменьшит размер таблицы с сотен мегабайт до считанных единиц.
Проанализировав все варианты, можно подвести итог:
Клиент. Это навсегда избавит от проблем с "незакрытием" и обеспечит высокую скорость работы.Клиент). Всю остальную информацию (товар, чеки) пишите в реквизиты.RG*.dbf (только в DBF-версии и после бэкапа!) и выполните пересчет итогов только по этому регистру, предварительно исправив программный код движений в документах.Помните, что регистр в 1С 7.7 — это инструмент для получения быстрых текущих данных. Если он превращается в свалку исторической информации по товарам в разрезе чеков за 10 лет, он неизбежно станет "тормозом" всей системы.