Одной из самых пугающих проблем для разработчика и администратора 1С является ситуация, когда остатки по регистру накопления не соответствуют его движениям. Это явление часто называют «расползанием итогов». Представьте ситуацию: на конец месяца остаток нулевой, движений в следующем месяце не было, но на второе число нового месяца внезапно «всплывает» ненулевой остаток, который исчезает к третьему числу. В этой статье мы подробно разберем, почему возникает этот баг, как его диагностировать на уровне SQL и какими способами можно вернуть системе целостность.
Чаще всего проблема проявляется в крупных информационных базах (УТ 10.3, ERP, КА) с большим объемом движений. Проанализируем типичный сценарий:
Полный пересчет итогов, и данные приходят в норму.Ситуация осложняется тем, что такие «фантомные» остатки могут влиять на проведение документов, вызывая ложные ошибки о нехватке товара или, наоборот, позволяя списывать то, чего фактически нет.
Проанализируем техническую сторону вопроса. В платформе 1С 8.3 расчет виртуальных таблиц (Остатки) — это сложный механизм. Система не хранит остатки на каждую секунду времени. Вместо этого существуют таблицы рассчитанных итогов (обычно на начало каждого месяца).
Рассмотрим основные причины сбоя:
Shared Memory иногда приводило к чтению «грязных» данных, когда итоги еще не зафиксированы окончательно, но уже попали в выборку виртуальной таблицы.Чтобы понять, имеем ли мы дело с багом платформы или с логической ошибкой в коде, нам нужно проверить физические таблицы в СУБД. В 1С регистр накопления представлен двумя основными таблицами: _AccumRg (движения) и _AccumRgT (итоги).
Посмотрим, как можно проверить соответствие итогов движениям с помощью прямого запроса. Допустим, наш регистр имеет имя ТоварыНаСкладах. Мы можем сравнить сумму всех движений с записями в таблице итогов:
-- Пример логики SQL-запроса (имена таблиц и полей будут уникальными для вашей базы)
SELECT
SumMovements.ItemUID,
SumMovements.TotalQty AS MovementsQty,
Totals.TotalQty AS TotalsTableQty
FROM (
-- Суммируем все движения из таблицы движений
SELECT _Fld100 AS ItemUID, SUM(_Fld101) AS TotalQty
FROM _AccumRg123
GROUP BY _Fld100
) AS SumMovements
LEFT JOIN (
-- Берем текущие итоги из таблицы итогов
SELECT _Fld100 AS ItemUID, SUM(_Fld101) AS TotalQty
FROM _AccumRgT124
WHERE _Period = '3999-11-01 00:00:00' -- Дата актуальных итогов
GROUP BY _Fld100
) AS Totals ON SumMovements.ItemUID = Totals.ItemUID
WHERE SumMovements.TotalQty <> Totals.TotalQty
Если такой запрос возвращает строки, значит, физическая таблица итогов _AccumRgT рассинхронизирована с таблицей движений _AccumRg. Это прямое подтверждение бага платформы.
Рассмотрим пошагово способы исправления ситуации, от простых к радикальным.
Это стандартное средство. Зайдите в Управление итогами и выполните полный пересчет для проблемного регистра. Это принудительно очистит таблицу _AccumRgT и заполнит её заново на основании таблицы _AccumRg. Однако помните, что на больших базах это может занять значительное время и потребовать монопольного доступа.
Если проблема повторяется регулярно, попробуйте в Конфигураторе у конкретного регистра снять галочку Разделение итогов. Это увеличит вероятность блокировок при записи, но исключит ошибки агрегации «расщепленных» записей.
Используйте режим Пересчет итогов в утилите ТиИ. Важно также проверить базу на наличие логической целостности. Иногда «битые» записи в таблице движений (например, записи с пустой датой или Активность = Ложь, которые ошибочно учитываются в итогах) мешают корректному расчету.
Поскольку баг часто специфичен для конкретного релиза (как в случае с 8.3.13.1644), рассмотрите переход на более стабильную версию. Опытные системные администраторы рекомендуют использовать проверенные LTSC-релизы платформы.
Если пересчет итогов не помогает (случается крайне редко), можно воспользоваться методом «передергивания» движений. Нужно программно прочитать набор записей регистра по конкретному документу и записать его обратно с признаком Записывать = Истина. Это заставляет платформу пересчитать итоги именно для этого набора данных.
Чтобы избежать подобных «сюрпризов» в будущем, проанализируем меры предосторожности:
Остатки с расчетным остатком по таблице Обороты или Движения за определенный период. При выявлении разницы администратор получит уведомление до того, как ошибку заметит бухгалтерия.Резюме: Ошибка расхождения итогов — это неприятный, но известный баг платформы 1С 8.3. Основным инструментом борьбы остается Пересчет итогов и тщательный подбор версии платформы. Понимание того, как данные лежат в SQL, позволяет быстро локализовать проблему и не допустить принятия управленческих решений на основе неверных данных.