Как написать внешнюю обработку для вывода договора контрагента и источника его получения из документа «Поступление на расчетный счет»

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

Разработка внешних обработок — это одна из наиболее частых задач для начинающего программиста 1С. В данной статье мы подробно разберем, как создать инструмент, который анализирует документ ПоступлениеНаРасчетныйСчет, извлекает из него договор контрагента и определяет, из какой именно части документа (шапки, табличной части или связанного счета) этот договор был взят. Мы пройдем путь от создания формы до написания серверного кода, учитывая типичные ошибки новичков.

Постановка задачи и проектирование формы

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

  1. Реквизит «ДокументСсылка» — поле для выбора конкретного документа ПоступлениеНаРасчетныйСчет.
  2. Табличная часть — назовем ее РезультатыПоиска, в которой будут две колонки: Договор (тип СправочникСсылка.ДоговорыКонтрагентов) и Источник (тип Строка).
  3. Команда «Сгенерировать» — кнопка, запускающая алгоритм поиска и заполнения таблицы.

Рассмотрим важный нюанс: при создании реквизита на форме для выбора документа, убедитесь, что его тип установлен как ДокументСсылка.ПоступлениеНаРасчетныйСчет. Это позволит платформе сразу понимать, с каким типом данных мы работаем.

Особенности структуры документа «Поступление на расчетный счет»

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

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

Реализация логики на сервере

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

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

Рассмотрим пример кода, реализующий базовую проверку:


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

Почему профессионалы рекомендуют использовать Запросы?

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

Посмотрим на пример того, как получить те же данные более эффективно через объект Запрос. Это позволит нам извлечь только нужные поля, не нагружая память сервера лишними данными:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Поступление.ДоговорКонтрагента КАК ДоговорШапка,
    |	Поступление.СчетНаОплату КАК Счет,
    |	Поступление.РасшифровкаПлатежа.(
    |		ДоговорКонтрагента КАК ДоговорТЧ
    |	) КАК Расшифровка
    |ИЗ
    |	Документ.ПоступлениеНаРасчетныйСчет КАК Поступление
    |ГДЕ
    |	Поступление.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Объект.ВыбранныйДокумент);
РезультатЗапроса = Запрос.Выполнить();

Проанализируем этот подход: запрос выполняется на уровне СУБД и возвращает структурированный результат. Даже если вы только начинаете изучать 1С, привычка использовать запросы вместо прямого обращения к объектам в циклах сделает вас востребованным специалистом значительно быстрее.

Типичные ошибки и способы их решения

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

Заключение

Мы разобрали основы создания внешней обработки для анализа структуры документа. Главный вывод: для успешного решения задачи в 1С важно не только знать синтаксис языка, но и понимать внутреннее устройство метаданных конфигурации. Сочетание правильного контекста выполнения (Клиент/Сервер) и грамотного обращения к реквизитам формы позволяет создавать надежные и быстрые инструменты автоматизации.

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

← На главную