Как реализовать отображение причины списания в печатной форме Акта списания (Сводный) в зависимости от документа-основания

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Управленческий учет Промышленность, строительство и АПК
← На главную

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

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

Анализ исходной ситуации и постановка задачи

Проанализируем текущую реализацию функции СТ_ПечатьАктСписания. В данный момент запрос собирает данные из табличной части Товары документа ВнутреннееПотреблениеТоваров, а также подтягивает цены и ответственных лиц. Причина списания сейчас берется напрямую из реквизита СТ_ПричинаСписания или СТ_ПричинаСписанияДетали основного документа.

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

Шаг 1. Модификация текста запроса для получения оснований

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

Найдем в коде место, где выбираются основные реквизиты документа ВнутреннееПотреблениеТоваров, и добавим туда выборку основания. Рекомендуется использовать конструкцию ВЫРАЗИТЬ, чтобы система понимала, с каким типом данных мы работаем:


| ВнутреннееПотреблениеТоваров.Номер КАК НомерДокумента,
| ВнутреннееПотреблениеТоваров.Дата КАК ДатаДокумента,
| // Добавляем поле документа-основания
| ВнутреннееПотреблениеТоваров.ДокументОснование КАК ДокументОснование,
| // Пытаемся сразу получить Несоответствие, если основание верного типа
| ВЫРАЗИТЬ(ВнутреннееПотреблениеТоваров.ДокументОснование КАК Документ.РегистрацияНесоответствий).Несоответствие КАК ПричинаИзНесоответствия,
| ВнутреннееПотреблениеТоваров.СТ_ПричинаСписания КАК ПричинаСписания,
| ...

Использование ВЫРАЗИТЬ в запросе — это хороший тон в программировании 1С, так как это помогает оптимизировать выполнение запроса и избежать проблем с обращением через точку к полям составного типа данных.

Шаг 2. Добавление логики определения причины в цикле формирования

Теперь перейдем к обработке результатов запроса. Нам нужно изменить алгоритм заполнения параметров области макета. В исходном коде заполнение происходит массово через Область.Параметры.Заполнить(ВыборкаШапка). Нам нужно внедрить проверку перед выводом области в табличный документ.

Проанализируем цикл Пока ВыборкаШапка.Следующий(). Именно здесь решается, какая информация попадет в шапку или в строки (в зависимости от настроек сводности). Рассмотрим пример реализации логики:


Пока ВыборкаШапка.Следующий() Цикл
    // ... существующий код подготовки номера документа ...

    Если Не Сводно Или ПервыйДокумент Тогда
        // Получаем область шапки
        Если Сводно Тогда
            Область = Макет.ПолучитьОбласть("ШапкаСводная");
        Иначе
            Область = Макет.ПолучитьОбласть("Шапка");
        КонецЕсли;

        // Заполняем стандартные параметры
        Область.Параметры.Заполнить(ВыборкаШапка);
        
        // Внедряем нашу логику выбора причины списания
        ТекПричинаСписания = "";
        Если ЗначениеЗаполнено(ВыборкаШапка.ПричинаИзНесоответствия) Тогда
            // Если документ создан на основании Регистрации несоответствий
            ТекПричинаСписания = Строка(ВыборкаШапка.ПричинаИзНесоответствия);
        ИначеЕсли ЗначениеЗаполнено(ВыборкаШапка.СТ_ПричинаСписанияДетали) Тогда
            // Если есть детализированная причина
            ТекПричинаСписания = ВыборкаШапка.СТ_ПричинаСписанияДетали;
        Иначе
            // Стандартная причина из документа
            ТекПричинаСписания = Строка(ВыборкаШапка.ПричинаСписания);
        КонецЕсли;

        // Принудительно устанавливаем параметр в области макета
        Область.Параметры.ПричинаСписания = ТекПричинаСписания;

        // ... остальной код вывода области ...
    КонецЕсли;
КонецЦикла;

Шаг 3. Обработка сводных печатных форм

Выясним причину, по которой данные могут отображаться некорректно в сводном режиме. Если параметр Сводно = Истина, то шапка выводится только один раз (для первого документа), а затем идут строки всех документов. Если у разных документов разные основания (один по регистрации, другой — нет), возникает вопрос: какую причину выводить в общей шапке?

Рассмотрим два варианта решения этой ситуации:

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

Если мы выбираем вариант с выводом в строках, код внутри цикла Пока ВыборкаСтрокиПоСсылке.Следующий() будет выглядеть следующим образом:


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

Особенности работы с реквизитом «ДокументОснование»

Важно помнить, что в типовых конфигурациях 1С (ERP/КА) поле ДокументОснование является составным типом. Это означает, что при обращении к нему в коде 1С напрямую через ВыборкаШапка.ДокументОснование.Несоответствие, система выполнит дополнительный запрос к базе данных для каждого документа в выборке (проблема N+1). Чтобы этого избежать, мы использовали ВЫРАЗИТЬ в основном тексте запроса на Шаге 1.

Также проанализируем ситуацию, упомянутую в обсуждении: «Заказ на внутреннее потребление не всегда создан на основании регистрации несоответствия». В этом случае цепочка документов выглядит так: Регистрация несоответствий -> Заказ на внутреннее потребление -> Внутреннее потребление товаров.

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


| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказНаВнутреннееПотребление КАК Заказ
| ПО ВнутреннееПотреблениеТоваров.ДокументОснование = Заказ.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.РегистрацияНесоответствий КАК Регистрация
| ПО (ВнутреннееПотреблениеТоваров.ДокументОснование = Регистрация.Ссылка 
|     ИЛИ Заказ.ДокументОснование = Регистрация.Ссылка)

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

Заключение

Подведем итоги. Для реализации корректного отображения причины списания мы выполнили следующие действия:

Теперь ваша печатная форма будет автоматически подстраиваться под бизнес-процесс: если списание идет по браку (через регистрацию несоответствий), ответственные лица увидят конкретный дефект, в остальных случаях — стандартную аналитику расходов. Это значительно повышает прозрачность учета и удобство работы сотрудников склада и бухгалтерии.

← На главную