В практике сопровождения 1С:Бухгалтерия 3.0 (БП 3.0) часто встречаются ситуации, когда после переноса данных из версии 7.7 или длительной эксплуатации базы возникают необъяснимые «фантомные» остатки. Типичный симптом: Оборотно-сальдовая ведомость (ОСВ) показывает нулевое сальдо по счету (например, 60.21), но регламентная операция «Переоценка валютных остатков» упорно создает проводки на суммы, которых «нет». При попытке исправить ситуацию программно или через Тестирование и исправление (ТиИ), остатки в ОСВ начинают «плыть» еще сильнее.
В этой статье мы подробно разберем причины возникновения этой ошибки, выясним разницу между техническими значениями в базе данных и рассмотрим пошаговые методы восстановления корректного учета.
Проанализируем механику работы регистра бухгалтерии. Когда мы смотрим на ОСВ, система выводит агрегированные данные. Однако алгоритм переоценки валюты обращается напрямую к таблицам остатков в разрезе всех измерений, включая скрытые. Основная причина проблемы кроется в техническом несоответствии значений в поле Подразделение на уровне базы данных SQL.
Для платформы 1С существуют три принципиально разных состояния поля измерения:
ПодразделенияОрганизаций.СправочникСсылка.ПодразделенияОрганизаций, который инициализирован, но не выбран (на уровне БД это уникальный идентификатор из нулей).Если на счете 60.21 учет по подразделениям не ведется, значение в базе данных обязано быть NULL. Однако после переноса данных или некорректных манипуляций там может оказаться Пустая ссылка. Система воспринимает NULL и Пустую ссылку как два разных аналитических разреза. В итоге: по NULL висит +100 рублей, а по Пустой ссылке — -100 рублей. Взаимно они дают ноль в общей ОСВ, но валютный механизм видит два разных «хвоста» и пытается их переоценить по отдельности.
При изменении любой записи в регистре бухгалтерии (даже если вы просто меняете «пустое» на «пустое»), платформа инициирует пересчет итогов. Если в базе присутствуют логические нарушения (например, несоответствие между основной таблицей движений _AccRg и таблицей итогов _AccRgTotals), то при попытке записи система обнаруживает, что «старые» итоги не сходятся с новыми данными. В результате ОСВ пересчитывается «как есть» на самом деле в базе, обнажая все скрытые ошибки прошлых лет, которые ранее маскировались неактуальными итогами.
Наиболее безопасный способ — заставить систему привести все технические поля в соответствие с текущим Планом счетов. Для этого мы воспользуемся функцией очистки неиспользуемых полей.
Рассмотрим по шагам выполнение этой процедуры:
Важный момент: Этот механизм просканирует записи и везде, где на счетах отключен учет по подразделениям или валютам, заменит «Пустые ссылки» на NULL. Это позволит системе «схлопнуть» остатки в один правильный разрез.
Если база данных имеет огромный объем и запуск полного ТиИ через конфигуратор невозможен из-за временных ограничений, можно воспользоваться административной утилитой. Рассмотрим пример команды для исправления структуры данных:
/IBConnectionString "Srvr=ServerName;Ref=BaseName;" /IBName "BaseName" /IBUser "Admin" /IBPassword "Pass" /CheckDBConfig -ClearUnusedFields
Параметр -ClearUnusedFields выполняет ту самую очистку полей, по которым не ведется учет, но делает это на уровне движка базы данных более эффективно. Это помогает убрать расхождения между NULL и пустыми ссылками без необходимости полной реиндексации всех таблиц.
Если вы опасаетесь трогать «древние» периоды, так как это может привести к непредсказуемым изменениям в закрытой отчетности, мы рекомендуем не править старые проводки напрямую. Вместо этого проанализируем ситуацию с помощью консоли запросов и создадим корректировку в текущем периоде.
Посмотрим на пример запроса, который поможет выявить проблемные записи:
ВЫБРАТЬ
ХозрасчетныйОстатки.Счет,
ХозрасчетныйОстатки.Подразделение,
ХозрасчетныйОстатки.СуммаОстаток
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет = &Счет, , ) КАК ХозрасчетныйОстатки
ГДЕ
(ХозрасчетныйОстатки.Подразделение = ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка)
ИЛИ ХозрасчетныйОстатки.Подразделение ЕСТЬ NULL)
Если в результате запроса вы увидите две строки с одинаковой суммой (одна с плюсом, другая с минусом), но в разных колонках (одна в NULL, другая в ПустаяСсылка), значит, вам нужно создать документ «Корректировка записей регистров». В нем вы вручную сделаете две записи: одну по NULL, другую по Пустой ссылке, чтобы технически закрыть этот разрыв в текущем месяце.
В самых сложных случаях, когда стандартные средства 1С не видят разницы между значениями (например, если в поле записан некорректный тип данных), специалисты прибегают к прямым SQL-запросам. Внимание: данный метод лишает вас поддержки вендора и может повредить базу, если вы не уверены в своих действиях.
Проанализируем пример логики SQL-запроса (имена таблиц _AccRgXX нужно предварительно выяснить через ПолучитьСтруктуруХраненияБазыДанных):
-- Замена 0 (пустой ссылки в бинарном виде) на NULL для конкретного счета
UPDATE _AccRgED1234
SET _Fld567RRef = NULL
WHERE _AccountRRef = (SELECT _IDRRef FROM _Acc12 WHERE _Code = '60.21')
AND _Fld567RRef = 0x00000000000000000000000000000000
После выполнения подобной операции в СУБД крайне важно зайти в 1С и выполнить Полный пересчет итогов через «Управление итогами», чтобы платформа обновила свои агрегатные таблицы на основе исправленных первичных движений.
Подведем итоги нашего исследования:
NULL и Пустой ссылкой в измерениях регистра.Всегда проводите подобные операции сначала на копии базы и сверяйте ОСВ до и после процедур с помощью отчета «Сравнение данных» или просто сохраняя отчеты в Excel для контроля контрольных сумм.