При разработке на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с задачей организации сложного ввода данных. Одним из таких сценариев является использование колонки таблицы значений с типом СписокЗначений. Однако стандартное поведение системы в управляемых формах таково, что при попытке заполнения такого списка пользователю сначала предлагается выбрать тип данных из огромного системного списка, что неудобно и может привести к ошибкам ввода. В этой статье мы подробно разберем, как принудительно ограничить типы данных в таких ячейках, чтобы сделать интерфейс профессиональным и понятным.
Когда мы добавляем обычный реквизит формы с типом СписокЗначений, платформа позволяет нам сразу в палитре свойств указать Тип значения (например, СправочникСсылка.Номенклатура). Но если этот список является частью структуры таблицы значений, ситуация меняется. По умолчанию колонка таблицы имеет тип СписокЗначений, но сам объект «Список» внутри каждой конкретной строки создается с типом «Произвольный».
Давайте проанализируем ситуацию: попытки задать тип через событие ПриОткрытии для всей колонки часто не приносят результата, так как каждый экземпляр списка в строке живет своей жизнью. Разберем наиболее эффективные способы решения этой задачи.
Это самый популярный и простой в реализации способ, подтвержденный практикой разработчиков. Суть метода заключается в том, что в момент, когда пользователь активирует ячейку для редактирования, мы программно перехватываем управление и назначаем объекту СписокЗначений нужный ОписаниеТипов.
Рассмотрим пошагово реализацию этого метода:
ПриНачалеРедактирования и создайте обработчик на клиенте.Посмотрим на пример кода:
&НаКлиенте
Процедура МояТаблицаПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
// Получаем данные текущей строки, которую редактирует пользователь
ТекДанные = Элемент.ТекущиеДанные;
// Если строка не определена (например, при удалении), выходим
Если ТекДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Формируем массив типов, которыми мы хотим ограничить список
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка.Номенклатура"));
МассивТипов.Добавить(Тип("СправочникСсылка.Склады"));
// Создаем объект ОписаниеТипов на основе нашего массива
НужныйТип = Новый ОписаниеТипов(МассивТипов);
// Назначаем ограничение типа конкретному списку в текущей строке
// Предположим, колонка называется "СписокВыбора"
ТекДанные.СписокВыбора.ТипЗначения = НужныйТип;
КонецПроцедуры
В данном примере мы разрешили пользователю добавлять в список только ссылки на справочники «Номенклатура» и «Склады». Теперь при нажатии кнопки добавления в списке значений 1С не будет спрашивать тип, а сразу предложит выбор из указанных объектов.
Хотя клиентское решение работает хорошо, более надежным подходом считается инициализация типов данных в момент создания самой таблицы или добавления новых строк на сервере. Рассмотрим ситуацию, когда таблица заполняется программно в процедуре ПриСозданииНаСервере. Если мы зададим тип сразу, системе не придется выполнять лишний код каждый раз при клике пользователя в ячейку.
Разберем пример программного заполнения:
&НаСервере
Процедура ЗаполнитьТаблицуПрограммно()
// Добавляем новую строку в таблицу
НоваяСтрока = Объект.ТЗ_Данные.Добавить();
// Сразу после создания строки ограничиваем тип списка
// Это гарантирует, что список не будет иметь типа "Произвольный"
ОписаниеНоменклатуры = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");
НоваяСтрока.КолонкаСписок.ТипЗначения = ОписаниеНоменклатуры;
// Теперь можно наполнять список данными, и они будут типизированы
НоваяСтрока.КолонкаСписок.Добавить(Справочники.Номенклатура.ПустаяСсылка());
КонецПроцедуры
Важный нюанс: Если вы очищаете ячейку простым присваиванием Строка.КолонкаСписок = Новый СписокЗначений, то все ваши настройки типов сбросятся! Чтобы сохранить ограничение типа, всегда используйте метод .Очистить() существующего объекта списка вместо создания нового.
Иногда просто ограничить тип недостаточно — нужно наложить дополнительные фильтры (например, выбирать только те товары, которые не помечены на удаление, или только услуги). Для этого мы можем использовать свойство элемента формы ПараметрыВыбора.
Проанализируем, как это работает для колонки таблицы:
Отбор.Услуга(Ложь).Это ограничение будет работать в связке с программным ограничением типа. Если в ТипЗначения установлен справочник «Номенклатура», то при попытке выбора элемента из списка значений будут отображаться только те товары, у которых признак «Услуга» равен «Ложь».
Рассмотрим типичную ситуацию: разработчик установил тип значения, но при нажатии на кнопку выбора всё равно появляется окно со всеми типами метаданных. Выясним причину.
Чаще всего это происходит из-за того, что в свойстве элемента формы (Поле ввода) неверно настроены параметры отображения. Проверьте следующие настройки:
Нет.Да.СписокЗначений.Также стоит помнить об особенностях мобильной платформы. На мобильных устройствах ограничение типа через ТипЗначения является обязательным требованием. Если этого не сделать, мобильное приложение может вести себя непредсказуемо, вызывая стандартные диалоги выбора типа, которые перекрывают весь экран и путают пользователя.
Если вам требуется динамическое ограничение, которое зависит от условий в других колонках (например, в колонке А выбран «Склад», значит в колонке Б со списком должны быть только «Сотрудники» этого склада), используйте событие НачалоВыбора.
Проанализируем алгоритм:
&НаКлиенте
Процедура ТЗСписокНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
// Отменяем стандартное поведение системы
СтандартнаяОбработка = Ложь;
// Программное открытие формы выбора с нужным отбором
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Истина);
ПараметрыФормы.Вставить("МножественныйВыбор", Ложь); // Выбираем по одному элементу в список
// Здесь можно задать сложные отборы
Отбор = Новый Структура("ПометкаУдаления", Ложь);
ПараметрыФормы.Вставить("Отбор", Отбор);
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры
В этом случае вы полностью контролируете процесс. После выбора элемента сработает событие ОбработкаВыбора, где вы сможете добавить выбранное значение в ваш список значений в строке таблицы.
Мы рассмотрели несколько способов ограничения типов в списке значений внутри таблицы значений. Самым надежным и простым является использование события ПриНачалеРедактирования на клиенте в сочетании с правильной инициализацией строк на сервере. Это решение гарантирует отличный пользовательский опыт и исключает ввод некорректных данных в систему.
Используйте объект ОписаниеТипов для жесткой фиксации доступных метаданных и не забывайте про визуальные настройки элементов формы, такие как «Параметры выбора» и кнопки отображения. Это позволит вам создавать удобные и надежные инструменты для работы пользователей в 1С 8.3.