При разработке обработок и отчетов на платформе 1С:Предприятие 7.7 нередко возникает задача запросить у пользователя элемент справочника без открытия полноценной формы обработки. Начинающие разработчики часто используют для этого стандартную функцию ВвестиЗначение(). Однако при работе с иерархическими справочниками возникает проблема: пользователь может случайно или намеренно выбрать папку (группу), а не конкретный элемент.
Попытка вызвать метод ВыборГруппы(0) для переменной, полученной через ПолучитьПустоеЗначение(), не дает результата. Выясним причину такого поведения платформы и разберем правильные способы решения задачи.
Проанализируем типичную ошибку при вызове функции. Разработчик пишет следующий фрагмент кода:
ТекНоменклатура = ПолучитьПустоеЗначение("Справочник.Номенклатура");
ТекНоменклатура.ВыборГруппы(0);
Если ВвестиЗначение(ТекНоменклатура, "Выберите номенклатуру", "Справочник.Номенклатура") = 0 Тогда
Возврат;
КонецЕсли;
Разберем по шагам, почему этот код не отключает выбор групп:
ПолучитьПустоеЗначение() возвращает пустое ссылочное значение определенного типа, а не сам программный объект справочника и не элемент управления диалога. У базовой ссылки метода ВыборГруппы() попросту не существует.ВыборГруппы() в синтаксисе 1С 7.7 применим либо к объекту типа Справочник, либо к реквизиту диалога на форме, либо вызывается в контексте модуля формы списка справочника.ВвестиЗначение() создает базовое модальное окно выбора без возможности передачи дополнительных настроек и параметров в открываемую форму (свойство Форма.Параметр остается пустым).Рассмотрим подробнее альтернативные и штатные варианты реализации запрета выбора групп.
Самое правильное и чистое решение взамен использования ВвестиЗначение() — это создание программного объекта справочника и вызов его встроенного метода Выбрать(). В этом случае мы можем напрямую применить метод ВыборГруппы(0) к объекту перед открытием модального окна выбора.
Посмотрим на пример кода:
СпрНом = СоздатьОбъект("Справочник.Номенклатура");
СпрНом.ВыборГруппы(0); // Запрещаем выбор папок в диалоге
Если СпрНом.Выбрать("Выберите номенклатуру", "") = 1 Тогда
ТекНоменклатура = СпрНом.ТекущийЭлемент();
// Дальнейшие действия с выбранным элементом
Иначе
// Пользователь нажал "Отмена" или закрыл окно
Возврат;
КонецЕсли;
Разберем детали работы данного метода:
ВыборГруппы(0) на уровне объекта отключает возможность выбора папок для последующего интерактивного окна.Выбрать(<Заголовок>, <ИмяФормы>) открывает модальное окно выбора справочника. Если второй параметр передан как пустая строка "", открывается основная форма списка/выбора.1, если элемент успешно выбран, и 0 при отмене.ТекущийЭлемент().Если по каким-либо причинам требуется оставить именно функцию ВвестиЗначение(), можно реализовать постобработку результата: проверять, является ли выбранный объект группой, и в случае необходимости повторять ввод.
Посмотрим на пример реализации с циклом:
ТекНоменклатура = ПолучитьПустоеЗначение("Справочник.Номенклатура");
Пока ВвестиЗначение(ТекНоменклатура, "Выберите номенклатуру", "Справочник.Номенклатура") = 1 Цикл
Если ТекНоменклатура.ЭтоГруппа() = 0 Тогда
// Выбран корректный элемент, прерываем цикл
Прервать;
Иначе
Предупреждение("Выбор групп запрещен! Выберите элемент.");
ТекНоменклатура = ПолучитьПустоеЗначение("Справочник.Номенклатура");
КонецЕсли;
КонецЦикла;
Если ПустоеЗначение(ТекНоменклатура) = 1 Тогда
Возврат;
КонецЕсли;
Этот способ позволяет избежать использования устаревшего оператора Перейти и метки перехода, обеспечивая понятную логику работы.
Если выбор значения происходит внутри формы документа или журнала, удобным решением является открытие формы подбора с передачей контекста. Это позволяет управлять поведением открываемого списка:
ОткрытьПодбор("Справочник.Номенклатура", "ФормаСписка", Конт, 0);
Конт.ВыборГруппы(0);
В этом случае обработка выбранного значения будет происходить стандартным образом — в предопределенной процедуре ОбработкаПодбора() формы-владельца.
Если выбор групп необходимо ограничить глобально для конкретной формы справочника, изменения можно внести непосредственно в модуль формы списка или формы выбора.
В предопределенной процедуре ПриВыбореСтроки() выполним проверку типа текущей строки. Чтобы отменить стандартный выбор и не допустить закрытия формы, обязательно используем оператор СтатусВозврата(0):
Процедура ПриВыбореСтроки()
Если ЭтоГруппа() = 1 Тогда
Предупреждение("Выбор групп запрещен!");
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецПроцедуры
Также в процедуре ПриОткрытии() формы списка можно напрямую вызвать метод контекста формы ВыборГруппы(0), если открытая форма используется исключительно для выбора конечных элементов.