Как правильно перенести проводки из регистра бухгалтерии и загрузить их в документ Операция в 1С?

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

Перенос бухгалтерских проводок между различными конфигурациями 1С — распространенная задача при смене учетных систем, объединении баз или интеграции специализированных отраслевых решений (например, систем доверительного управления или учета некредитных финансовых организаций — НФО) с типовыми конфигурациями «1С:Бухгалтерия предприятия».

Разберем детально, как устроена архитектура проводок в 1С, как правильно выгрузить движения из регистра бухгалтерии источника и как программно создать документы ОперацияБух в базе-приемнике, избежав типичных ошибок при работе с наборами записей.

Архитектура хранения проводок и роль документа Операция

Проанализируем базовый принцип работы подсистемы бухгалтерского учета платформы 1С:Предприятие:

  1. Проводки не существуют отдельно от регистратора: любая запись в регистре бухгалтерии обязана иметь ссылку на документ-регистратор (измерение Регистратор). В типовых документах проводки формируются при проведении.
  2. Документ «ОперацияБух» как универсальный регистратор: если данные переносятся в виде готовых проводок без создания первичных документов (накладных, актов, платежек), в приемнике создается документ ОперацияБух. Сам документ выступает заголовком и носителем ссылки-регистратора, а сами проводки хранятся в наборе записей соответствующего регистра бухгалтерии (например, Хозрасчетный или отраслевого ЕПС).
  3. Сумма операции и реквизиты: реквизиты документа ОперацияБух (сумма, содержание, организация) являются информационными полями шапки. Реальный балансовый и аналитический учет строится исключительно на строках движений регистра.

Выгрузка проводок из регистра бухгалтерии источника

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


ВЫБРАТЬ
    ЕПСДвиженияССубконто.Период КАК Период,
    ЕПСДвиженияССубконто.Регистратор КАК Регистратор,
    ЕПСДвиженияССубконто.НомерСтроки КАК НомерСтроки,
    ЕПСДвиженияССубконто.Активность КАК Активность,
    ЕПСДвиженияССубконто.СчетДт КАК СчетДт,
    ЕПСДвиженияССубконто.СубконтоДт1 КАК СубконтоДт1,
    ЕПСДвиженияССубконто.ВидСубконтоДт1 КАК ВидСубконтоДт1,
    ЕПСДвиженияССубконто.СубконтоДт2 КАК СубконтоДт2,
    ЕПСДвиженияССубконто.ВидСубконтоДт2 КАК ВидСубконтоДт2,
    ЕПСДвиженияССубконто.СчетКт КАК СчетКт,
    ЕПСДвиженияССубконто.СубконтоКт1 КАК СубконтоКт1,
    ЕПСДвиженияССубконто.ВидСубконтоКт1 КАК ВидСубконтоКт1,
    ЕПСДвиженияССубконто.СубконтоКт2 КАК СубконтоКт2,
    ЕПСДвиженияССубконто.ВидСубконтоКт2 КАК ВидСубконтоКт2,
    ЕПСДвиженияССубконто.Организация КАК Организация,
    ЕПСДвиженияССубконто.Сумма КАК Сумма,
    ЕПСДвиженияССубконто.Содержание КАК Содержание
ИЗ
    РегистрБухгалтерии.ЕПС.ДвиженияССубконто(&НачДата, &КонДата, Портфель = &Портфель, , ) КАК ЕПСДвиженияССубконто
УПОРЯДОЧИТЬ ПО
    ЕПСДвиженияССубконто.Регистратор,
    ЕПСДвиженияССубконто.НомерСтроки

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

Типичная ошибка при программной записи набора проводок

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


// ОШИБОЧНЫЙ КОД
Для Каждого СтрТ Из Таблица Цикл
    // ... создание документа ОперацияБух ...
    
    // ОШИБКА: набор создается заново на каждой строке
    РегХозрасчетный = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
    РегХозрасчетный.Отбор.Регистратор.Значение = ДокОперацияСсылка;
    
    РегЗапись = РегХозрасчетный.Добавить();
    // Заполнение полей РегЗапись...
    
    // ОШИБКА: перезапись набора затирает все добавленные ранее проводки документа!
    РегХозрасчетный.Записать(); 
КонецЦикла;

Вызов метода СоздатьНаборЗаписей() инициализирует пустой набор. При вызове Записать() платформа перезаписывает движения регистратора. В результате в документе остается только одна последняя обработанная проводка.

Правильный алгоритм программного создания операций и заполнения проводок

Разберем по шагам правильную структуру алгоритма:

  1. Группируем строки по идентификатору исходного документа (или номеру/дате).
  2. При смене документа-регистратора записываем накопленный набор записей для предыдущей операции.
  3. Создаем и записываем новый документ ОперацияБух.
  4. Инициализируем новый НаборЗаписей с отбором по ссылке нового документа.
  5. Добавляем проводки в набор через метод Добавить().
  6. Заполняем субконто счетов с помощью типового механизма БухгалтерскийУчет.УстановитьСубконто.
  7. После завершения цикла записываем последний обработанный набор записей.

Посмотрим на пример корректной реализации алгоритма загрузки:


Процедура ЗагрузитьПроводкиВОперации(ТаблицаПроводок)

    ЗагрОрг = Справочники.Организации.НайтиПоНаименованию("ОАО ""РОНИН Траст""");
    Ответственный = ПараметрыСеанса.ТекущийПользователь;
    
    ТекущийРегистраторНомер = "";
    ДокОперацияОбъект = Неопределено;
    НаборЗаписей = Неопределено;
    СуммаПоОперации = 0;

    Для Каждого СтрТ Из ТаблицаПроводок Цикл
        
        Если ПустаяСтрока(СтрТ.Период) Тогда
            Продолжить;
        КонецЕсли;

        НомерИсходногоДокумента = СтрЗаменить(СтрТ.РегистраторНомер, ",", "");

        // Проверяем, начался ли новый документ
        Если НомерИсходногоДокумента <> ТекущийРегистраторНомер Тогда
            
            // Если предыдущий набор был открыт — записываем его
            Если НаборЗаписей <> Неопределено И НаборЗаписей.Количество() > 0 Тогда
                НаборЗаписей.Записать();
                
                // Актуализируем итоговую сумму в шапке документа
                ДокОперацияОбъект.СуммаОперации = СуммаПоОперации;
                ДокОперацияОбъект.Записать();
            КонецЕсли;

            // Создаем новый документ ОперацияБух
            ДокОперацияОбъект = Документы.ОперацияБух.СоздатьДокумент();
            ДокОперацияОбъект.Номер = НомерИсходногоДокумента;
            ДокОперацияОбъект.Дата = Дата(СтрТ.Период);
            ДокОперацияОбъект.Организация = ЗагрОрг;
            ДокОперацияОбъект.Ответственный = Ответственный;
            ДокОперацияОбъект.Содержание = "Перенос проводок из внешней системы";
            ДокОперацияОбъект.Комментарий = "Загружено обработкой " + Строка(ТекущаяДата());
            ДокОперацияОбъект.Записать();

            ТекущийРегистраторНомер = НомерИсходногоДокумента;
            СуммаПоОперации = 0;

            // Инициализируем набор записей для нового регистратора
            НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
            НаборЗаписей.Отбор.Регистратор.Установить(ДокОперацияОбъект.Ссылка);
            
        КонецЕсли;

        // Добавляем строку проводки в набор
        РегЗапись = НаборЗаписей.Добавить();
        РегЗапись.Период = Дата(СтрТ.Период);
        РегЗапись.Регистратор = ДокОперацияОбъект.Ссылка;
        РегЗапись.Организация = ЗагрОрг;
        РегЗапись.Содержание = СтрТ.Содержание;

        // Счета дебета и кредита
        РегЗапись.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду(СтрЗаменить(СтрТ.СчетДт, ".", ""));
        РегЗапись.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду(СтрЗаменить(СтрТ.СчетКт, ".", ""));

        // Установка субконто по Дебету
        Если ЗначениеЗаполнено(СтрТ.ВидСубконтоДт1) И ЗначениеЗаполнено(РегЗапись.СчетДт) Тогда
            ВидСубконтоДт = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.НайтиПоНаименованию(СтрТ.ВидСубконтоДт1);
            ЗначениеСубконто = НайтиВСПР(СтрТ.ВидСубконтоДт1, СтрТ.СубконтоДт1);
            БухгалтерскийУчет.УстановитьСубконто(РегЗапись.СчетДт, РегЗапись.СубконтоДт, ВидСубконтоДт, ЗначениеСубконто);
        КонецЕсли;

        // Установка субконто по Кредиту
        Если ЗначениеЗаполнено(СтрТ.ВидСубконтоКт1) И ЗначениеЗаполнено(РегЗапись.СчетКт) Тогда
            ВидСубконтоКт = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.НайтиПоНаименованию(СтрТ.ВидСубконтоКт1);
            ЗначениеСубконто = НайтиВСПР(СтрТ.ВидСубконтоКт1, СтрТ.СубконтоКт1);
            БухгалтерскийУчет.УстановитьСубконто(РегЗапись.СчетКт, РегЗапись.СубконтоКт, ВидСубконтоКт, ЗначениеСубконто);
        КонецЕсли;

        РегЗапись.Сумма = Число(СтрТ.Сумма);
        СуммаПоОперации = СуммаПоОперации + РегЗапись.Сумма;

    КонецЦикла;

    // Записываем последний обработанный набор записей
    Если НаборЗаписей <> Неопределено И НаборЗаписей.Количество() > 0 Тогда
        НаборЗаписей.Записать();
        ДокОперацияОбъект.СуммаОперации = СуммаПоОперации;
        ДокОперацияОбъект.Записать();
    КонецЕсли;

КонецПроцедуры

Рекомендации по выбору инструмента интеграции

При реализации переноса проводок между базами 1С следует сопоставить трудозатраты выбранного подхода:

  1. Использование «1С:Конвертация данных 2.18» (КД 2): оптимальный вариант для регулярного или масштабного переноса. Конфигурация автоматически обрабатывает сопоставление ссылочных типов (справочников, перечислений, планов счетов) по уникальным идентификаторам и реквизитам поиска, исключая дублирование аналитики.
  2. Собственный скрипт/обработка: оправдан при разовом переносе фиксированных остатков или небольшого среза проводок. При этом разработчик обязан вручную реализовать алгоритмы синхронизации субконто, валидацию заполнения обязательных реквизитов и корректную группировку строк по регистраторам.
← На главную