Как правильно организовать выбор периода и дополнительных параметров на управляемой форме 1С?

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

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

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

Проблема модальности и переход к асинхронности

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

Рассмотрим первый и самый простой способ замены — метод ПоказатьВводДаты. В отличие от ВвестиДату, этот метод не возвращает значение сразу, а требует описания оповещения. Однако в последних версиях платформы (начиная с 8.3.18) появился более элегантный способ написания асинхронного кода с использованием ключевого слова Ждать (Await).

Посмотрим на пример того, как мог бы выглядеть код для ввода двух дат по отдельности:


&НаКлиенте
Асинх Процедура ВвестиДатыПоОтдельности(Команда)
    
    НачалоПериода = ТекущаяДата();
    КонецПериода = ТекущаяДата();
    
    // Ввод начальной даты
    РезультатНачало = Ждать ПоказатьВводДатыАсинх("Введите дату начала");
    Если РезультатНачало = Неопределено Тогда
        Возврат; // Пользователь отказался от ввода
    КонецЕсли;
    НачалоПериода = РезультатНачало;
    
    // Ввод конечной даты
    РезультатКонец = Ждать ПоказатьВводДатыАсинх("Введите дату окончания");
    Если РезультатКонец = Неопределено Тогда
        Возврат;
    КонецЕсли;
    КонецПериода = РезультатКонец;
    
    Сообщить("Выбран период: " + НачалоПериода + " - " + КонецПериода);
    
КонецПроцедуры

Обратите внимание на аннотацию Асинх перед процедурой — она обязательна при использовании Ждать.

Использование объекта СтандартныйПериод

Выбор даты по отдельности — это не самый удобный интерфейсный паттерн. В 1С существует специальный объект СтандартныйПериод, который позволяет пользователю выбирать не только произвольные даты, но и готовые интервалы: "Сегодня", "Этот месяц", "Прошлый квартал" и так далее. Это считается стандартом "Look & Feel" в экосистеме 1С.

Разберем по шагам, как вызвать диалог выбора периода асинхронно:


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

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

Выбор дополнительных параметров (Сотрудник, Организация)

Часто одного периода недостаточно. Проанализируем ситуацию, когда после выбора дат нам нужно уточнить, по какому сотруднику выводить данные. Если мы не хотим создавать отдельную сложную форму, можно использовать метод ВвестиЗначениеАсинх. Для комплексного ввода параметров также подойдёт универсальная форма для ввода нескольких значений различных типов.

Рассмотрим комплексный пример взаимодействия с пользователем:


&НаКлиенте
Асинх Процедура ВыполнитьПечатьСПараметрами(Команда)
    
    // 1. Выбор периода
    Период = Новый СтандартныйПериод;
    Диалог = Новый ДиалогРедактированияСтандартногоПериода;
    Диалог.Период = Период;
    ВыбранныйПериод = Ждать Диалог.РедактироватьАсинх();
    
    Если ВыбранныйПериод = Неопределено Тогда
        Возврат;
    КонецЕсли;

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

Лучшая практика: Реквизиты формы вместо всплывающих окон

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

Рекомендуем следующий алгоритм реализации:

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

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

Важные технические нюансы при работе с запросами

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

Выясним, как этого избежать:

Пример установки параметров в коде 1С:


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

Резюмируя: для создания произвольно вводимого периода лучше всего использовать объект СтандартныйПериод, размещенный на форме в виде реквизита. Если же требуется динамический ввод в процессе выполнения кода, используйте асинхронные методы РедактироватьАсинх и ВвестиЗначениеАсинх с использованием ключевого слова Ждать.

← На главную