Почему не переносится План счетов и возникает ошибка "Не заполнен счет дебета" при переносе данных (КД 2)?

Программист 1С v8.3 (Управляемые формы) Бухгалтерский учет
← На главную

Рассмотрим распространенную проблему при настройке правил обмена в "Конвертации данных 2.0/2.1" (КД). Ситуация, с которой часто сталкиваются разработчики, выглядит следующим образом: при выгрузке документа (например, "Ввод начальных остатков" или "Поступление материалов") из базы-источника данные уходят корректно. Однако в базе-приемнике, несмотря на то, что документ создается, поля счетов в табличных частях (ТЧ) оказываются пустыми.

Это приводит к критической ошибке при попытке записи движений документа (хотя сама выгрузка движений документа XML может проходить без ошибок). В журнале регистрации или окне сообщений мы видим ошибку:


Ошибка при вызове метода контекста (Записать): Не удалось записать: "Журнал проводок (ЕПСБУ)"!
Проводка 1. Не заполнен счет дебета

Разберем подробно причины этого поведения, почему отладчик может вводить в заблуждение, и рассмотрим два способа решения (по методике конвертации данных 2): "быстрый" (через код в обработчиках) и "правильный" (через передачу параметров).

Диагностика проблемы: Почему счет исчезает?

В описанной ситуации (особенно характерной для бюджетного учета — БГУ, план счетов ЕПСБУ) происходит следующее:

  1. В источнике: Счет в табличной части заполнен (например, 105.36).
  2. При выгрузке: Данные попадают в XML-файл (такая выгрузка в XML стандартна для многих процессов). Если открыть файл, мы увидим там код счета и, возможно, наименование.
  3. При загрузке (в отладчике): Если поставить точку останова в обработчике ПослеЗагрузки, можно увидеть, что в объекте документа в ТЧ "Материалы" поле "Счет" заполнено объектом типа ПланСчетовСсылка.
  4. После записи: Счета очищаются, документ не проводится или не записывает движения.

Причина кроется в механизме поиска ссылок (ПКО).

Когда система загружает данные, она пытается найти счет в базе-приемнике. В правилах конвертации объектов (ПКО) для плана счетов обычно стоят флаги поиска "По коду" и/или "По наименованию".

Решение 1: Программное дозаполнение счетов (Метод "Пост-обработка")

Если стандартный поиск по ПКО не срабатывает из-за различий в планах счетов (например, разная структура субсчетов или предопределенных элементов), можно явно указать соответствие счетов в обработчике ПослеЗагрузкиОбъекта в правилах для Документа.

Этот метод требует написания кода, но позволяет жестко контролировать, какой счет будет подставлен.

Рассмотрим пример кода, который нужно разместить в ПКО документа "Ввод начальных остатков" на вкладке Обработчики событий -> После загрузки.


// Определяем переменную для хранения найденного счета
СчетЕПСБУ = ПланыСчетов.ЕПСБУ.ПустаяСсылка();

// Логика сопоставления. 
// Объект.Счет - это счет из шапки документа (обычно групповой, например 105.00)
// Нам нужно определить детальный счет для строк (например 105.36)

Если Объект.Счет.Код = "105.00" Тогда
    // Ищем конкретный счет в базе-приемнике
    СчетЕПСБУ = ПланыСчетов.ЕПСБУ.НайтиПоКоду("105.36");
    
ИначеЕсли Объект.Счет.Код = "07" Тогда
    СчетЕПСБУ = ПланыСчетов.ЕПСБУ.НайтиПоКоду("07.2");
    
ИначеЕсли Объект.Счет.Код = "01.32" Тогда
    // Если коды совпадают, все равно ищем явно, чтобы исключить ошибки ссылок
    СчетЕПСБУ = ПланыСчетов.ЕПСБУ.НайтиПоКоду("01.32");
КонецЕсли;

// Если счет найден, заполняем табличную часть
Если ЗначениеЗаполнено(СчетЕПСБУ) Тогда
    
    // 1. Заполняем табличную часть "Материалы"
    Для каждого СтрокаТЧ Из Объект.Материалы Цикл
        // Можно заполнять всегда или только если пусто
        Если НЕ ЗначениеЗаполнено(СтрокаТЧ.Счет) Тогда
            СтрокаТЧ.Счет = СчетЕПСБУ;
        КонецЕсли;
    КонецЦикла;
    
    // 2. Исправляем движения (проводки), так как ошибка возникала именно там
    // Выгружаем набор записей в таблицу значений для обработки
    ТаблицаДвижений = Объект.Движения.ЖурналПроводокЕПСБУ.Выгрузить();
    
    Для каждого Проводка Из ТаблицаДвижений Цикл
        // Заполняем счет дебета (или кредита, в зависимости от операции)
        Проводка.СчетДт = СчетЕПСБУ;
    КонецЦикла;
    
    // Загружаем исправленные движения обратно в набор
    Объект.Движения.ЖурналПроводокЕПСБУ.Загрузить(ТаблицаДвижений);
    
КонецЕсли;

Важно: При таком подходе необходимо установить у документа режим записи, который не перезаписывает движения автоматически, либо убедиться, что ваша логика выполняется после формирования движений системой.

Решение 2: Передача таблицы счетов через Параметры (Универсальный метод)

Более продвинутый способ — не "хардкодить" счета в приемнике (ведь коды могут меняться), а передать реальные коды счетов из базы-источника в базу-приемник через параметры конвертации.

Этот метод позволяет передать произвольную таблицу данных вместе с объектом.

Шаг 1. Источник (Перед выгрузкой)

В ПКО документа на стороне источника, в событии ПередВыгрузкой, соберем коды счетов из табличной части в структуру и поместим её в ИсходящиеДанные.


// Создаем таблицу для передачи информации о счетах
ТЗ_Счета = Новый ТаблицаЗначений;
ТЗ_Счета.Колонки.Добавить("НомерСтроки");
ТЗ_Счета.Колонки.Добавить("КодСчета");

// Обходим табличную часть источника
Для Каждого Стр Из Источник.Материалы Цикл
    НовСтр = ТЗ_Счета.Добавить();
    НовСтр.НомерСтроки = Стр.НомерСтроки;
    // Нам важен именно текстовый код, так как ссылка не перенесется напрямую
    НовСтр.КодСчета = Стр.Счет.Код; 
КонецЦикла;

// Передаем таблицу в параметры, которые уйдут в XML
// В КД 2 можно использовать ИсходящиеДанные, если настроено ПКС,
// либо передавать через параметры узла, но надежнее через свойства.
// Создадим фиктивное свойство (см. ниже) или используем ВходящиеДанные приемника.
ВходящиеДанные = Новый Структура("ТаблицаСчетовМатериалов", ТЗ_Счета);

Шаг 2. Настройка ПКО

Чтобы ВходящиеДанные передались, в правилах конвертации свойств (ПКС) документа можно создать фиктивное свойство. Но проще воспользоваться механизмом ПараметрыОбъекта.

В обработчике После загрузки в приемнике параметры из файла обмена доступны через структуру ПараметрыОбъекта (если они были туда помещены при выгрузке).

Шаг 3. Приемник (После загрузки)

Теперь в базе-приемнике мы можем прочитать эти коды и найти соответствующие счета.


// Проверяем, передали ли мы таблицу
Если ПараметрыОбъекта <> Неопределено И ПараметрыОбъекта.Свойство("ТаблицаСчетовМатериалов") Тогда
    
    ТЗ_Счета = ПараметрыОбъекта.ТаблицаСчетовМатериалов;
    
    Для Каждого СтрТЧ Из Объект.Материалы Цикл
        
        // Ищем строку в переданной таблице по номеру строки
        НайденнаяСтрока = ТЗ_Счета.Найти(СтрТЧ.НомерСтроки, "НомерСтроки");
        
        Если НайденнаяСтрока <> Неопределено Тогда
            КодСчетаИсточника = НайденнаяСтрока.КодСчета;
            
            // Пытаемся найти счет в текущей базе по коду
            // Важно: Поиск должен быть точным
            НайдСчет = ПланыСчетов.ЕПСБУ.НайтиПоКоду(КодСчетаИсточника);
            
            Если ЗначениеЗаполнено(НайдСчет) Тогда
                СтрТЧ.Счет = НайдСчет;
            Иначе
                // Если по полному коду не нашли, можно искать родителя или аналог
                // Сообщить("Не найден счет: " + КодСчетаИсточника);
            КонецЕсли;
        КонецЕсли;
        
    КонецЦикла;
    
    // Аналогично обновляем движения, если они уже сформированы
    // ... см. код из Решения 1 для движений ...
    
КонецЕсли;

Резюме

Основная ошибка "Не заполнен счет дебета" возникает из-за того, что при конвертации ссылка на счет либо не находится, либо не соответствует типу счета (группа/элемент) в приемнике, и платформа очищает её перед записью набора записей регистра.

Для исправления используйте один из методов:

  1. Тщательно выверьте ПКО для Плана Счетов (поиск только по коду, синхронизация кодов, отсутствие пробелов).
  2. Используйте принудительное заполнение счетов в обработчике ПослеЗагрузки, если структура планов счетов в базах различается.
← На главную