Как передать параметр в форму отчета 1С 8.3 (на БСП)?

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

При разработке отчетов в конфигурациях на платформе 1С 8.3, особенно тех, которые используют Библиотеку стандартных подсистем (БСП), часто возникает необходимость передавать параметры в форму отчета при ее открытии. Например, мы хотим открыть отчет по конкретному документу прямо из этого документа, чтобы пользователи могли быстро получить нужную информацию, не заполняя поля вручную. Однако этот процесс может столкнуться с неожиданными трудностями, если не учитывать особенности платформы и БСП.

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

Исходная проблема: почему параметр не заполняется в форме отчета

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


// Пример изначального, не работающего кода в обработчике общей команды
Параметры = Новый Структура("Документ", ПараметрКоманды);
ОткрытьФорму("Отчет.ДвиженияДокумента.Форма.ФормаОтчета", Параметры);

В этом примере ПараметрКоманды, как мы видим в отладчике, действительно содержит ссылку на нужный нам документ. Мы ожидаем, что в форме отчета "ДвиженияДокумента" реквизит с именем "Документ" будет автоматически заполнен переданным значением. Однако, при дальнейшей отладке, в процедуре ПриСозданииНаСервере() формы отчета, которая отвечает за инициализацию формы и ее реквизитов, мы обнаруживаем, что переменная Параметры оказывается либо пустой, либо не содержит ожидаемого ключа "Документ".

Давайте посмотрим на пример кода из процедуры ПриСозданииНаСервере(), который пытается получить переданный параметр и присвоить его реквизиту отчета:


// Код в ПриСозданииНаСервере() формы отчета до исправления
&НаСервере
Процедура ПриСозданииНаСервере() // Обратите внимание, здесь нет стандартных параметров Отказ, СтандартнаяОбработка
    // Здесь Отчет.Документ должен был быть заполнен переданным параметром,
    // но при отладке выясняется, что Параметры.Документ не содержит значения.
    Отчет.Документ = Параметры.Документ;    
    Элементы.Документ.ТолькоПросмотр = ЗначениеЗаполнено(Отчет.Документ);    
    Если НЕ ЗначениеЗаполнено(СпособВыводаОтчета) Тогда
        СпособВыводаОтчета = Перечисления.СпособыВыводаОтчета.ПоВертикали;
    КонецЕсли;
КонецПроцедуры

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

Выясняем причину: особенности передачи параметров в БСП

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

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

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

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

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

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

    
    // Создаем структуру с фактическими параметрами отчета
    ДанныеДляОтчета = Новый Структура("Документ", ПараметрКоманды);
    // Здесь ПараметрКоманды - это ссылка на объект, который мы хотим передать.
    // Например, если команда вызывается из формы документа, то это может быть 'Объект.Ссылка'.
    

    Обратите внимание, что ключ "Документ" в этой структуре должен совпадать с именем реквизита объекта отчета, который мы хотим заполнить.

  2. Оборачиваем внутреннюю структуру во внешнюю с ключом "Параметры". Теперь создадим еще одну структуру. Она будет корневой структурой, которую мы фактически передадим в метод ОткрытьФорму(). В эту корневую структуру мы вставим нашу первую структуру (ДанныеДляОтчета) по специальному ключу "Параметры":

    
    // Создаем корневую структуру, которая будет передана в ОткрытьФорму()
    ПараметрыФормы = Новый Структура;
    // Вставляем нашу структуру с данными по ключу "Параметры"
    ПараметрыФормы.Вставить("Параметры", ДанныеДляОтчета);
    

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

    
    // Более компактный вариант создания вложенной структуры
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Параметры", Новый Структура("Документ", ПараметрКоманды));
    
  3. Открываем форму отчета, передавая корректно сформированную структуру. После того как мы правильно сформировали структуру ПараметрыФормы, мы можем использовать ее при вызове метода ОткрытьФорму():

    ОткрытьФорму("Отчет.ДвиженияДокумента.Форма.ФормаОтчета", ПараметрыФормы);

Соберем весь код обработчика команды воедино, чтобы наглядно представить окончательное рабочее решение:


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

// 1. Формируем структуру с реальными параметрами отчета
ПараметрыОтчета = Новый Структура("Документ", ПараметрКоманды);

// 2. Оборачиваем эту структуру во внешнюю с ключом "Параметры" для совместимости с БСП
ВходящиеПараметрыДляФормы = Новый Структура;
ВходящиеПараметрыДляФормы.Вставить("Параметры", ПараметрыОтчета);

// 3. Открываем форму отчета, передавая корректно сформированные параметры
ОткрытьФорму("Отчет.ДвиженияДокумента.Форма.ФормаОтчета", ВходящиеПараметрыДляФормы);

После выполнения этих шагов, наша структура с параметрами будет корректно передана в форму отчета.

Корректируем обработчик ПриСозданииНаСервере() в форме отчета

После того как мы правильно сформировали и передали параметры из обработчика команды, нам также необходимо внести небольшую, но важную корректировку в процедуру ПриСозданииНаСервере() формы отчета. Теперь наши фактические параметры будут доступны не напрямую через Параметры.Документ, а через Параметры.Параметры.Документ, учитывая нашу "обертку".

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


// Обновленный код в ПриСозданииНаСервере() формы отчета
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) 
    // Переменная 'Параметры' здесь содержит структуру, переданную в ОткрытьФорму().
    // То есть, она равна нашей 'ВходящиеПараметрыДляФормы'.

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

Мы видим, что теперь для доступа к параметру "Документ" мы используем выражение Параметры.Параметры.Документ. Очень важно добавить проверки на существование ключей с помощью ТипЗнч() и Свойство(). Это позволяет избежать ошибок времени выполнения, если форма отчета открывается без параметров (например, из меню "Все отчеты") или с параметрами другого формата, где ключ "Параметры" или "Документ" может отсутствовать.

Присвоение значения Отчет.Документ означает, что мы заполняем реквизит самого объекта отчета, который является источником данных для формы. Далее этот реквизит будет связан с элементом формы "Документ", обеспечивая его отображение и использование в СКД отчета.

Дополнительные аспекты и полезные советы

Разберем дополнительные нюансы, которые помогут вам глубже понять механизм передачи параметров и эффективно работать с отчетами в 1С 8.3, особенно при использовании БСП.

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

Платформа 1С действительно обладает механизмом автоматического сопоставления. Если вы передаете в ОткрытьФорму() структуру, чьи ключи совпадают с именами реквизитов самой формы или реквизитов основного объекта формы (например, реквизитами объекта отчета, если форма является его основной формой), то 1С попытается автоматически заполнить эти реквизиты. Однако этот "автоматический" механизм часто дополняется или переопределяется логикой, реализованной в БСП.

В нашем случае, требование БСП к "обертке" с ключом "Параметры" фактически меняет ожидаемый формат. Если бы не это требование, и реквизит "Документ" был бы напрямую доступен в корневой структуре, автоматическое сопоставление могло бы сработать. Тем не менее, даже в таком случае, для сложной логики инициализации или для работы с реквизитами объекта отчета, процедура ПриСозданииНаСервере() все равно является предпочтительным местом для явного присвоения значений.

Важно понимать, что в нашем примере реквизит "Документ" является реквизитом объекта отчета (доступен как Отчет.Документ), а не реквизитом непосредственно формы. Именно поэтому мы обращаемся к нему через Отчет.Документ в процедуре ПриСозданииНаСервере(), а не просто Документ или ЭтотОбъект.Документ (если бы это был реквизит формы).

Диагностика и отладка проблем с параметрами

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

  1. В месте вызова ОткрытьФорму(): Установите точку останова непосредственно перед строкой ОткрытьФорму(...) (в обработчике команды или модуля формы документа). В этот момент внимательно проинспектируйте содержимое переменной ВходящиеПараметрыДляФормы (или как вы назвали свою структуру). Убедитесь, что она имеет правильную структуру: внешний ключ "Параметры", а внутри него — ваша структура с ключом "Документ" и корректным значением (ссылкой на документ).

  2. В начале процедуры ПриСозданииНаСервере() формы отчета: Установите точку останова в самой первой строке процедуры ПриСозданииНаСервере() в модуле формы отчета. Здесь проинспектируйте содержимое переменной Параметры. Именно эта переменная содержит ту структуру, которую вы передали в ОткрытьФорму(). Вы сможете увидеть, какие ключи и значения фактически были переданы и доступны. Если вы видите, что Параметры.Свойство("Параметры") возвращает Истина, а затем Параметры.Параметры.Свойство("Документ") также Истина, значит, параметры переданы корректно, и проблема может быть в логике присвоения.

Этот пошаговый анализ позволит вам точно определить, на каком этапе происходит потеря, некорректное формирование или неправильная интерпретация данных.

Отличие реквизитов отчета от параметров Системы Компоновки Данных (СКД)

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

Если бы "Документ" был параметром СКД, то для его заполнения потребовался бы иной подход:

  1. Открытие формы отчета (возможно, с передачей других параметров, например, для инициализации формы).

  2. После инициализации формы, в той же процедуре ПриСозданииНаСервере(), необходимо было бы получить доступ к компоновщику настроек СКД в форме отчета. Обычно он доступен через свойство Отчет.КомпоновщикНастроек.

  3. Установка значения параметра СКД с помощью метода УстановитьЗначениеПараметра() объекта НастройкиКомпоновщикаНастроек.ПараметрыДанных или прямо через Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.


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

Однако, в нашей текущей ситуации, как было изначально указано, "Документ" — это реквизит объекта отчета, а не параметр СКД. Поэтому мы работаем непосредственно с Отчет.Документ, а не с объектами СКД.

Использование стандартных параметров команды

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

Мы правильно извлекаем это значение (ссылку на документ) и используем его для формирования внутренней структуры с параметрами отчета. Этот подход является типовым и эффективным способом передачи контекста между различными объектами конфигурации.

Заключение

Мы подробно рассмотрели, как эффективно передавать параметры в формы отчетов в 1С 8.3, особенно в конфигурациях, разработанных на базе БСП. Ключевым моментом для успешной передачи является правильное формирование структуры параметров: использование "обертки" с ключом "Параметры" для ваших фактических данных.

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

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

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

← На главную