При разработке интерфейсных механизмов в «1С:Предприятие 8» часто возникает задача запросить у пользователя ввод определенных данных сразу после авторизации. В данном случае мы рассмотрим ситуацию, когда необходимо предложить пользователю выбрать ровно один месяц из двенадцати для планирования отпуска, сохранить этот выбор в структуру и отобразить результат на экране. Мы разберем как базовый подход, предложенный новичком, так и более профессиональные методы реализации этой задачи.
Основная сложность задачи, озвученной автором, заключается в ограничении: нужно выбрать строго один месяц. Использование стандартного метода ОтметитьЭлементы для СписокЗначений не совсем корректно, так как этот метод предназначен для множественного выбора (с установкой галочек). Тем не менее, проанализируем, как можно решить задачу разными способами: от простого «переборного» до профессионального «событийного».
Рассмотрим логику, которую предложил автор темы. Этот способ основан на циклическом вызове диалога до тех пор, пока пользователь не выберет ровно один пункт. Хотя этот метод избыточен, он наглядно показывает работу с объектом СписокЗначений и коллекцией Структура.
Разберем алгоритм по шагам:
СписокЗначений и заполняем его названиями месяцев.ОтметитьЭлементы.Пример программного кода:
Список = Новый СписокЗначений;
Список.Добавить("Январь");
Список.Добавить("Февраль");
Список.Добавить("Март");
Список.Добавить("Апрель");
Список.Добавить("Май");
Список.Добавить("Июнь");
Список.Добавить("Июль");
Список.Добавить("Август");
Список.Добавить("Сентябрь");
Список.Добавить("Октябрь");
Список.Добавить("Ноябрь");
Список.Добавить("Декабрь");
КоличествоВыбранных = 0;
ВыбранныйМесяцСтруктура = Новый Структура();
Пока Истина Цикл
Если Список.ОтметитьЭлементы("Выберите ОДИН месяц отпуска!") Тогда
КоличествоВыбранных = 0;
Для каждого ЭлементСписка Из Список Цикл
Если ЭлементСписка.Пометка Тогда
КоличествоВыбранных = КоличествоВыбранных + 1;
КонецЕсли;
КонецЦикла;
Если КоличествоВыбранных = 1 Тогда
// Находим выбранный элемент и сохраняем в структуру
Для каждого ЭлементСписка Из Список Цикл
Если ЭлементСписка.Пометка Тогда
ВыбранныйМесяцСтруктура.Вставить("Месяц", ЭлементСписка.Значение);
Прервать;
КонецЕсли;
КонецЦикла;
Прервать; // Выход из основного цикла Пока
Иначе
Предупреждение("Необходимо выбрать строго один месяц!");
// Сбрасываем пометки для следующей попытки
Для каждого ЭлементСписка Из Список Цикл
ЭлементСписка.Пометка = Ложь;
КонецЦикла;
КонецЕсли;
Иначе
// Если пользователь нажал Отмена
Возврат;
КонецЕсли;
КонецЦикла;
// Отображение результата
Сообщить("Вы выбрали для отпуска: " + ВыбранныйМесяцСтруктура.Месяц);
Для того чтобы не заставлять пользователя ставить галочки и не писать сложные проверки на количество выбранных элементов, в платформе 1С предусмотрен метод ВыбратьИзСписка. Он открывает меню, в котором можно кликнуть только на одну строку. Это лучшее решение для данной задачи.
Проанализируем преимущества этого метода:
Рассмотрим пример реализации (синхронный метод для обычных форм или простых сценариев):
Список = Новый СписокЗначений;
Список.Добавить("Январь");
Список.Добавить("Февраль");
// ... добавление остальных месяцев ...
ВыбранныйЭлемент = Список.ВыбратьИзСписка("В каком месяце вы планируете отпуск?");
Если ВыбранныйЭлемент <> Неопределено Тогда
Результат = Новый Структура("МесяцОтпуска", ВыбранныйЭлемент.Значение);
Сообщить("Сохранен выбор: " + Результат.МесяцОтпуска);
КонецЕсли;
В современных конфигурациях на платформе 8.3 (интерфейс «Такси») использование модальных окон (блокирующих работу системы) не рекомендуется или вовсе запрещено. Для реализации задачи «при входе» правильно использовать асинхронный вызов ПоказатьВыборИзСписка.
Выясним, как это работает по шагам:
ПриНачалеРаботыСистемы создаем ОписаниеОповещения. Это объект, который указывает системе, какую процедуру выполнить после того, как пользователь сделает выбор.ПоказатьВыборИзСписка.Пример кода в модуле управляемого приложения:
Процедура ПриНачалеРаботыСистемы()
СписокМесяцев = Новый СписокЗначений;
// Заполнение списка можно автоматизировать через массив
МассивМесяцев = Новый Массив;
МассивМесяцев.Добавить("Январь");
МассивМесяцев.Добавить("Февраль");
// ... и так далее
СписокМесяцев.ЗагрузитьЗначения(МассивМесяцев);
Оповещение = Новый ОписаниеОповещения("ПослеВыбораМесяца", ЭтотОбъект);
ПоказатьВыборИзСписка(Оповещение, СписокМесяцев, "Выберите месяц отпуска");
КонецПроцедуры
Процедура ПослеВыбораМесяца(ВыбранныйЭлемент, Параметры) Экспорт
Если ВыбранныйЭлемент <> Неопределено Тогда
ВыборПользователя = Новый Структура;
ВыборПользователя.Вставить("ВыбранныйМесяц", ВыбранныйЭлемент.Значение);
// Показать результат через современное оповещение
ТекстСообщения = "Вы планируете отпуск в месяце: " + ВыборПользователя.ВыбранныйМесяц;
ПоказатьОповещениеПользователя("Выбор принят", , ТекстСообщения);
КонецЕсли;
КонецПроцедуры
Разберем несколько важных моментов, которые помогут сделать ваше решение более надежным и соответствующим стандартам разработки 1С:
1. Использование Перечислений. Вместо того чтобы вручную прописывать строки «Январь», «Февраль», создайте в конфигураторе объект Перечисление.Месяцы. Это позволит избежать опечаток в коде и упростит локализацию программы. Список значений в таком случае заполняется автоматически:
Список.ЗагрузитьЗначения(Перечисления.Месяцы.Выгрузить().ВыгрузитьКолонку("Ссылка"));
2. Место размещения кода. Чтобы диалог появлялся именно при входе, код следует размещать в Модуле управляемого приложения внутри предопределенной процедуры ПриНачалеРаботыСистемы. Если вы разместите его в ПередНачаломРаботыСистемы, программа может выдать ошибку, так как основной интерфейс еще не инициализирован для показа диалогов.
3. Хранение данных. Помните, что объект Структура существует только пока работает ваш программный код или пока открыта форма. Если вам нужно, чтобы система «запомнила» выбор пользователя до следующего входа, значение из структуры нужно сохранить в базу данных (например, в реквизит справочника Пользователи) или в ХранилищеОбщихНастроек.
4. Визуализация. Кроме стандартного Сообщить(), попробуйте использовать ПоказатьОповещениеПользователя. Это создает всплывающее окно в углу экрана, которое выглядит гораздо современнее и не мешает пользователю начинать работу с программой.
Подводя итог, можно сказать: хотя задача решается простым циклом и проверкой пометок, использование встроенного метода ВыбратьИзСписка делает код в разы надежнее и проще. Всегда старайтесь использовать штатные возможности платформы для ограничения ввода пользователя, это лучший способ избежать ошибок «человеческого фактора».