В практике работы с базами 1С:Бухгалтерия (особенно в версии ПРОФ) встречается неприятная техническая коллизия: при просмотре «Карточки счета» или других стандартных отчетов бухгалтер видит странную картину — первая строка субконто пустая (отображается как пустые скобки < >), а заполненные значения смещены на вторую или третью позицию. При этом, если зайти в сам документ, все поля заполнены корректно. Перепроведение документа исправляет ситуацию, но если таких записей тысячи, перепроводить всю базу — задача рискованная и трудоемкая. В данной статье мы разберем, почему это происходит и как исправить ситуацию с помощью программного кода.
Проанализируем ситуацию с точки зрения архитектуры платформы. В регистре бухгалтерии Хозрасчетный данные субконто хранятся в виде индексированной коллекции. Для каждой записи предусмотрено три (в типовых решениях) слота под субконто: Субконто1, Субконто2 и Субконто3. Порядок их заполнения строго соответствует порядку видов субконто, заданных в Плане счетов для конкретного счета.
Основными причинами возникновения «пустот» являются:
Вести учет по подразделениям, это могло привести к смещению индексов в таблице регистра. Программа начинает «думать», что первое субконто пустое, и записывает значимые данные во второе.Запись.Субконто[ВидСубконто] без учета индексации (например, при корректировке проводок по начислению матпомощи), или если вид субконто был удален из Плана счетов, а затем добавлен снова.Рассмотрим, почему это критично. Для отчетов (экранных форм) платформа пытается сопоставить данные из регистра с метаданными счета. Если первое значение в регистре — NULL или ПустаяСсылка, отчет честно рисует пустоту. При интерактивном перепроведении система заново вызывает обработчик проведения документа, который «схлопывает» коллекцию субконто, записывая их строго по порядку (1, 2, 3) без пропусков.
Особое коварство этой ошибки проявляется при Закрытии месяца. Проанализируем ситуацию: бухгалтер пытается выполнить распределение затрат, но система выдает ошибку. Это происходит потому, что алгоритмы расчета себестоимости обращаются не к документам, а к итогам регистра. Если в регистре «битая» аналитика (например, пустое первое субконто на счете 25), база распределения не может собраться корректно, так как ключ аналитики в таблице итогов не совпадает с ожидаемым.
Иногда помогает временное включение и последующее отключение признака учета по подразделениям на счете, но это лишь «костыль». Для проверки корректности данных после таких манипуляций полезно убедиться в отсутствии расхождений.
Чтобы решить проблему без перепроведения (сохраняя время и не затрагивая другие регистры, такие как НДС или взаиморасчеты), мы должны поработать с объектом РегистрБухгалтерииНаборЗаписей.Хозрасчетный. Наша задача — прочитать записи, выгрузить заполненные субконто во временную структуру и записать их обратно в правильном порядке.
Разберем по шагам алгоритм обработки или воспользуемся готовым инструментом для анализа и редактирования записей регистров:
Субконто1 пустое, а Субконто2 заполнено).СубконтоДт и СубконтоКт.Посмотрим на пример кода, который реализует эту логику:
Процедура ИсправитьСмещениеСубконто(РегистраторСсылка)
// Создаем набор записей для конкретного документа
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(РегистраторСсылка);
НаборЗаписей.Прочитать();
БылиИзменения = Ложь;
Для Каждого Запись Из НаборЗаписей Цикл
// Обрабатываем Дебет и Кредит отдельно
Если ИсправитьКоллекциюСубконто(Запись.СубконтоДт, Запись.СчетДт) Тогда
БылиИзменения = Истина;
КонецЕсли;
Если ИсправитьКоллекциюСубконто(Запись.СубконтоКт, Запись.СчетКт) Тогда
БылиИзменения = Истина;
КонецЕсли;
КонецЦикла;
// Записываем набор, только если нашли смещение
Если БылиИзменения Тогда
// Важно: отключаем выполнение обработчиков, чтобы не вызвать лишних движений
НаборЗаписей.Записать(Истина);
Сообщить("Документ " + РегистраторСсылка + " успешно исправлен.");
КонецЕсли;
КонецПроцедуры
Функция ИсправитьКоллекциюСубконто(КоллекцияСубконто, Счет)
Если Счет.Пустая() Или КоллекцияСубконто.Количество() = 0 Тогда
Возврат Ложь;
КонецЕсли;
// Собираем реально заполненные значения во временный массив
СписокЗначений = Новый СписокЗначений;
Для Каждого Элемент Из КоллекцияСубконто Цикл
Если ЗначениеЗаполнено(Элемент.Значение) Тогда
СписокЗначений.Добавить(Элемент.Значение, Элемент.Ключ);
КонецЕсли;
КонецЦикла;
// Если количество заполненных не совпадает с общим или порядок нарушен
// Простейший признак: если первое субконто пустое, а второе нет
Если СписокЗначений.Количество() > 0 И Не ЗначениеЗаполнено(КоллекцияСубконто[0].Значение) Тогда
// Очищаем текущую аналитику
КоллекцияСубконто.Очистить();
// Заполняем заново из списка по порядку видов субконто счета
Для Инд = 0 По СписокЗначений.Количество() - 1 Цикл
ВидСубКонто = Счет.ВидыСубконто[Инд].ВидСубконто;
КоллекцияСубконто.Вставить(ВидСубКонто, СписокЗначений[Инд].Значение);
КонецЦикла;
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Проанализируем ключевые моменты представленного выше кода. Мы используем метод ЗначениеЗаполнено(), чтобы отличить реальную аналитику от пустых ссылок. Важно помнить, что в коллекции субконто ключом является ПланВидовХарактеристикСсылка.ВидыСубконтоХозрасчетные.
Почему мы используем НаборЗаписей.Записать(Истина)?
Параметр Истина в методе Записать означает перезапись существующего набора. Однако, чтобы система не начала пересчитывать другие регистры (например, налоговый учет или НДС, если это не комплексная корректировка), убедитесь, что вы работаете только с Хозрасчетным. В некоторых случаях стоит использовать ОбменДанными.Загрузка = Истина, чтобы обойти проверки в подписках на события.
Как найти все «проблемные» документы?
Перед запуском исправления выполните в консоли запросов следующий поиск:
ВЫБРАТЬ РАЗЛИЧНЫЕ
Хозрасчетный.Регистратор
ИЗ
РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
Хозрасчетный.Субконто1 = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) // Замените на нужный тип или используйте NULL
И (НЕ Хозрасчетный.Субконто2 = ЗНАЧЕНИЕ(Справочник.СтатьиЗатрат.ПустаяСсылка))
Этот запрос поможет вам точечно определить документы, требующие вмешательства, не перебирая весь объем данных за несколько лет.
Мы выяснили, что «пустое субконто» — это не просто визуальный баг, а следствие нарушения структуры данных в регистре бухгалтерии 1С. Основной причиной является некорректная запись наборов данных при изменении учетной политики или миграции данных. Используя программный метод «пересортировки» коллекции субконто в объекте НаборЗаписей, мы можем быстро и безопасно восстановить целостность учета, не прибегая к массовому перепроведению документов и не нарушая последовательность границ партионного учета.