Как программно получить доступ к содержанию проводок документа ОперацияБух в 1С

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

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

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

Почему у документа ОперацияБух нет табличной части проводок

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

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

Способ 1. Изменение проводок через коллекцию движений документа

Рассмотрим вариант, когда у нас уже есть ссылка на документ или получен сам объект документа. В этом случае мы можем обратиться к свойству объекта Движения.

Разберем по шагам последовательность действий:

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

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


// Находим нужный документ (например, по номеру и дате)
СсылкаНаДокумент = Документы.ОперацияБух.НайтиПоНомеру("00000000718", Дата(2016, 12, 31));

Если Не ЗначениеЗаполнено(СсылкаНаДокумент) Тогда
    ВызватьИсключение "Документ с указанным номером и датой не найден!";
КонецЕсли;

ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();

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

// Считываем текущие проводки документа
НаборЗаписей.Прочитать();

// Обходим проводки и корректируем содержание
Для Каждого Проводка Из НаборЗаписей Цикл
    Проводка.Содержание = "Корректировка остатков";
КонецЦикла;

// Записываем измененный набор движений в базу данных
НаборЗаписей.Записать();

Способ 2. Оптимальный вариант: работа напрямую через набор записей регистра

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

Значительно безопаснее и быстрее создать набор записей непосредственно из менеджера регистра бухгалтерии, установив отбор по регистратору:


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

// Устанавливаем жесткий отбор по нашему документу
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);

// Считываем записи регистра по установленному отбору
НаборЗаписей.Прочитать();

Для Каждого Запись Из НаборЗаписей Цикл
    Запись.Содержание = "Корректировка расчетного счета";
КонецЦикла;

// Записываем набор обратно в базу данных
НаборЗаписей.Записать();

Важные технические нюансы и частые ошибки

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

  1. Опасность потери данных при пропуске метода Прочитать(). Метод Записать() у набора записей по умолчанию выполняется с параметром Замещать = Истина. Если перед циклом забыть вызвать НаборЗаписей.Прочитать(), платформа посчитает набор пустым и метод Записать() просто удалит все существующие проводки документа.
  2. Ограничение длины строки реквизита. Поле Содержание проводки в типовом регистре бухгалтерии Хозрасчетный имеет ограниченную длину (как правило, до 100 символов). Если передать строку большего размера, платформа автоматически усечет текст до максимальной длины метаданных без генерации ошибок.
  3. Особенности поиска через НайтиПоНомеру(). Метод НайтиПоНомеру() чувствителен к точной длине строки номера, префиксам организации и информационных баз, а также ведущим нулям. Если в одном периоде работают несколько организаций с пересекающейся нумерацией, метод может вернуть некорректную ссылку. Для надежного поиска документов в пакетных обработках рекомендуется использовать запрос 1С с отбором по номеру, организации и периоду.
  4. Синхронизация суммы операции. Документ ОперацияБух не использует стандартный механизм проведения через ОбработкаПроведения. В шапке документа присутствует реквизит СуммаОперации. Если при модификации движений вы изменяете не только текстовое содержание, но и суммы проводок, сумма в шапке документа автоматически не пересчитается. В этом случае потребуется открыть и пересчитать реквизит через запись самого объекта документа.
← На главную