Как правильно скопировать проводку в 1С:Предприятие 8

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

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

Метод 1. Копирование через Таблицу Значений

Первый и самый распространенный способ — это использование промежуточной таблицы значений. Механика работы с данными в памяти здесь отдаленно напоминает добавление данных в существующую временную таблицу, но со своими особенностями. Проанализируем, почему нельзя просто добавить новую запись в набор и приравнять её к существующей. В регистре бухгалтерии есть системное поле НомерСтроки, которое управляется платформой автоматически. Если мы попытаемся скопировать его напрямую, система может выдать ошибку или проигнорировать запись.

Рассмотрим пошагово алгоритм через выгрузку в ТаблицаЗначений:

  1. Получаем объект документа и читаем его движения.
  2. Выгружаем движения в таблицу значений.
  3. Добавляем новую строку в таблицу, копируя данные из образца, но исключая системные поля.
  4. Загружаем таблицу обратно в набор записей.

Посмотрим на пример кода, реализующий этот подход:


ДокОбъект = Док.ПолучитьОбъект();
Хозрасчетный = ДокОбъект.Движения.Хозрасчетный;
Хозрасчетный.Прочитать();

// Выгружаем движения в ТЗ для манипуляций
ТЗ = Хозрасчетный.Выгрузить(); 

// Добавляем новую строку, копируя все свойства из первой строки (индекс 0),
// при этом обязательно исключаем "НомерСтроки", чтобы платформа назначила его сама
ЗаполнитьЗначенияСвойств(ТЗ.Добавить(), ТЗ[0], , "НомерСтроки");

// Загружаем измененную таблицу обратно в движения документа
Хозрасчетный.Загрузить(ТЗ);

Этот метод хорош тем, что ЗаполнитьЗначенияСвойств корректно переносит простые реквизиты: счет, сумму, количество, содержание. Однако он имеет ограничение при работе с субконто, если они не представлены в виде колонок в ТЗ.

Метод 2. Копирование напрямую в наборе записей

Если нам нужно минимизировать количество операций и не плодить лишние объекты в памяти, мы можем работать непосредственно с коллекцией движений. Проанализируем ситуацию: метод Добавить() создает пустую запись, которую нам нужно заполнить по образу и подобию существующей.

Рассмотрим компактный вариант реализации:


// Предположим, ДокОбъект уже получен
ДвиженияХозрасчетный = ДокОбъект.Движения.Хозрасчетный;
ДвиженияХозрасчетный.Прочитать();

// Создаем новую проводку
НоваяПроводка = ДвиженияХозрасчетный.Добавить();

// Копируем данные из первой существующей проводки (индекс 0)
// Исключаем НомерСтроки, так как это системный идентификатор
ЗаполнитьЗначенияСвойств(НоваяПроводка, ДвиженияХозрасчетный[0], , "НомерСтроки");

Важное замечание: Несмотря на компактность, этот способ часто "спотыкается" на субконто. В 1С СубконтоДт и СубконтоКт — это не просто поля, а специальные коллекции (наборы записей). Прямое копирование через ЗаполнитьЗначенияСвойств не перенесет аналитику автоматически.

Метод 3. Решение проблемы с Субконто через БСП

Выясним причину, по которой субконто не копируются обычными методами. Аналитика в регистре бухгалтерии хранится в подчиненной таблице. Когда мы обращаемся к Проводка.СубконтоДт, мы получаем объект типа РегистрБухгалтерииСубконто.Хозрасчетный.

Если в вашей конфигурации используется Библиотека стандартных подсистем (БСП), задача решается значительно проще. В модуле БухгалтерскийУчетДвижения (или аналогичных модулях бухгалтерского учета в БП 3.0) существуют вспомогательные функции. Для уверенной работы с ними рекомендуем использовать справочник по методам БСП.

Разберем пример с использованием функций БСП:


// Копирование субконто дебета из старой проводки в новую
БухгалтерскийУчет.СкопироватьСубконто(ИсточникПроводка.СчетДт, ИсточникПроводка.СубконтоДт, 
                                     НоваяПроводка.СчетДт, НоваяПроводка.СубконтоДт);

// Аналогично для кредита
БухгалтерскийУчет.СкопироватьСубконто(ИсточникПроводка.СчетКт, ИсточникПроводка.СубконтоКт, 
                                     НоваяПроводка.СчетКт, НоваяПроводка.СубконтоКт);

Если же БСП не используется, нам придется обходить коллекцию субконто в цикле, используя метод Вставить() или Установить() для каждого вида субконто, определенного на счете.

Метод 4. Оптимизация через RecordSet (Набор записей)

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

Проанализируем шаги:

  1. Создаем набор записей регистра бухгалтерии.
  2. Устанавливаем фильтр по регистратору (нашему документу).
  3. Читаем данные.
  4. Добавляем новые записи в таблицу и записываем набор.

Такой подход работает быстрее, так как не инициализирует тяжелые модули объекта документа и его экранные формы. Однако в сложных сценариях записи может потребоваться самодельный обработчик ПослеЗаписи, чтобы гарантировать корректное завершение транзакции.


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

ТЗ_Движений = Набор.Выгрузить();

// Копируем нужную строку
НоваяСтрока = ТЗ_Движений.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ТЗ_Движений[0], , "НомерСтроки");

Набор.Загрузить(ТЗ_Движений);
Набор.Записать();

Нюансы, о которых нельзя забывать

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

Подводя итог, можно сказать, что самый надежный способ копирования "в лоб" для программиста — это использование ТаблицыЗначений с четким исключением системных колонок и обязательным использованием специализированных методов для копирования аналитики (субконто). Это гарантирует целостность данных и корректную работу бухгалтерских отчетов.

← На главную