Как открыть форму отчета в 1С с заполнением реквизитов и установкой отборов?

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

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

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

Почему возникает «Ошибка отображения типов»?

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

Когда вы пытаетесь выполнить функцию вида:


&НаСервереБезКонтекста
Функция ПолучитьЗаполненныйОтчет()
    ОтчетОбъект = Отчеты.ВедомостьПоОстаткам.Создать();
    ОтчетОбъект.Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7701010101");
    Возврат ОтчетОбъект; // Здесь произойдет ошибка при передаче на клиент!
КонецФункции

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

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

---

Решение 1. Использование временного объекта и метода КопироватьДанныеФормы()

Если вам обязательно нужно открыть форму существующего отчета, передать его в серверную процедуру для заполнения реквизитов, а затем отобразить изменения пользователю, воспользуйтесь следующим алгоритмом. Мы получим форму на клиенте, обратимся к ее свойству Отчет (которое имеет тип ДанныеФормыСтруктура, доступный и на клиенте, и на сервере), передадим его на сервер, а затем скопируем изменения обратно.

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

Рассмотрим рабочий пример реализации на клиенте и сервере:


&НаКлиенте
Процедура ЗаполнитьИОткрытьФормуОтчета()

    // Шаг 1. Получаем форму нужного отчета без ее немедленного открытия
    ФормаОтчета = ПолучитьФорму("Отчет.ВедомостьПоОстаткам.ФормаОбъекта");
    
    // Шаг 2. Копируем данные формы во временную переменную для обхода ограничений
    ОтчетДляЗаполнения = ФормаОтчета.Отчет;
    
    // Шаг 3. Передаем данные на сервер для заполнения
    ЗаполнитьРеквизитыОтчетаНаСервере(ОтчетДляЗаполнения);
    
    // Шаг 4. Копируем заполненные данные обратно в структуру формы
    КопироватьДанныеФормы(ОтчетДляЗаполнения, ФормаОтчета.Отчет);
    
    // Шаг 5. Открываем подготовленную форму пользователю
    ФормаОтчета.Открыть();

КонецПроцедуры

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

Этот способ полностью рабочий, однако он требует выполнения серверного вызова и написания объемного кода. Давайте посмотрим, как решить эту задачу изящнее.

---

Решение 2. Штатный запуск отчета с передачей параметров (Рекомендуемый способ)

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

У расширения формы отчета есть стандартные параметры, такие как Отбор и СформироватьПриОткрытии. Давайте проанализируем пример открытия отчета без единого серверного вызова:


&НаКлиенте
Процедура ОткрытьОтчетШтатно()

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

КонецПроцедуры

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

---

Решение 3. Почему отборы компоновщика не видны на форме и как это исправить?

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

В Системе Компоновки Данных (СКД) настройки разделены на два уровня:

  1. Основная настройка компоновки (хранится в КомпоновщикНастроек.Настройки).
  2. Пользовательские настройки (хранятся в КомпоновщикНастроек.ПользовательскиеНастройки).

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

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


&НаСервереБезКонтекста
Процедура УстановитьОтборВПользовательскихНастройках(ФормаОтчета, ИмяПоля, ЗначениеОтбора)
    
    Компоновщик = ФормаОтчета.Отчет.КомпоновщикНастроек;
    ПолеСКД = Новый ПолеКомпоновкиДанных(ИмяПоля);
    
    // Шаг 1. Ищем элемент отбора в основных настройках компоновщика
    ЭлементОтбора = Неопределено;
    Для Каждого Элемент Из Компоновщик.Настройки.Отбор.Элементы Цикл
        Если Элемент.ЛевоеЗначение = ПолеСКД Тогда
            ЭлементОтбора = Элемент;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    // Шаг 2. Если элемент найден и он доступен пользователю, меняем его в пользовательских настройках
    Если ЭлементОтбора <> Неопределено И ЗначениеЗаполнено(ЭлементОтбора.ИдентификаторПользовательскойНастройки) Тогда
        
        ПользовательскийЭлемент = Компоновщик.ПользовательскиеНастройки.Элементы.Найти(ЭлементОтбора.ИдентификаторПользовательскойНастройки);
        Если ПользовательскийЭлемент <> Неопределено Тогда
            ПользовательскийЭлемент.ПравоеЗначение = ЗначениеОтбора;
            ПользовательскийЭлемент.Использование = Истина;
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

---

Решение 4. Использование фиксированных (жестких) настроек

Если по условиям бизнес-логики требуется открыть отчет с фильтром, который пользователь не должен иметь возможности отключить или отредактировать, стандартный параметр "Отбор" не подойдет, так как пользователь сможет зайти в настройки и снять галочку.

Для решения этой задачи используется параметр формы "ФиксированныеНастройки". Эти настройки накладываются «поверх» всех пользовательских изменений и гарантируют строгость выборки данных:


&НаКлиенте
Процедура ОткрытьОтчетСФиксированнымОтбором()

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

КонецПроцедуры

---

Решение 5. Открытие конкретного варианта отчета

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


&НаКлиенте
Процедура ОткрытьКонкретныйВариантОтчета()

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

КонецПроцедуры

---

Решение 6. Программное открытие отчетов в конфигурациях на базе БСП

Если вы ведете разработку в типовой конфигурации (например, ERP, Управление торговлей, Комплексная автоматизация, ЗУП или Бухгалтерия предприятия), в вашем распоряжении находится готовый инструментарий Библиотеки Стандартных Подсистем. Разработчики БСП создали удобные общие модули для работы с отчетами.

Для программного открытия отчета с автоматическим заполнением параметров рекомендуется вызывать клиентский метод модуля ВариантыОтчетовКлиент:


&НаКлиенте
Процедура ОткрытьОтчетЧерезБСП()

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

КонецПроцедуры

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

Резюме

Мы детально рассмотрели проблему клиент-серверного взаимодействия при открытии форм отчетов. Подведем итог:

← На главную