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