При разработке интерфейсов на управляемых формах в «1С:Предприятии 8.3» программисты часто сталкиваются с задачей оптимизации ввода даты и времени. Классический пример — форма планирования событий или создания документов взаимодействия (например, заказ-нарядов), где пользователю необходимо быстро указать дату начала и окончания процесса. Стандартный календарь удобен для выбора дня, но выбор времени «по минутам» вручную часто замедляет работу. Было бы идеально предоставить пользователю возможность выбирать дату из календаря, а время — из удобного раскрывающегося списка с определенным шагом (например, каждые 30 минут).
В этой статье мы подробно разберем, как реализовать такой совмещенный ввод, выясним, почему стандартное событие НачалоВыбораИзСписка может не работать в управляемом интерфейсе, и покажем готовое решение с использованием механизма расширений конфигурации на примере типовой конфигурации «1С:Управление нашей фирмой» (УНФ).
Для начала проанализируем, как эта задача решена в типовом коде конфигурации. В УНФ при работе с событиями и другими объектами, привязанными ко времени, список выбора формируется динамически. Если перед вами стоит задача найти место заполнения списка в типовом решении, выполните глобальный поиск или воспользуйтесь отладчиком.
В типовой конфигурации УНФ за это отвечает общий модуль СобытияУНФКлиентСервер, а именно процедура ЗаполнитьСписокВыбораВремени. Именно она генерирует временную сетку, которая затем подставляется в элементы управления формы.
Частой ошибкой разработчиков, особенно имеющих опыт работы с обычными формами (в рамках платформы 1С 8.2), является попытка использовать событие НачалоВыбораИзСписка для динамического заполнения перечня доступного времени перед его раскрытием.
Разберем детально, почему этот обработчик «молчит» и не реагирует на нажатия:
НачалоВыбораИзСписка сохранено в основном для обратной совместимости.РежимВыбораИзСписка установлено в значение Истина.РежимВыбораИзСписка в значение Истина, поле ввода перейдет в строгий режим выбора. С него исчезнет кнопка стандартного выбора (календаря), пропадет возможность вводить произвольные значения руками — останется только стрелка «вниз» для раскрытия списка. Соответственно, совместить календарь и список времени таким образом не удастся.РежимВыбораИзСписка установлено в Ложь, а кнопки выбора и списка активны, то при нажатии на них платформа генерирует событие НачалоВыбора, а не НачалоВыбораИзСписка.Чтобы предоставить пользователю и календарь, и список времени в рамках одного поля ввода, необходимо правильно настроить свойства элемента формы в конфигураторе (или программно). Выставите следующие параметры для поля ввода даты:
Ложь (это ключевое условие, чтобы поле не блокировало другие способы ввода);Истина (активирует кнопку с тремя точками или календарем);Истина (активирует кнопку со стрелкой «вниз» для раскрытия заготовленного списка значений).При такой комбинации свойств платформа берет управление на себя: нажатие на кнопку выбора откроет стандартный интерактивный календарь, а нажатие на кнопку списка покажет те значения, которые мы программно добавим в коллекцию СписокВыбора.
Чтобы не снимать типовую конфигурацию с поддержки, всю логику заполнения списка выбора мы вынесем в расширение. Лучшим местом для первоначального наполнения списка является серверный обработчик создания формы.
Рассмотрим пошаговый алгоритм реализации решения:
ЗНСтарт и ЗНФиниш).ПриСозданииНаСервере с аннотацией &НаСервере и типом вызова &После.Проанализируем пример программного заполнения списка выбора времени в модуле формы расширения:
&НаСервере
Процедура РСШ_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Очищаем списки выбора для полей начала и окончания работ
Элементы.ЗНСтарт.СписокВыбора.Очистить();
Элементы.ЗНФиниш.СписокВыбора.Очистить();
// Определяем базовую дату (начало текущего дня из реквизита объекта)
НачальнаяДата = НачалоДня(Объект.Старт);
// Заполняем списки выбора значениями времени с шагом в 30 минут.
// В данном цикле переменная "х" определяет количество 30-минутных интервалов.
// Например, интервал от 18 (9:00 утра) до 42 (21:00 вечера).
Для х = 18 По 42 Цикл
ТекущееВремя = НачальнаяДата + х * 60 * 30; // Вычисляем время в секундах
Элементы.ЗНСтарт.СписокВыбора.Добавить(ТекущееВремя);
Элементы.ЗНФиниш.СписокВыбора.Добавить(ТекущееВремя);
КонецЦикла;
КонецПроцедуры
При работе с расширениями и программным изменением элементов управляемых форм обратите внимание на следующие важные аспекты:
1. Динамическое обновление списка выбора при изменении даты.
В приведенном выше примере базовая дата берется на момент создания формы. Если пользователь изменит саму дату (например, переключит день с 12-го на 13-е число), время в списке выбора может остаться привязанным к предыдущему дню. Чтобы этого избежать, обновляйте коллекцию СписокВыбора также в обработчике события ПриИзменении для основного реквизита даты.
2. Блокировка обработчиков в расширении при ошибках.
Иногда разработчики сталкиваются с ситуацией, когда обработчик события в расширении (особенно с аннотацией &НаКлиенте) срабатывает ровно один раз, а при последующих действиях полностью игнорируется платформой до перезапуска сеанса отладки. Это защитный механизм платформы «1С:Предприятие». Если при выполнении кода в расширении генерируется скрытое исключение или критическая ошибка времени выполнения, платформа может заблокировать вызов этого обработчика в текущем сеансе во избежание бесконечного зацикливания интерфейса. Если вы столкнулись с подобным поведением — внимательно проверьте стек вызовов на наличие ошибок и перезапустите отладку.
3. Режим совместимости расширения.
Следите за тем, чтобы режим совместимости вашего расширения в точности соответствовал режиму совместимости основной конфигурации. Расхождение версий может приводить к нестабильной работе перехватов событий формы на клиенте.
Применяя описанную методику настройки элементов и программного заполнения списков на сервере, вы сможете создавать максимально отзывчивые и эргономичные интерфейсы для пользователей, сохраняя типовую конфигурацию на поддержке.