Как реализовать выбор одного месяца из списка при входе пользователя в 1С

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

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

Анализ исходной задачи и выбор инструментов

Основная сложность задачи, озвученной автором, заключается в ограничении: нужно выбрать строго один месяц. Использование стандартного метода ОтметитьЭлементы для СписокЗначений не совсем корректно, так как этот метод предназначен для множественного выбора (с установкой галочек). Тем не менее, проанализируем, как можно решить задачу разными способами: от простого «переборного» до профессионального «событийного».

Вариант 1. Использование метода ОтметитьЭлементы с проверкой количества

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

Разберем алгоритм по шагам:

  1. Создаем объект СписокЗначений и заполняем его названиями месяцев.
  2. Запускаем цикл, который будет прерван только при корректном выборе.
  3. Вызываем диалог ОтметитьЭлементы.
  4. Подсчитываем количество элементов с установленной пометкой.
  5. Если выбрано больше одного или ни одного — выдаем предупреждение и возвращаемся к началу.

Пример программного кода:


Список = Новый СписокЗначений;
Список.Добавить("Январь");
Список.Добавить("Февраль");
Список.Добавить("Март");
Список.Добавить("Апрель");
Список.Добавить("Май");
Список.Добавить("Июнь");
Список.Добавить("Июль");
Список.Добавить("Август");
Список.Добавить("Сентябрь");
Список.Добавить("Октябрь");
Список.Добавить("Ноябрь");
Список.Добавить("Декабрь");

КоличествоВыбранных = 0;
ВыбранныйМесяцСтруктура = Новый Структура();

Пока Истина Цикл
    Если Список.ОтметитьЭлементы("Выберите ОДИН месяц отпуска!") Тогда
        КоличествоВыбранных = 0;
        Для каждого ЭлементСписка Из Список Цикл
            Если ЭлементСписка.Пометка Тогда
                КоличествоВыбранных = КоличествоВыбранных + 1;
            КонецЕсли;
        КонецЦикла;

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

// Отображение результата
Сообщить("Вы выбрали для отпуска: " + ВыбранныйМесяцСтруктура.Месяц);

Вариант 2. Профессиональный подход: Метод ВыбратьИзСписка

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

Проанализируем преимущества этого метода:

Рассмотрим пример реализации (синхронный метод для обычных форм или простых сценариев):


Список = Новый СписокЗначений;
Список.Добавить("Январь");
Список.Добавить("Февраль");
// ... добавление остальных месяцев ...

ВыбранныйЭлемент = Список.ВыбратьИзСписка("В каком месяце вы планируете отпуск?");

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

Вариант 3. Современный асинхронный метод (для Управляемых форм)

В современных конфигурациях на платформе 8.3 (интерфейс «Такси») использование модальных окон (блокирующих работу системы) не рекомендуется или вовсе запрещено. Для реализации задачи «при входе» правильно использовать асинхронный вызов ПоказатьВыборИзСписка.

Выясним, как это работает по шагам:

  1. В процедуре ПриНачалеРаботыСистемы создаем ОписаниеОповещения. Это объект, который указывает системе, какую процедуру выполнить после того, как пользователь сделает выбор.
  2. Вызываем метод ПоказатьВыборИзСписка.
  3. Программа продолжает работу, а когда пользователь кликает по месяцу, срабатывает наша процедура обработки.

Пример кода в модуле управляемого приложения:


Процедура ПриНачалеРаботыСистемы()
    СписокМесяцев = Новый СписокЗначений;
    // Заполнение списка можно автоматизировать через массив
    МассивМесяцев = Новый Массив;
    МассивМесяцев.Добавить("Январь");
    МассивМесяцев.Добавить("Февраль");
    // ... и так далее
    СписокМесяцев.ЗагрузитьЗначения(МассивМесяцев);

    Оповещение = Новый ОписаниеОповещения("ПослеВыбораМесяца", ЭтотОбъект);
    ПоказатьВыборИзСписка(Оповещение, СписокМесяцев, "Выберите месяц отпуска");
КонецПроцедуры

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

Важные рекомендации по улучшению кода

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

1. Использование Перечислений. Вместо того чтобы вручную прописывать строки «Январь», «Февраль», создайте в конфигураторе объект Перечисление.Месяцы. Это позволит избежать опечаток в коде и упростит локализацию программы. Список значений в таком случае заполняется автоматически:

Список.ЗагрузитьЗначения(Перечисления.Месяцы.Выгрузить().ВыгрузитьКолонку("Ссылка"));

2. Место размещения кода. Чтобы диалог появлялся именно при входе, код следует размещать в Модуле управляемого приложения внутри предопределенной процедуры ПриНачалеРаботыСистемы. Если вы разместите его в ПередНачаломРаботыСистемы, программа может выдать ошибку, так как основной интерфейс еще не инициализирован для показа диалогов.

3. Хранение данных. Помните, что объект Структура существует только пока работает ваш программный код или пока открыта форма. Если вам нужно, чтобы система «запомнила» выбор пользователя до следующего входа, значение из структуры нужно сохранить в базу данных (например, в реквизит справочника Пользователи) или в ХранилищеОбщихНастроек.

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

Подводя итог, можно сказать: хотя задача решается простым циклом и проверкой пометок, использование встроенного метода ВыбратьИзСписка делает код в разы надежнее и проще. Всегда старайтесь использовать штатные возможности платформы для ограничения ввода пользователя, это лучший способ избежать ошибок «человеческого фактора».

← На главную