Почему в запросе к исходящему платежному поручению не виден документ-основание и как это исправить?

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

При разработке отчетов, выгрузок или кастомных механизмов интеграции в программах «1С:Предприятие 8» (особенно в конфигурациях на обычных формах, таких как «Управление производственным предприятием 1.3» или «Управление торговлей 10.3») программисты часто сталкиваются со странным поведением системы. Один и тот же документ — например, ПлатежноеПоручениеИсходящее — в одних случаях возвращает заполненный документ-основание (ЗаказПоставщику), а в других (когда документ создан вручную или загружен через обработку «Клиент-Банк») это поле в запросе оказывается абсолютно пустым, хотя визуально на форме заказ выбран.

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

В чем суть проблемы? Анализируем два сценария создания документа

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

Сценарий 1: Ввод на основании (автоматическое заполнение)

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

Сценарий 2: Ручное заполнение или загрузка через «Клиент-Банк»

Теперь рассмотрим другую ситуацию. Платежное поручение загружается из текстового файла выписки («Клиент-Банк») или создается пользователем вручную в журнале документов. В этом случае документ-основание (заказ или счет) выбирается непосредственно внутри документа. Пользователь видит заполненное поле на форме, проводит документ, но когда мы пытаемся обратиться к реквизиту ДокументОснование через запрос, он возвращает нам значение НЕОПРЕДЕЛЕНО или пустую ссылку. Нам кажется, что данные не записались, хотя в интерфейсе программы поле заполнено.

Давайте разберемся, почему возникает это различие в поведении платформы.

Архитектурная разница между реквизитом шапки и табличной частью

В типовых конфигурациях 1С, использующих сложную аналитику взаиморасчетов (УПП, УТ 10.3, КА 1.1), связь между платежным документом и сделкой (заказом, договором, счетом) реализована на двух совершенно разных уровнях метаданных:

  1. Реквизит шапки ДокументОснование. Это стандартный ссылочный реквизит типа ДокументСсылка (или составного типа). Он предназначен исключительно для поддержки системного механизма «Ввод на основании» и корректного построения отчета «Структура подчиненности». С точки зрения проведения документа и движения по регистрам накопления этот реквизит является чисто информационным и никак не влияет на учет.
  2. Табличная часть РасшифровкаПлатежа и реквизит Сделка. Это оперативный аналитический реквизит, расположенный внутри табличной части документа. Именно он отвечает за фактический зачет оплаты по конкретному заказу в регистрах накопления (таких как «Взаиморасчеты с контрагентами» или «Расчеты с контрагентами»). При проведении платежного поручения система анализирует именно эту табличную часть и делает движения по регистрам в разрезе указанных там сделок.

Когда вы импортируете выписку из банка или заполняете документ вручную, система стремится корректно отразить операцию в учете. Для этого она заполняет табличную часть РасшифровкаПлатежа, указывая в реквизите Сделка ваш ЗаказПоставщику. Реквизит шапки ДокументОснование при этом остается пустым, так как программно вызов метода «Заполнить на основании» не происходил.

Проблема «многострочных» платежей

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

В этом случае табличная часть РасшифровкаПлатежа будет содержать несколько строк:

Общая сумма платежного поручения составит 100 000 рублей. В такой ситуации физически невозможно записать в один реквизит шапки ДокументОснование ссылку на конкретный заказ, ведь их там три! Именно поэтому хранение аналитики в табличной части является единственно верным и методологически правильным решением.

Решение проблемы: Как правильно составить запрос

Чтобы ваш запрос гарантированно возвращал документ-основание (заказ или договор) независимо от того, как именно была создана платежка, вам необходимо обращаться к табличной части документа. Рассмотрим два основных способа написания такого запроса.

Вариант 1. Запрос по табличной части документа

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


ВЫБРАТЬ
    ПлатежкаРасшифровка.Ссылка КАК ПлатежноеПоручение,
    ПлатежкаРасшифровка.Ссылка.Дата КАК ДатаПлатежа,
    ПлатежкаРасшифровка.Сделка КАК ДокументОснование,
    ПлатежкаРасшифровка.СуммаПлатежа КАК Сумма
ИЗ
    Документ.ПлатежноеПоручениеИсходящее.РасшифровкаПлатежа КАК ПлатежкаРасшифровка
ГДЕ
    ПлатежкаРасшифровка.Ссылка = &СсылкаНаПлатежку

Этот запрос вернет все строки расшифровки платежа, и в поле ДокументОснование мы получим точные ссылки на заказы поставщикам, даже если платежка была загружена из «Клиент-Банка».

Вариант 2. Универсальный запрос с использованием ЕСТЬNULL

Если вы хотите подстраховаться на случай, когда по какой-то причине табличная часть документа оказалась не заполнена (например, платеж проведен в целом по договору без детализации по сделкам, но в шапке заполнен реквизит ДокументОснование), можно использовать конструкцию ЕСТЬNULL. Проанализируем следующий пример:


ВЫБРАТЬ
    ПлатежкаШапка.Ссылка КАК ПлатежноеПоручение,
    ПлатежкаШапка.Дата КАК ДатаПлатежа,
    ВЫБОР
        КОГДА ПлатежкаРасшифровка.Сделка ЕСТЬ НЕ NULL И ПлатежкаРасшифровка.Сделка <> ЗНАЧЕНИЕ(Документ.ЗаказПоставщику.ПустаяСсылка)
            ТОГДА ПлатежкаРасшифровка.Сделка
        ИНАЧЕ ПлатежкаШапка.ДокументОснование
    КОНЕЦ КАК ДокументОснование,
    ПлатежкаШапка.СуммаДокумента КАК Сумма
ИЗ
    Документ.ПлатежноеПоручениеИсходящее КАК ПлатежкаШапка
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПлатежноеПоручениеИсходящее.РасшифровкаПлатежа КАК ПлатежкаРасшифровка
        ПО ПлатежкаРасшифровка.Ссылка = ПлатежкаШапка.Ссылка
ГДЕ
    ПлатежкаШапка.Ссылка = &СсылкаНаПлатежку

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

Альтернативное решение: Программное заполнение реквизита (костыль)

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

Для этого в модуле формы документа ПлатежноеПоручениеИсходящее найдем обработчик изменения или выбора заказа (сделки) в табличной части и пропишем простой код заполнения реквизита шапки:


&НаКлиенте
Процедура РасшифровкаПлатежаСделкаПриИзменении(Элемент)
    СтрокаТЧ = Элементы.РасшифровкаПлатежа.ТекущиеДанные;
    Если СтрокаТЧ <> Неопределено Тогда
        // Проверяем, заполнена ли сделка в текущей строке ТЧ
        Если ЗначениеЗаполнено(СтрокаТЧ.Сделка) Тогда
            // Если реквизит шапки пуст, заполняем его первой выбранной сделкой
            Если Не ЗначениеЗаполнено(Объект.ДокументОснование) Тогда
                Объект.ДокументОснование = СтрокаТЧ.Sделка;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Важное предупреждение: Использование данного метода является обходным решением («костылем»). Применяйте его аккуратно, так как при многострочном заполнении расшифровки платежа в шапку запишется только один из заказов, что может ввести в заблуждение пользователей, анализирующих структуру подчиненности документов.

Как настроить «Структуру подчиненности» для ручных документов

Часто программисты пытаются принудительно заполнять реквизит шапки ДокументОснование только ради того, чтобы платежка отображалась в дереве связанных документов («Структуре подчиненности») для конкретного заказа поставщику.

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

  1. Откройте конфигуратор вашей информационной базы.
  2. Найдите ветку метаданных Критерии отбора (как правило, это критерий с именем СвязанныеДокументы или аналогичный).
  3. Перейдите на вкладку Состав.
  4. Найдите в списке документов ПлатежноеПоручениеИсходящее.
  5. Убедитесь, что галочки стоят напротив двух реквизитов:
    • ПлатежноеПоручениеИсходящее.ДокументОснование
    • ПлатежноеПоручениеИсходящее.РасшифровкаПлатежа.Сделка
  6. Сохраните и обновите конфигурацию базы данных.

После этой несложной настройки платформа начнет автоматически анализировать как шапку документа, так и его табличную часть при построении дерева подчиненности. Теперь, даже если платежка была загружена через «Клиент-Банк» и реквизит шапки пуст, она гарантированно отобразится в списке связанных документов для соответствующего заказа поставщику.

← На главную