При работе с базами данных 1С, особенно после обменов между конфигурациями (например, ЗУП и БП) или неудачных сверток, мы можем столкнуться с ситуацией, когда в Оборотно-сальдовой ведомости (ОСВ) появляются "фантомные" строки. Визуально субконто пустое, но строки не сворачиваются. При программном анализе выясняется, что в этих полях содержатся значения неверных типов: Неопределено, пустые ссылки на справочники или вообще значения типов, не предусмотренных Планом счетов для данного счета (например, на счете 70 вместо "Сотрудника" записан "Вид начисления").
Попытки исправить это стандартной ОперациейБух (введенной вручную) обычно заканчиваются неудачей, так как платформа включает строгий контроль типов и просто не дает выбрать "неверное" значение в качестве списываемого субконто. В этой статье мы подробно разберем причины возникновения таких ошибок и способы их устранения.
Прежде чем приступать к лечению, давайте проанализируем, откуда берутся значения типов, не свойственных плану счетов.
СправочникСсылка.ВидыНачисленийОплатыТрудаДляНалоговогоУчетаПоНалогуНаПрибыль на счете, где ожидаются только РаботникиОрганизаций.Главная проблема для программиста заключается в следующем: если вы попробуете создать документ ОперацияБух и в проводке попытаетесь указать в Кредите счета 70 значение типа "Вид начисления", платформа 1С автоматически очистит это поле, так как в метаданных счета 70 такого типа субконто нет.
Самый безопасный и "штатный" метод решения проблем с битыми ссылками и некорректными типами — это использование встроенного механизма тестирования.
Важно: Перед выполнением любых действий обязательно сделайте резервную копию базы данных. Если база повреждена сильно (как упоминалось в обсуждении, не выгружается в .dt), делайте копию файла базы (.1CD) или бэкап средствами SQL.
Выполним следующие шаги в режиме Конфигуратора:
Запуск этой процедуры часто помогает привести типы субконто к значению NULL или пустой ссылке правильного типа, что позволит в дальнейшем свернуть их обработкой "Поиск и замена значений" или ручной операцией.
Если база данных находится в плохом состоянии ("мертвая", не выгружается), стандартное ТИИ может не сработать или зависнуть. В этом случае обратимся к более низкоуровневым инструментам.
Для файлового варианта:
chdbfl.exe в папке bin установки платформы 1С.Для клиент-серверного варианта (SQL):
DBCC CHECKDB ('ИмяВашейБазы');
Эти действия не исправят логику (не заменят "Вид начисления" на "Сотрудника"), но они могут починить структуру таблиц, что позволит базе нормально работать и выгружаться.
Если ТИИ не помогло или вы хотите точечно исправить конкретные записи регистра бухгалтерии, не пересчитывая всю базу, нам потребуется написать небольшую обработку. Это самый действенный метод для "неуловимых" типов данных.
Суть метода: мы не создаем новые проводки, чтобы закрыть старые (это невозможно из-за контроля типов). Мы изменяем существующие записи регистра, заменяя неправильное значение на правильное (или пустое правильного типа).
Для этого необходимо использовать свойство ОбменДанными.Загрузка = Истина. Этот флаг отключает проверки платформы при записи набора данных.
Разберем алгоритм решения задачи:
Посмотрим на пример кода, который выполняет эту задачу:
Процедура ИсправитьБитоеСубконто(СсылкаНаДокумент)
// Создаем набор записей для регистра Хозрасчетный
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
// Устанавливаем отбор по регистратору (документу, создавшему проводку)
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);
// Читаем существующие движения
НаборЗаписей.Прочитать();
НуженСбросЗаписи = Ложь;
Для Каждого Движение Из НаборЗаписей Цикл
// Проверяем счет, например 70
Если Движение.СчетДт.Код = "70" Тогда
// Анализируем СубконтоДт. Например, первое субконто должно быть Сотрудником
// Проверяем тип значения. Если это НЕ Справочник.ФизическиеЛица (или Сотрудники), значит ошибка
Если ТипЗнч(Движение.СубконтоДт.РаботникиОрганизаций) <> Тип("СправочникСсылка.ФизическиеЛица") Тогда
// Исправляем на пустую ссылку правильного типа или на конкретного "технического" сотрудника
Движение.СубконтоДт.РаботникиОрганизаций = Справочники.ФизическиеЛица.ПустаяСсылка();
НуженСбросЗаписи = Истина;
КонецЕсли;
КонецЕсли;
// Аналогичная проверка для Кредита
Если Движение.СчетКт.Код = "70" Тогда
// В зависимости от конфигурации ключ субконто может называться иначе (Субконто1, Субконто2...)
// Лучше обращаться через коллекцию СубконтоКт
КлючСубконто = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.РаботникиОрганизаций;
Если Движение.СубконтоКт.Свойство(КлючСубконто) Тогда
ТекущееЗначение = Движение.СубконтоКт[КлючСубконто];
// Если тип неверный (например, Неопределено или левый справочник)
Если ТипЗнч(ТекущееЗначение) <> Тип("СправочникСсылка.ФизическиеЛица") Тогда
// Заменяем на пустое физлицо
Движение.СубконтоКт.Вставить(КлючСубконто, Справочники.ФизическиеЛица.ПустаяСсылка());
НуженСбросЗаписи = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если НуженСбросЗаписи Тогда
// Самый важный момент! Отключаем проверки
НаборЗаписей.ОбменДанными.Загрузка = Истина;
НаборЗаписей.Записать();
Сообщить("Записи документа " + СсылкаНаДокумент + " исправлены.");
КонецЕсли;
КонецПроцедуры
Если база данных старая и ошибок много, точечное исправление может занять много времени. В этом случае стоит рассмотреть вариант Свертки базы.
Однако стандартная свертка может споткнуться об те же самые ошибки типов данных. Поэтому мы рекомендуем комбинированный подход:
Если вы не хотите писать код, можно воспользоваться готовыми инструментами сообщества, такими как "Универсальный редактор регистров" или "Редактор движений документов".
Принцип работы с ними:
Хозрасчетный).ОбменДанными.Загрузка = Истина, что позволяет обойти контроль типов.Проблема "битых" типов в субконто решается, но требует вмешательства на уровне записи регистров. Стандартные бухгалтерские документы здесь бессильны. Помните, что приоритет действий должен быть таким: