Почему не заполняется табличная часть «Расшифровка платежа» при программном создании документа «Оплата платежной картой»?

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

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

Выясним причину ошибки

Посмотрим на фрагмент исходного кода, где создается новый документ ОплатаПлатежнойКартой:


ДокОПК = Документы.ОплатаПлатежнойКартой.СоздатьДокумент();
ДокОПК.ВидОперации = Объект.ВидОперации;
ДокОПК.Контрагент = Склад;
ДокОПК.Дата = ДатаОПК;
ДокОПК.ВидОплаты = Объект.ВидОплаты;
ДокОПК.СуммаДокумента = СуммаОПК; 
ДокОПК.СтавкаНДС = Перечисления.СтавкиНДС.БезНДС;
ДокОПК.Организация = Справочники.Организации.НайтиПоКоду("00-000002");
ДокОПК.Комментарий = Склад.Наименование;

Для каждого Расшифровка Из ДокОПК.РасшифровкаПлатежа Цикл 
    Расшифровка.СпособПогашенияЗадолженности = Перечисления.СпособыПогашенияЗадолженности.Автоматически;
    Расшифровка.СуммаПлатежа = ДокОПК.СуммаДокумента;
    Расшифровка.КурсВзаиморасчетов = 1;
    Расшифровка.СуммаВзаиморасчетов = Расшифровка.СуммаПлатежа;
    Расшифровка.КратностьВзаиморасчетов = 1;
КонецЦикла;  

ДокОПК.Записать(РежимЗаписиДокумента.Запись);

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

Конструкция Для каждого Расшифровка Из ДокОПК.РасшифровкаПлатежа Цикл предназначена исключительно для обхода уже существующих строк коллекции. Поскольку строк в табличной части нет, платформе не по чему итерироваться: цикл завершается сразу же, тело цикла не выполняется ни разу, и ни одна строка с суммой так и не создается. В результате реквизит СуммаДокумента заполнен значением, а сумма по строкам пустой табличной части равна 0, что и вызывает отказ типовой проверки перед записью.

Исправление ошибки: явное добавление строки в табличную часть

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

Заменим ошибочный цикл на явное добавление строки:


// Добавляем новую строку в табличную часть
СтрокаРасшифровки = ДокОПК.РасшифровкаПлатежа.Добавить();
СтрокаРасшифровки.СпособПогашенияЗадолженности = Перечисления.СпособыПогашенияЗадолженности.Автоматически;
СтрокаРасшифровки.СуммаПлатежа = ДокОПК.СуммаДокумента;
СтрокаРасшифровки.КурсВзаиморасчетов = 1;
СтрокаРасшифровки.СуммаВзаиморасчетов = СтрокаРасшифровки.СуммаПлатежа;
СтрокаРасшифровки.КратностьВзаиморасчетов = 1;

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

Важные нюансы и скрытые ошибки при заполнении документа

Рассмотрим подробнее другие моменты представленного кода, которые могут привести к критическим ошибкам при проведении документа или искажению данных бухгалтерского учета:

  1. Несоответствие типов данных в реквизитах шапки. В строке ДокОПК.Контрагент = Склад; переменная имеет имя Склад. Если в эту переменную помещена ссылка на справочник Склады, то в реквизит Контрагент запишется пустая ссылка или произойдет ошибка несовпадения типов, так как данный реквизит ожидает тип СправочникСсылка.Контрагенты. Необходимо следить за передачей корректных ссылок.
  2. Обязательные аналитики взаиморасчетов. Для того чтобы документ «Оплата платежной картой» мог быть успешно проведен, одного указания суммы и способа погашения недостаточно. В строке РасшифровкаПлатежа обязательно должны быть заполнены аналитики:
    • ДоговорКонтрагента — ключевой разрез учета расчетов с контрагентом. Без договора механизмы проведения конфигурации вернут ошибку валюты расчетов или признака расчетов в условных единицах.
    • СчетУчетаРасчетовСКонтрагентом и СчетУчетаРасчетовПоАвансам — счета расчетов (обычно 62.01 и 62.02). При программном заполнении их следует получать и прописывать явно, например, из регистра сведений счетов расчетов по умолчанию.
    • СтатьяДДС — статья движения денежных средств, необходимая для формирования регламентированных проводок.
  3. Курсы и валютные расчеты. Установка параметров КурсВзаиморасчетов = 1 и КратностьВзаиморасчетов = 1 допустима только в том случае, если взаиморасчеты ведутся строго в валюте регламентированного учета (рублях). Если договор оформлен в валюте или у.е., курс и кратность необходимо получать из регистра сведений «Курсы валют» на дату документа и корректно рассчитывать СуммаВзаиморасчетов.
  4. Инициализация документа по умолчанию. Рекомендуется сразу после создания объекта вызвать метод ДокОПК.Заполнить(Неопределено). Это позволит автоматически заполнить системные реквизиты (организацию по умолчанию, ответственного, подразделение) согласно настройкам текущей информационной базы, сократив количество ручного кода.

Итоговый корректный пример кода

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


ДокОПК = Документы.ОплатаПлатежнойКартой.СоздатьДокумент();

// Первичная инициализация типовых реквизитов значениями по умолчанию
ДокОПК.Заполнить(Неопределено);

// Заполнение шапки документа
ДокОПК.ВидОперации = Объект.ВидОперации;
ДокОПК.Организация = Справочники.Организации.НайтиПоКоду("00-000002");
ДокОПК.Дата = ДатаОПК;
ДокОПК.Контрагент = КонтрагентСсылка; // Передаем ссылку на справочник Контрагенты
ДокОПК.ВидОплаты = Объект.ВидОплаты;
ДокОПК.СуммаДокумента = СуммаОПК; 
ДокОПК.СтавкаНДС = Перечисления.СтавкиНДС.БезНДС;
ДокОПК.Комментарий = "Создано программно";

// Формирование строки табличной части
СтрокаРасшифровки = ДокОПК.РасшифровкаПлатежа.Добавить();
СтрокаРасшифровки.ДоговорКонтрагента = ДоговорСсылка;
СтрокаРасшифровки.СпособПогашенияЗадолженности = Перечисления.СпособыПогашенияЗадолженности.Автоматически;
СтрокаРасшифровки.СуммаПлатежа = ДокОПК.СуммаДокумента;
СтрокаРасшифровки.КурсВзаиморасчетов = 1;
СтрокаРасшифровки.КратностьВзаиморасчетов = 1;
СтрокаРасшифровки.СуммаВзаиморасчетов = ДокОПК.СуммаДокумента;

// Заполнение счетов учета расчетов
СтрокаРасшифровки.СчетУчетаРасчетовСКонтрагентом = ПланыСчетов.Хозрасчетный.РасчетыСПокупателями; // 62.01
СтрокаРасшифровки.СчетУчетаРасчетовПоАвансам = ПланыСчетов.Хозрасчетный.РасчетыПоАвансамПолученным; // 62.02

// Безопасная запись объекта
Попытка 
    ДокОПК.Записать(РежимЗаписиДокумента.Запись);
Исключение
    ВызватьИсключение "Ошибка при сохранении документа: " + ОписаниеОшибки();
КонецПопытки;

Использование метода Добавить() вместо попытки перебора пустой таблицы исключает ошибку расхождения сумм и гарантирует корректную запись нового документа.

← На главную