При работе в сложных конфигурациях, таких как 1С:ERP Управление предприятием, пользователи иногда сталкиваются с парадоксальной ситуацией: в карточке счета или оборотно-сальдовой ведомости (ОСВ) отображаются неверные итоговые данные. Например, при оборотах по дебету 1000 и по кредиту 1000 конечное сальдо может составлять -400, хотя математически оно должно быть нулевым. При этом анализ движений в регистре бухгалтерии через консоль запросов не выявляет «лишних» строк. Разберем подробно, почему так происходит и как исправить эту проблему.
Для начала проанализируем, как система формирует отчеты. 1С не пересчитывает все записи регистра с начала времен каждый раз, когда вы открываете ОСВ. Вместо этого платформа использует виртуальные таблицы итогов. Данные в этих таблицах хранятся в разрезе периодов (обычно месяц) и всех измерений счета (организация, подразделение, субконто, валюта и т.д.).
Если в какой-то момент произошел технический сбой, данные в физической таблице движений могут разойтись с данными в таблице итогов. Типичные причины возникновения разрыва:
ОбменДанными.Загрузка = Истина, которые не инициировали пересчет итогов.NULL там, где их быть не должно.Прежде чем приступать к программным исправлениям, рассмотрим ситуацию со стороны настроек учета. В 1С:ERP счет 44.02 («Издержки обращения в организациях, осуществляющих промышленную и иную производственную деятельность») имеет сложную структуру. Выясним, не кроется ли ошибка в разрезах учета.
Иногда сальдо «разваливается» по подразделениям или направлениям деятельности, которые не выведены в текущий отчет. Проанализируем карточку счета, включив в настройках отображение всех возможных измерений: Подразделение, Направление деятельности, Валюта. Если по одному подразделению висит дебет, а по другому — кредит на ту же сумму, общее сальдо по счету может выглядеть корректно в одном отчете и некорректно в другом (если в одном включена группировка, а в другом — нет).
Если стандартное Тестирование и исправление с галочкой «Пересчет итогов» не помогло, попробуем обмануть систему и заставить ее полностью перестроить таблицы. Разберем по шагам:
Одной из самых коварных причин является наличие в регистре бухгалтерии значений NULL или пустых ссылок в полях, по которым на данном счете учет вестись не должен (например, поле Валюта заполнено для невалютного счета). Рассмотрим пример кода, который помогает выявить такие записи и «вылечить» их. Суть метода заключается в том, чтобы прочитать набор записей и перезаписать его, принудительно устанавливая NULL в те системные поля, которые не соответствуют настройкам счета.
Проанализируем следующий алгоритм исправления:
&НаСервере
Процедура ИсправитьНекорректныеПоляНаСервере()
Запрос = Новый Запрос;
// Выбираем регистраторы, где есть подозрение на мусорные данные в системных полях
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Хозрасчетный.Регистратор КАК Регистратор
|ИЗ
| РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
|ГДЕ
| (Хозрасчетный.ПодразделениеДт <> ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка)
| И НЕ Хозрасчетный.СчетДт.УчетПоПодразделениям)
| ИЛИ (Хозрасчетный.ВалютаДт <> ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка)
| И НЕ Хозрасчетный.СчетДт.Валютный)";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Набор = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
Набор.Прочитать();
Для Каждого Запись Из Набор Цикл
// Если счет не валютный, очищаем валюту
Если НЕ (ЗначениеЗаполнено(Запись.СчетДт) И Запись.СчетДт.Валютный) Тогда
Запись.ВалютаДт = NULL;
КонецЕсли;
Если НЕ (ЗначениеЗаполнено(Запись.СчетКт) И Запись.СчетКт.Валютный) Тогда
Запись.ВалютаКт = NULL;
КонецЕсли;
// Если на счете нет учета по подразделениям, очищаем их
Если НЕ (ЗначениеЗаполнено(Запись.СчетДт) И Запись.СчетДт.УчетПоПодразделениям) Тогда
Запись.ПодразделениеДт = NULL;
КонецЕсли;
Если НЕ (ЗначениеЗаполнено(Запись.СчетКт) И Запись.СчетКт.УчетПоПодразделениям) Тогда
Запись.ПодразделениеКт = NULL;
КонецЕсли;
КонецЦикла;
// Записываем с включенным режимом загрузки, чтобы не инициировать лишние проверки
Набор.ОбменДанными.Загрузка = Истина;
Набор.Записать();
КонецЦикла;
КонецПроцедуры
Важный момент: использование ОбменДанными.Загрузка = Истина позволяет обойти проверки бизнес-логики, но при этом платформа корректно обновляет итоги при записи набора. Это критически важно для исправления «битых» данных, которые накопились за старые периоды.
Чтобы окончательно убедиться, что проблема решена, выполним запрос не к таблице ДвиженияССубконто, а напрямую к виртуальной таблице остатков. Посмотрим на пример запроса:
ВЫБРАТЬ
ХозрасчетныйОстатки.Счет,
ХозрасчетныйОстатки.Организация,
ХозрасчетныйОстатки.Подразделение,
ХозрасчетныйОстатки.СуммаОстаток
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет = &НужныйСчет, , ) КАК ХозрасчетныйОстатки
Если этот запрос показывает остаток, а в карточке счета (которая строится по оборотам) вы его не видите — значит, в итогах «застряла» запись с заполненным измерением, которого нет в движениях. В 1С:ERP часто таким измерением выступает Направление деятельности. Проанализируем, все ли документы закрытия месяца корректно сформировали проводки по этому разрезу.
Для предотвращения подобных ситуаций в будущем рекомендуем придерживаться следующих правил:
Подведем итог: если вы столкнулись с «фантомным» сальдо, сначала попробуйте сдвинуть границу рассчитанных итогов, а если это не поможет — воспользуйтесь программной очисткой регистра от некорректных NULL-значений. Эти действия в 99% случаев решают проблему отображения данных в отчетах.