В практике работы с платформой 1С:Предприятие 8 программисты часто сталкиваются с загадочной ситуацией: при получении остатков по регистру бухгалтерии запрос возвращает две строки вместо одной. При этом номенклатура, склад и счет учета совпадают, а различие кроется в поле аналитики (например, «Партия» или «Документ оприходования»). В одной строке значение отображается как NULL, а в другой — как Неопределено. Разберем подробно, почему так происходит, как диагностировать проблему и какими способами ее можно решить.
Для начала проанализируем техническую сторону вопроса. В системе 1С поля субконто имеют составной тип данных. На уровне СУБД (SQL) для хранения одного субконто выделяется несколько колонок. Разница между NULL и Неопределено принципиальна:
LEFT JOIN. Если система итогов содержит записи, где разрез аналитики вообще не был инициализирован (например, при специфических операциях «Закрытия месяца»), виртуальная таблица может выдать NULL.Ситуация, когда на 00:00:00 запрос выдает одну запись, а на 00:00:01 — две, указывает на то, что в первую секунду дня система начинает учитывать движения, которые «разрывают» целостность итогов. Даже если визуально документов в этой секунде нет, проблема может крыться в физических записях таблиц итогов, которые не были корректно пересчитаны или содержат записи от удаленных документов.
Первым делом нам необходимо выяснить, какой именно документ (регистратор) породил запись с некорректным значением. Обычный отчет «Оборотно-сальдовая ведомость» может не показать разницы, так как он часто группирует пустые значения. Проанализируем данные с помощью консоли запросов. Напишем запрос к физической таблице движений регистра бухгалтерии Хозрасчетный:
ВЫБРАТЬ
Хозрасчетный.Регистратор,
Хозрасчетный.НомерСтроки,
Хозрасчетный.Период,
Хозрасчетный.Субконто2 КАК Партия,
ТИПЗНАЧЕНИЯ(Хозрасчетный.Субконто2) КАК ТипПартии
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
Хозрасчетный.Счет В (&СчетаУчета)
И Хозрасчетный.Субконто1 = &Номенклатура
И Хозрасчетный.Организация = &Организация
В этом запросе нас интересует колонка ТипПартии. Если мы увидим, что у одних документов тип значения — Документ ссылка... (даже если ссылка пустая), а у других — NULL, мы нашли источник проблемы. Как показывает практика, документы типа «Закрытие месяца» или «Корректировка стоимости номенклатуры» могут формировать записи с NULL, в то время как обычные накладные записывают Неопределено.
Иногда проблема кроется не в самих движениях, а в таблице итогов. Если тестирование и исправление (ТиИ) с галкой «Пересчет итогов» не помогло, попробуем выполнить полный пересчет итогов вручную через режим «Управление итогами». Разберем ситуацию: если учет по партиям был отключен в учетной политике (установлено списание «По средней»), 1С перестает требовать заполнения субконто «Партии». Однако старые записи в регистре никуда не исчезают. Проанализируем, не осталось ли «хвостов» от того периода, когда партионный учет был включен.
Если мы обнаружили конкретные документы, которые записывают NULL в субконто, нам необходимо привести их к единому стандарту (обычно к значению Неопределено или пустой ссылке нужного типа). Рассмотрим пример кода, который позволяет программно перезаписать движения документа без перепроведения, чтобы исправить аналитику:
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ПроблемныйДокумент);
НаборЗаписей.Прочитать();
Для Каждого Запись Из НаборЗаписей Цикл
// Проверяем Субконто2 (Партия)
Если Запись.Субконто2 = NULL Тогда
// Устанавливаем Неопределено или пустую ссылку типа ДокументОприходования
Запись.Субконто2 = Неопределено;
КонецЕсли;
КонецЦикла;
НаборЗаписей.Записать();
Важный момент: перед массовым исправлением обязательно сделайте резервную копию базы данных. В некоторых конфигурациях (например, в «Бухгалтерии предприятия») тип субконто жестко определен в плане счетов, и запись значения Неопределено вместо NULL позволит виртуальной таблице остатков корректно «свернуть» записи в одну строку.
Если в движениях все чисто, но остатки все равно двоятся, это признак некорректных записей в физических таблицах итогов (таблицы с префиксами _AccRgED и _AccRgT). Рассмотрим алгоритм действий для глубокой очистки:
Рассмотрим причину, по которой стандартное тестирование и исправление часто оказывается бессильным. ТиИ выполняет проверку ссылочной целостности (битых ссылок). Однако NULL и Неопределено — это валидные типы данных для платформы. С точки зрения 1С, запись с NULL — это просто запись с другим значением ключа аналитики. Система не считает это ошибкой, которую нужно «чинить» автоматически. Именно поэтому требуется ручное вмешательство программиста для унификации данных в регистре.
Подводя итог нашему анализу, выделим основные причины «странной аналитики» в РБ:
Для предотвращения подобных проблем в будущем рекомендуется проверять код доработок, которые выполняют прямую запись в регистр бухгалтерии (через НаборЗаписей), и следить за тем, чтобы во все измерения и субконто передавались значения правильного типа, избегая записи NULL там, где ожидается ссылка или Неопределено.