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