Как из модуля менеджера обратиться к текущей строке таблицы значений на форме

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

При разработке печатных форм в системе 1С:Предприятие 8.3, особенно при использовании Библиотеки стандартных подсистем (БСП), программисты часто сталкиваются с архитектурным ограничением: модуль менеджера ничего не знает о контексте формы. Если на форме документа расположена таблица значений, которая не является реквизитом самого объекта (документа), а существует только в рамках интерфейса, напрямую «увидеть» её данные из процедуры Печать в модуле менеджера невозможно.

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

Почему возникает проблема?

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

Если ваша задача — напечатать только выделенные строки из таблицы значений (ТЗ), которая является реквизитом формы, нам придется «пробросить» эти данные через стандартные механизмы БСП.

Решение 1: Передача данных через параметры печати (рекомендуемый способ)

Рассмотрим основной механизм БСП. При вызове команды печати формируется структура ПараметрыПечати. Мы можем вмешаться в этот процесс на уровне формы и добавить в эту структуру свои данные.

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

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

Пример кода в модуле формы:


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

Теперь рассмотрим, как принять эти данные в Модуле менеджера. Стандартная процедура БСП имеет параметр ПараметрыПечати. Проанализируем, как извлечь из него нашу таблицу:


Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

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

Решение 2: Использование Временного хранилища (для больших объемов данных)

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

Алгоритм действий будет следующим:

  1. На сервере (в модуле формы) помещаем нужную часть таблицы значений во временное хранилище.
  2. Передаем Адрес этого хранилища в модуль менеджера через ПараметрыПечати.
  3. В модуле менеджера получаем таблицу по адресу.

Посмотрим на пример реализации на сервере в модуле формы:


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

Затем в модуле менеджера в процедуре Печать мы выполняем обратное действие:


Если ПараметрыПечати.Свойство("АдресДанныхТЗ") Тогда
    ТаблицаДанных = ПолучитьИзВременногоХранилища(ПараметрыПечати.АдресДанныхТЗ);
    // Теперь у нас есть полноценная ТЗ со всеми данными из формы
КонецЕсли;

Важный нюанс: Печать из списка документов

Нужно учитывать ситуацию, когда пользователь пытается распечатать документ не открывая его — прямо из списка. В этом случае формы не существует, и никакие параметры из неё переданы не будут. Обязательно предусмотрите проверку:

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

Резюме

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

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

← На главную