В системе компоновки данных (СКД) часто используется тип данных СтандартныйПериод. Он удобен для пользователя, так как позволяет выбирать предопределенные интервалы (например, «Этот месяц», «Прошлый квартал»). Однако при разработке внешних обработок или при программном формировании отчетов программисты часто сталкиваются с трудностями при попытке заполнить этот параметр из кода. В этой статье мы подробно разберем, как правильно передать значения начала и конца периода, избежав типичных ошибок и «погрешностей» в результатах отчета.
Рассмотрим ситуацию, с которой начинают многие разработчики. Попытка установить значение свойства через точку в строковом названии параметра выглядит логично, но приводит к ошибке Ошибка при вызове метода контекста (УстановитьЗначениеПараметра): Параметр с указанным именем не найден. Проанализируем пример неправильного кода:
// ОШИБОЧНЫЙ КОД
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Периодичность.ДатаНачала", ДатаНачала);
Выясним причину ошибки: метод УстановитьЗначениеПараметра ожидает в качестве первого аргумента имя параметра точно в том виде, в котором оно задано в схеме компоновки данных (например, Периодичность). Свойства ДатаНачала и ДатаОкончания являются внутренними реквизитами объекта СтандартныйПериод, а не отдельными параметрами компоновки. Обращение к ним через точку внутри строки недопустимо.
Правильный подход заключается в создании полноценного объекта типа СтандартныйПериод, заполнении его свойств и последующей передаче этого объекта в настройки компоновщика. Рассмотрим пошагово, как это реализовать:
// 1. Создаем новый объект типа СтандартныйПериод
НовыйПериод = Новый СтандартныйПериод;
// 2. Устанавливаем вариант периода (Произвольный период или предопределенный)
НовыйПериод.Вариант = ВариантСтандартногоПериода.ПроизвольныйПериод;
// 3. Заполняем даты
НовыйПериод.ДатаНачала = НачалоДня(ДатаНачала);
НовыйПериод.ДатаОкончания = КонецДня(ДатаОкончания);
// 4. Передаем объект в параметры компоновщика
КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Периодичность", НовыйПериод);
Важный нюанс: всегда используйте функцию КонецДня() для даты окончания. Если передать просто дату (на начало суток), данные за последний день периода могут не попасть в отчет, что часто воспринимается как «погрешность» или ошибка в запросе.
Если в схеме СКД для параметра Периодичность включен флаг «Включать в пользовательские настройки», то прямое изменение в КомпоновщикНастроек.Настройки может не сработать. Это связано с тем, что значения из коллекции ПользовательскиеНастройки имеют более высокий приоритет при формировании финального результата. Разберем, как найти и изменить параметр именно в пользовательских настройках:
// Ищем описание параметра в основных настройках
ПараметрДанных = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Периодичность");
Если ПараметрДанных <> Неопределено Тогда
// Получаем идентификатор пользовательской настройки
ИдентификаторПользНастройки = ПараметрДанных.ИдентификаторПользовательскойНастройки;
// Ищем элемент в коллекции пользовательских настроек
ЭлементПользНастройки = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(ИдентификаторПользНастройки);
Если ТипЗнч(ЭлементПользНастройки) = Тип("ЗначениеПараметраКомпоновкиДанных") Тогда
// Устанавливаем использование и значения дат
ЭлементПользНастройки.Использование = Истина;
ЭлементПользНастройки.Значение.Вариант = ВариантСтандартногоПериода.ПроизвольныйПериод;
ЭлементПользНастройки.Значение.ДатаНачала = НачалоДня(ВыбДатаНачала);
ЭлементПользНастройки.Значение.ДатаОкончания = КонецДня(ВыбДатаОкончания);
КонецЕсли;
КонецЕсли;
Этот способ является наиболее надежным при разработке интерфейсных решений, так как он гарантирует синхронизацию значений, которые видит пользователь на форме, с фактическими параметрами запроса.
Проанализируем ситуацию, когда параметры установлены верно, но отчет все равно выводит не те данные. Часто проблема кроется в самой схеме компоновки данных. Если в вашем запросе используются виртуальные таблицы (например, РегистрНакопления.Продажи.Обороты), они по умолчанию ориентируются на системные параметры &НачалоПериода и &КонецПериода.
Для того чтобы ваш пользовательский параметр &Периодичность управлял данными запроса, выполним следующие шаги в конструкторе СКД:
НачалоПериода в колонке «Выражение» укажем: &Периодичность.ДатаНачала.КонецПериода в колонке «Выражение» укажем: &Периодичность.ДатаОкончания.НачалоПериода и КонецПериода, чтобы они не путали пользователя.После этой настройки любые изменения программно заданного СтандартногоПериода будут корректно транслироваться в виртуальные таблицы запроса.
Иногда требуется задать не произвольные даты, а конкретный период, например, «Сегодня» или «Текущий месяц». В этом случае можно использовать перечисление ВариантСтандартногоПериода. Посмотрим на краткий пример:
ЭлементПериода = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Периодичность");
Если ЭлементПериода <> Неопределено Тогда
ЭлементПериода.Значение.Вариант = ВариантСтандартногоПериода.Сегодня;
ЭлементПериода.Использование = Истина;
КонецЕсли;
При таком подходе платформа сама вычислит нужные даты начала и окончания в момент формирования отчета, основываясь на текущей дате сеанса. Это избавляет от необходимости вручную вычислять КонецДня или первый день месяца.
Подводя итог, отметим, что для корректной работы с периодами в СКД важно соблюдать три условия: передавать целиком объект СтандартныйПериод, учитывать коллекцию ПользовательскиеНастройки и правильно связывать выражения параметров в схеме компоновки.