В современных конфигурациях 1С, таких как ERP 2.5, Управление торговлей 11 или Комплексная автоматизация 2, работа с финансовыми документами имеет свои особенности. Часто начинающие разработчики сталкиваются с ситуацией, когда программно измененный документ прекрасно проводится из формы, но выдает ошибки при попытке провести его из списка или кодом. Разберем детально, почему так происходит и как правильно автоматизировать работу с документом ПоступлениеБезналичныхДенежныхСредств.
Рассмотрим типичную ситуацию: при программном изменении документа программист обновляет реквизиты в шапке, например, ХозяйственнаяОперация и СтатьяДвиженияДенежныхСредств. Однако при попытке проведения система выдает ошибку: «Поле "Статья ДДС" в строке 1 списка "Расшифровка платежа" не заполнено».
Проанализируем причину. В современных конфигурациях данные о платеже хранятся не в шапке, а в табличной части РасшифровкаПлатежа. Реквизиты шапки часто являются вспомогательными или отображают данные из первой строки таблицы. Когда вы открываете форму, программные механизмы формы могут «подтягивать» значения из шапки в таблицу (или наоборот), поэтому ручное проведение работает. Но при работе напрямую с объектом (через контекстное меню или программную запись) логика формы не вызывается, и документ остается некорректно заполненным.
Для того чтобы документ прошел все проверки, мы должны обязательно транслировать изменения в табличную часть РасшифровкаПлатежа. Рассмотрим пример кода, который правильно обходит строки расшифровки:
// Получаем объект документа
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
// Устанавливаем операцию в шапке
ДокОбъект.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ПоступлениеОплатыПоПлатежнойКарте;
// Переходим к заполнению табличной части
Для Каждого СтрокаТЧ Из ДокОбъект.РасшифровкаПлатежа Цикл
// Заполняем статью ДДС в каждой строке распределения
СтрокаТЧ.СтатьяДвиженияДенежныхСредств = Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("Эквайринг");
КонецЦикла;
// Если табличная часть пуста (например, новый документ), её нужно создать
Если ДокОбъект.РасшифровкаПлатежа.Количество() = 0 Тогда
НоваяСтрока = ДокОбъект.РасшифровкаПлатежа.Добавить();
НоваяСтрока.СтатьяДвиженияДенежныхСредств = Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("Эквайринг");
НоваяСтрока.Сумма = ДокОбъект.СуммаДокумента;
КонецЕсли;
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
Часто ошибки возникают еще на этапе получения объекта. Выясним причину, почему метод НайтиПоНомеру() может возвращать пустую ссылку. В системе 1С номера документов периодические. Чтобы поиск сработал, необходимо передать дату, входящую в нужный период (обычно год).
Посмотрим на правильный пример поиска документа по номеру:
// Обязательно указываем дату для поиска в периоде
ДатаПоиска = '20231231235959';
НужныйДокумент = Документы.ПоступлениеБезналичныхДенежныхСредств.НайтиПоНомеру("ССОФ-000581", ДатаПоиска);
Если Не НужныйДокумент.Пустая() Тогда
ОбъектДок = НужныйДокумент.ПолучитьОбъект();
// Далее производим манипуляции с объектом
Иначе
Сообщить("Документ с таким номером не найден в указанном периоде!");
КонецЕсли;
Программирование условий по тексту «Назначения платежа» через Найти(Объект.НазначениеПлатежа, "Мерчант...") — это «жесткое кодирование» (hardcode), которое крайне нежелательно. Если банк изменит текст в назначении, ваш код перестанет работать, и придется снова вызывать программиста.
Разберем, как сделать это правильно в 1С:ERP и УТ 11:
ЭквайринговыеТерминалы. В нем указывается «Номер мерчанта». При загрузке выписки через Директ-Банк система сама найдет нужный терминал по идентификатору и заполнит статью ДДС, договор и банк-эквайер.Проанализируем еще несколько важных моментов, которые помогут избежать ошибок при записи документа:
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение, РежимПроверкиЗаполнения.ВыдаватьОшибку). Это позволит вам увидеть в сообщениях пользователю, каких именно данных не хватает для проведения.РасшифровкаПлатежа совпадает с общей суммой документа. В противном случае документ не проведется по управленческому учету.ПередЗаписью) или использовать Расширение. Это гарантирует, что ваша логика сработает независимо от того, как записывается документ — через форму, обработкой или при загрузке из банка.Выясним, как может выглядеть универсальная процедура заполнения в модуле объекта (через расширение):
&После("ПередЗаписью")
Процедура ИТ_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, что это не удаление и документ соответствует условиям эквайринга
Если Найти(ЭтотОбъект.НазначениеПлатежа, "Мерчант №331000008318") > 0 Тогда
ЭтотОбъект.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ПоступлениеОплатыПоПлатежнойКарте;
// Обновляем ТЧ
Для Каждого Стр Из ЭтотОбъект.РасшифровкаПлатежа Цикл
Стр.СтатьяДвиженияДенежныхСредств = Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию("НужнаяСтатья");
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Подведем итог: Основная ошибка заключалась в игнорировании структуры документа, где шапка является лишь отражением табличной части. Всегда работайте с РасшифровкаПлатежа в финансовых документах 1С 8.3, и ваши документы будут проводиться корректно в любых режимах.