Как заполнить таблицу на форме из документа, добавить данные вручную и вывести на печать?

Программист 1С v8.3 (Управляемые формы)
← На главную

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

Проанализируем частые ошибки при загрузке данных в таблицу

Разберем типичный фрагмент кода, в котором разработчики пытаются перенести данные из табличной части документа в таблицу на форме с помощью цикла:


Для Каждого СтрокаТовары Из Документ.Товары Цикл          
    ТабТовары.Очистить();
    // ... присвоение значений ...
КонецЦикла;

В этом коде кроется грубая логическая ошибка. Метод Очистить() вызывается на каждой итерации цикла. Из-за этого при проходе по каждой новой строке документа таблица значений на форме будет полностью очищаться. В итоге после завершения цикла в вашей таблице останется только одна — самая последняя строка. Очистку таблицы необходимо всегда выносить за пределы цикла, до его начала.

Оптимизируем перенос данных из табличной части

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

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

ТабТовары.Загрузить(ДокументОбъект.Товары.Выгрузить());

Для управляемых форм, чтобы перенести данные табличной части на форму, мы можем использовать встроенные методы конвертации, такие как РеквизитФормыВЗначение и ЗначениеВРеквизитФормы, либо передать массив структур. Это сильно сокращает объем кода, снижает вероятность опечаток при сопоставлении полей и значительно ускоряет работу программы.

Улучшаем пользовательский интерфейс: получение выбранной строки

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

Гораздо правильнее использовать выделенную строку непосредственно в самом табличном поле. Оператор просто кликает на нужную строку, вводит недостающие значения (вес нетто, брутто) прямо в таблицу и нажимает кнопку печати. Выясним, как получить данные строки, на которой сейчас стоит курсор:

Таким образом, получив переменную ТекущаяСтрока, мы имеем доступ ко всем введенным пользователем данным именно для этой строки, и никакие дополнительные кнопки выбора нам не нужны.

Автоматизируем заполнение параметров макета

Когда данные текущей строки получены, нам нужно передать их в параметры макета для вывода на печать. Вместо того чтобы вручную прописывать каждую переменную (например, ОбластьМакета.Параметры.ВесБрутто = ТекущаяСтрока.ВесБрутто;), можно автоматизировать этот процесс.

Если имена колонок в вашей таблице на форме полностью совпадают с именами параметров в макете печатной формы, мы можем использовать удобный метод Заполнить():


// Получаем область макета
ОбластьМакета = Макет.ПолучитьОбласть("Макет");

// Заполняем параметры структуры текущей строкой
ОбластьМакета.Параметры.Заполнить(ТекущаяСтрока);

// Заполняем параметры шапки (документа)
ОбластьМакета.Параметры.Заполнить(ДанныеШапки);

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

Решаем проблему сохранения ручных правок и закрытого периода

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

Разберем возможные варианты решения:

  1. Добавление колонок в табличную часть документа. Мы можем добавить реквизиты "Вес нетто", "Вес тары" прямо в ТЧ документа. Пользователь будет заполнять их там. Но здесь возникает серьезный минус: если документ проведен и период закрыт (установлена дата запрета редактирования), пользователь не сможет сохранить эти изменения. Документ будет недоступен для перезаписи.
  2. Использование независимого Регистра Сведений. Это наиболее оптимальный и правильный подход. Мы создаем отдельный непериодический регистр сведений.
    • В качестве измерений регистра указываем Документ (ссылка на наш документ) и КлючСтроки (или НомерСтроки).
    • В качестве ресурсов указываем наши дополнительные поля: ВесБрутто, ВесНетто, ВесТары.

Как это работает на практике: при открытии формы печати система проверяет, есть ли записи в этом регистре для данного документа. Если записи есть — таблица на форме заполняется из регистра. Если нет — подтягиваются дефолтные расчетные данные из документа. При нажатии кнопок "Печать" или "Сохранить", введенные оператором данные записываются в этот регистр. Поскольку регистр независимый, проблема с закрытым периодом отпадает — записи в регистр можно добавлять даже для документов из закрытого периода (если, конечно, не настроить иное ограничение прав).

Использование Внешних печатных форм (ВПФ)

Чтобы не вносить изменения в типовые документы конфигурации (не снимать их с поддержки) и не добавлять новые формы непосредственно в дерево метаданных, эту задачу лучше всего реализовывать через механизм Внешних печатных форм (ВПФ) с собственной экранной формой.

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

← На главную