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

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

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

1. Анализируем исходную проблему и почему клиентский код не работает

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


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    Парам = ЭтотОбъект.Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ДатаОтчета");
    Парам.Использование = Истина;
    Парам.Значение = ТекущаяДата;
КонецПроцедуры

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

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

2. Правильный подход к установке параметров: серверные обработчики

Для программной установки параметров отчета в управляемой форме нам следует использовать серверные обработчики событий. Эти процедуры выполняются на сервере, где доступен объект Отчет.КомпоновщикНастроек и его коллекции. Рассмотрим наиболее подходящие обработчики:

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

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

3. Установка параметра "ДатаОтчета" на конец месяца

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    УстановитьДатуОтчета();
КонецПроцедуры

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

&НаСервере
Процедура ПриЗагрузкеПользовательскихНастроекНаСервере(Настройки)
    УстановитьДатуОтчета(); // Повторяем установку при загрузке пользовательских настроек
КонецПроцедуры

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

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

4. Установка периода отчета

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    УстановитьПериодОтчета();
КонецПроцедуры

&НаСервере
Процедура УстановитьПериодОтчета()
    // Вычисляем начальную и конечную даты периода
    ДатаНачала = НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), -4));
    ДатаОкончания = КонецМесяца(ТекущаяДата());

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

&НаСервере
Процедура ПриЗагрузкеПользовательскихНастроекНаСервере(Настройки, ИспользуютсяСтандартныеНастройки)
    УстановитьПериодОтчета();
КонецПроцедуры

&НаСервере
Процедура ПриЗагрузкеВариантаНаСервере(Настройки)
    УстановитьПериодОтчета();
КонецПроцедуры

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

5. Обеспечение интерактивности и возможности изменения параметра пользователем

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

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

  1. Вывести параметр на форму отчета: Убедитесь, что элемент управления для вашего параметра (например, "ДатаОтчета") добавлен на форму отчета. Как правило, это делается автоматически при создании формы на основании схемы компоновки данных, если параметр включен в пользовательские настройки.
  2. Связать параметр с пользовательскими настройками в СКД: В схеме компоновки данных, на закладке "Параметры", для вашего параметра должно быть установлено свойство "Включать в пользовательские настройки". Это гарантирует, что параметр будет доступен для редактирования на форме отчета и будет частью коллекции ПользовательскиеНастройки.
  3. Модифицировать ПользовательскиеНастройки на сервере: Как мы уже выяснили, при программной установке значения параметра всегда обращайтесь к коллекции Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы, находя нужный элемент по его идентификатору.
  4. Установить Использование = Истина: Для параметра в ПользовательскихНастройках необходимо установить свойство Использование в Истина, чтобы он был активен и его значение учитывалось при формировании отчета.

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

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

6. Альтернативный метод: установка выражения по умолчанию в схеме СКД

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

  1. Откройте схему компоновки данных вашего отчета.
  2. Перейдите на закладку "Параметры".
  3. Найдите ваш параметр (например, "ДатаОтчета" или "Период").
  4. В колонке "Выражение" укажите необходимое значение по умолчанию.

Например, для установки даты в конец текущего дня, вы можете написать:

КонецПериода(ТекущаяДата(), "День")

Для установки периода, например, "Текущий день", вы можете использовать:

СтандартныйПериод.ТекущийДень

или для произвольного периода:

Новый СтандартныйПериод(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()))

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

Заключение

Мы видим, что для успешной установки параметров отчета в управляемых формах 1С необходимо четко понимать архитектуру управляемого приложения и принципы работы с Системой Компоновки Данных. Забудьте о прямом изменении серверных объектов на клиенте. Вместо этого:

  1. Используйте серверные обработчики событий формы отчета (ПриСозданииНаСервере, ПриЗагрузкеПользовательскихНастроекНаСервере, ПриЗагрузкеВариантаНаСервере).
  2. Всегда работайте с коллекцией Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы, чтобы ваши изменения отображались на форме и были интерактивными.
  3. Убедитесь, что для параметра в схеме СКД установлено свойство "Включать в пользовательские настройки", а в коде вы устанавливаете свойство Использование = Истина.
  4. В качестве альтернативы для простых значений по умолчанию, рассмотрите возможность использования выражений в настройках параметров СКД напрямую.

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

← На главную