Как убрать «фантомную» проводку или зависший остаток по счету в 1С:Бухгалтерия 3.0?

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

Каждый практикующий специалист 1С или опытный бухгалтер рано или поздно сталкивается с загадочной ситуацией: в оборотно-сальдовой ведомости (ОСВ) по какому-либо счету (например, по счету 02 «Амортизация основных средств» или 01 «Основные средства») висит непонятная сумма. При этом попытки детализировать эту сумму, открыв карточку счета, не приносят результатов — отчет оказывается абсолютно пустым, либо показывает эту сумму «из ниоткуда» на самую раннюю дату (например, на 1989 год или даже на «начало времен» — 01.01.0001). Стандартные документы-регистраторы отсутствуют, ручные операции не создавались, а база данных ведет себя некорректно, искажая отчетность по налогу на имущество или баланс.

В этой статье мы подробно разберем, почему возникают такие «фантомные» остатки, проанализируем внутреннее устройство регистров бухгалтерии в платформе «1С:Предприятие 8.3», выясним, почему стандартное тестирование и исправление (ТИИ) часто оказывается бессильным, и пошагово решим эту проблему с помощью программных и интерактивных методов.

Физическая суть проблемы: почему возникают «висящие» остатки

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

  1. Таблица движений (проводок) — в ней хранятся детальные записи по каждой проводке, жестко привязанные к конкретному документу-регистратору (например, таблица _AccRg в MS SQL или PostgreSQL). Каждая строка здесь — это физическое действие: проведение документа, ручная операция или корректировка регистров.
  2. Таблицы итогов — вспомогательные таблицы (например, _AccRgT), в которых платформа 1С хранит предварительно рассчитанные и агрегированные остатки и обороты в разрезе месяцев, счетов и субконто. Это необходимо для того, чтобы тяжелые отчеты (ОСВ, баланс) формировались за секунды, а не сканировали терабайты детальных проводок за всю историю ведения учета при каждом запросе.

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

Шаг 1. Диагностика проблемы с помощью консоли запросов

Прежде чем приступать к исправлению, нам необходимо убедиться, что мы имеем дело именно с рассогласованием итогов, а не с реально существующей, но скрытой проводкой (например, сделанной в «далеком будущем» из-за опечатки в дате документа типа 2358 года). Для этого воспользуемся консолью запросов. Нам нужно сопоставить данные виртуальной таблицы остатков и физической таблицы движений.

Разберем пример запроса, который поможет выявить наличие реальных проводок за сомнительный период:


ВЫБРАТЬ
    Хозрасчетный.Регистратор КАК Регистратор,
    Хозрасчетный.Период КАК Период,
    Хозрасчетный.Сумма КАК Сумма,
    Хозрасчетный.СчетДт КАК СчетДт,
    Хозрасчетный.СчетКт КАК СчетКт
ИЗ
    РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
    Хозрасчетный.Период МЕЖДУ &НачалоПериода И &КонецПериода
    И (Хозрасчетный.СчетДт = &ЦелевойСчет ИЛИ Хозрасчетный.СчетКт = &ЦелевойСчет)

В качестве параметров укажем:

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

Шаг 2. Почему стандартный пересчет итогов и ТИИ не помогают?

Казалось бы, решение очевидно: нужно запустить «Тестирование и исправление» (ТИИ) из конфигуратора с установленным флагом «Пересчет итогов» либо выполнить пересчет через стандартные административные функции. Однако на больших базах данных эта процедура может длиться сутками (вплоть до 3–4 дней) и в итоге все равно завершиться неудачей. Почему так происходит?

Платформа 1С использует оптимизацию хранения данных. Чтобы база данных не раздувалась до невероятных размеров, разработчики платформы ввели механизмы ограничения хранения итогов. У любого регистра бухгалтерии существуют параметры:

По умолчанию в типовой конфигурации «1С:Бухгалтерия 3.0» минимальный период рассчитанных итогов часто сдвинут на дату начала реального ведения учета (например, 01.01.2015). Если «битая» запись в таблице итогов СУБД имеет дату ранее этого минимального периода (например, проецируется на пустую дату 01.01.0001), то при запуске стандартного ТИИ или обычного пересчета итогов платформа просто **игнорирует** этот временной пласт. Она производит расчеты только внутри установленного диапазона. Фантомный остаток, находящийся «за бортом» минимального периода, остается нетронутым и продолжает отравлять жизнь бухгалтерам.

Шаг 3. Решение проблемы: сброс минимального периода рассчитанных итогов программно

Для того чтобы заставить платформу 1С принудительно очистить и пересчитать абсолютно всю временную шкалу регистра бухгалтерии, нам необходимо сдвинуть минимальный период рассчитанных итогов в «начало времен» — на дату 01.01.0001. После этого платформа принудительно проверит целостность таблиц и сопоставит итоги с реальными проводками, начиная с Рождества Христова.

Выполнить эту операцию можно программно. Напишем простую обработку. Разберем по шагам код, который необходимо выполнить в контексте сервера:


Процедура СброситьМинимальныйПериодИтогов() Экспорт
    
    // Получаем менеджер регистра бухгалтерии "Хозрасчетный"
    Регистр = РегистрыБухгалтерии.Хозрасчетный;
    
    // Выведем текущие настройки для анализа в окно сообщений
    ТекущийМинимум = Регистр.ПолучитьМинимальныйПериодРассчитанныхИтогов();
    ТекущийМаксимум = Регистр.ПолучитьМаксимальныйПериодРассчитанныхИтогов();
    
    Сообщить("Текущий минимальный период итогов: " + СокрЛП(ТекущийМинимум));
    Сообщить("Текущий максимальный период итогов: " + СокрЛП(ТекущийМаксимум));
    
    // Устанавливаем минимальный период в самую раннюю возможную дату 1С
    Попытка
        Регистр.УстановитьМинимальныйПериодРассчитанныхИтогов('00010101');
        Сообщить("Минимальный период успешно сброшен на 01.01.0001!");
    Исключение
        ВызватьИсключение "Не удалось установить минимальный период. Ошибка: " + ОписаниеОшибки();
    КонецПопытки;
    
КонецПроцедуры

Важное предупреждение: так как база данных может быть огромной, выполнение этого кода и последующий пересчет итогов могут занять значительное время и потребовать свободных ресурсов оперативной памяти на сервере приложений 1С и сервере СУБД (MS SQL / PostgreSQL). Настоятельно рекомендуем выполнять эту процедуру на копии базы данных перед тем, как запускать её на рабочей системе!

Шаг 4. Альтернативный способ через стандартный интерфейс

Если вы не хотите писать код или запускать внешние обработки, в платформе 1С:Предприятие 8.3 предусмотрен интерактивный механизм управления итогами. Рассмотрим, как им воспользоваться:

  1. Перейдите в главное меню программы, выберите пункт «Функции для технического специалиста» (в старых релизах платформы этот пункт назывался «Все функции»). Если этот пункт у вас не отображается, включите его в настройках параметров системы (Меню - Настройки - Параметры - флаг «Режим технического специалиста»).
  2. В открывшемся дереве объектов найдите раздел «Стандартные» и выберите инструмент «Управление итогами».
  3. В списке регистров найдите регистр бухгалтерии Хозрасчетный.
  4. Обратите внимание на колонку с минимальным периодом итогов. Нажмите кнопку «Полные возможности» или выберите в контекстном меню пункт, позволяющий изменить границы расчета.
  5. Сбросьте минимальный период расчета итогов до пустой даты (01.01.0001) и нажмите кнопку выполнения изменений.

Шаг 5. Полный пересчет итогов после сброса периода

После того как минимальный период успешно установлен в значение 01.01.0001, нам необходимо запустить пересчет итогов. Для этого у нас есть два пути:

Вариант А: Через режим конфигуратора (рекомендуется для файловых баз)

  1. Запустите базу данных в режиме Конфигуратор монопольно.
  2. Откройте меню Администрирование — Тестирование и исправление...
  3. Установите флаг только напротив пункта «Пересчет итогов». Остальные флаги (проверка логической целостности, ссылочной целостности и т.д.) можно снять, чтобы сэкономить время.
  4. В блоке «При наличии удаленных объектов» выберите «Не изменять». Нажмите кнопку «Выполнить».

Вариант Б: Через режим предприятия (рекомендуется для больших клиент-серверных баз)

В окне «Управление итогами» (которое мы открывали на Шаге 4) выделите регистр Хозрасчетный, нажмите правую кнопку мыши и выберите команду «Пересчитать итоги». Платформа произведет перестроение индексных таблиц и физических таблиц итогов на сервере СУБД без необходимости монопольного захвата всей базы данных в конфигураторе.

После завершения этой операции откройте оборотно-сальдовую ведомость по проблемному счету. Вы увидите, что «фантомный» остаток в 3 060,72 руб. (или любая другая зависшая сумма) полностью исчез, так как система перестроила таблицы итогов исключительно на основании реально существующих проводок из таблицы движений.

Шаг 6. Что делать, если база клиент-серверная (решение для администраторов СУБД)

Если ваша база данных имеет объем в сотни гигабайт или терабайты, полный пересчет итогов с '0001-01-01' может парализовать работу предприятия на длительный срок. В таком случае опытный системный администратор или администратор баз данных (DBA) может решить проблему непосредственно на уровне СУБД. Проанализируем этот сценарий на примере MS SQL Server:

  1. Сначала необходимо определить физическое имя таблицы итогов для регистра бухгалтерии Хозрасчетный. Для этого в 1С можно воспользоваться методом ПолучитьСтруктуруХраненияБазыДанных() или специализированными обработками. Предположим, имя таблицы итогов — _AccRgT1.
  2. Напишем SQL-запрос, который выявляет записи в таблице итогов, для которых отсутствуют соответствующие регистраторы (движения) в таблице проводок _AccRg1:

SELECT t.* 
FROM _AccRgT1 t
LEFT JOIN _AccRg1 d ON t._AccountRRef = d._AccountRRef AND t._Fld123 = d._Fld123 -- пример связи по субконто и счетам
WHERE d._Period IS NULL AND t._FldSumBalance <> 0

Если такие «сиротские» строки обнаружены, их можно аккуратно удалить прямой SQL-командой DELETE. Помните, что любое прямое изменение данных в СУБД в обход платформы 1С нарушает лицензионное соглашение и правила технической поддержки, поэтому всегда делайте резервную копию (бэкап) перед проведением подобных работ!

Рекомендации по профилактике появления подобных сбоев

Чтобы в будущем вам не пришлось сталкиваться с «фантомными» суммами на счетах учета, рекомендуем придерживаться нескольких простых правил:

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

← На главную