Как заполнить список выбора в колонке табличной части на обычной форме 1С и решить проблему с исчезновением выбранного значения?

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

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

Почему возникает ошибка при попытке заполнить список выбора?

Для начала проанализируем типичную ошибку, с которой столкнулся автор темы на форуме. При открытии формы он попытался использовать следующий код:


Штрих = Новый ТаблицаЗначений;
// ... выполнение запроса ...
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Штрих.ЗаполнитьЗначения("Штрихкод", РезультатЗапроса.ВыгрузитьКолонку("Штрихкод"));
ЭлементыФормы.МТД_Поставщики.Колонки.Штрихкод.ЭлементУправления.СписокВыбора = Штрих;

В данном фрагменте кода кроются сразу две серьезные методологические ошибки, которые приводят к аварийному завершению работы программы (падению на последних строчках):

  1. Несоответствие типов данных: Свойство СписокВыбора элемента управления (в данном случае это ПолеВвода в колонке табличного поля) ожидает объект типа СписокЗначений. Автор же создает объект типа ТаблицаЗначений и пытается присвоить его напрямую. Платформа 1С не может выполнить автоматическое преобразование таблицы в список, что приводит к ошибке несовместимости типов.
  2. Использование неподходящих методов: Метод ЗаполнитьЗначения() у объекта ТаблицаЗначений предназначен для заполнения всех строк определенной колонки таблицы одним фиксированным значением. Попытка передать туда массив (полученный методом ВыгрузитьКолонку()) некорректна и вызывает исключение "Метод объекта не обнаружен".

Шаг 1. Исправление инициализации списка выбора

Для того чтобы исправить падение кода, мы должны использовать специализированный объект СписокЗначений и его метод ЗагрузитьЗначения(), который отлично принимает массив, возвращаемый методом таблицы значений ВыгрузитьКолонку(). Рассмотрим исправленный и рабочий вариант кода инициализации при открытии формы:


// Создаем запрос для получения штрихкодов по владельцу
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Штрихкоды.Штрихкод КАК Штрихкод
    |ИЗ
    |   РегистрСведений.Штрихкоды КАК Штрихкоды
    |ГДЕ
    |   Штрихкоды.Владелец = &Владелец";

Запрос.УстановитьПараметр("Владелец", Ссылка);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();

// Инициализируем СписокЗначений вместо ТаблицыЗначений
СписокШтрихкодов = Новый СписокЗначений;
СписокШтрихкодов.ЗагрузитьЗначения(РезультатЗапроса.ВыгрузитьКолонку("Штрихкод"));

// Присваиваем список выбора элементу управления колонки
ЭлементыФормы.МТД_Поставщики.Колонки.Штрихкод.ЭлементУправления.СписокВыбора = СписокШтрихкодов;

Этот код успешно отработает без ошибок, и при нажатии на кнопку выбора в ячейке "Штрихкод" пользователь действительно увидит выпадающий список со штрихкодами. Однако здесь мы сталкиваемся со следующей проблемой: при выборе значения из списка и последующем клике на любую другую ячейку выбранный штрихкод бесследно исчезает. Давайте разберемся, почему это происходит и как это исправить.

Причина 1: Неправильная настройка свойств «РежимВыбораИзСписка» и «КнопкаСпискаВыбора»

В обычных формах 1С поведение поля ввода регулируется набором взаимосвязанных свойств. Свойство РежимВыбораИзСписка (Choice list mode) накладывает на поле жесткое ограничение: значение в ячейке *обязательно* должно присутствовать в связанном списке выбора СписокВыбора.

Если этот флаг установлен в значение Истина, а список выбора по какой-то причине пуст, не инициализирован для конкретной строки или же содержит значения другого типа, то при потере фокуса ячейкой платформа принудительно очистит визуальное отображение значения, так как не сможет сопоставить его с элементами списка.

Решение проблемы:

  1. Откройте палитру свойств для элемента управления (Поля ввода) колонки Штрихкод.
  2. Найдите свойство РежимВыбораИзСписка и установите его в значение Ложь.
  3. Найдите свойство КнопкаСпискаВыбора и установите его в значение Истина.

При такой комбинации настроек поле ввода сохранит кнопку выпадающего списка (стрелочку вниз), но платформа перестанет принудительно очищать ячейку при потере фокуса, даже если список выбора в какой-то момент окажется неактуальным.

Причина 2: Несоответствие типов данных реквизита и списка выбора

Еще одна частая причина исчезновения выбранного значения — неявное несовпадение типов данных. Например, в базе данных штрихкод может храниться как строка (тип Строка), а реквизит вашей табличной части Штрихкод на форме имеет тип ссылки (например, СправочникСсылка.Штрихкоды), или наоборот.

Когда пользователь выбирает элемент из списка, платформа пытается записать выбранное значение в связанный реквизит табличной части. Если типы не совпадают (например, вы пытаетесь записать строку "4601234567890" в поле с типом значения Число или СправочникСсылка), трансляция типа завершается неудачей. Платформа не выдает явной ошибки, но значение в реквизит не записывается, и при обновлении строки ячейка снова становится пустой.

Решение проблемы: обязательно проверьте тип реквизита в табличной части вашего объекта (или реквизита формы, если ТЧ создана на форме программно) и тип значений, которые выгружаются из запроса. Они должны быть строго идентичны.

Причина 3: Статическое заполнение списка выбора при открытии формы

В обычных формах 1С табличное поле оптимизирует использование ресурсов: для редактирования всей колонки создается всего один общий элемент управления (в нашем примере — ПолеВвода). Когда вы пишете код заполнения списка выбора в обработчике ПриОткрытии формы, вы жестко задаете один статический список выбора для всей колонки.

Если логика вашей задачи подразумевает, что список штрихкодов должен зависеть от владельца (например, от номенклатуры в текущей строке), то заполнение списка при открытии формы работать не будет. Переходя на новую строку с другой номенклатурой, вы будете видеть либо пустой список, либо список от предыдущей строки, а старые выбранные значения в других строках будут визуально пропадать, так как платформа не найдет их в текущем (изменившемся или пустом) списке выбора элемента управления.

Решение проблемы: динамическое заполнение в событии «НачалоВыбораИзСписка»

Мы рекомендуем отказаться от заполнения списка выбора при открытии формы и перенести этот процесс в обработчик события элемента управления колонки табличной части. Это гарантирует актуальность списка в момент выбора для каждой конкретной строки.

Разберем по шагам, как это реализовать:

  1. Откройте свойства колонки Штрихкод вашей табличной части МТД_Поставщики.
  2. Перейдите на вкладку "События" элемента управления этой колонки и создайте обработчик для события НачалоВыбораИзСписка.
  3. Пропишите в созданном обработчике код динамического заполнения списка на основе данных текущей строки табличной части:

Процедура МТД_ПоставщикиШтрихкодНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
    
    // Отменяем стандартную обработку, чтобы платформа не пыталась открыть свой список
    СтандартнаяОбработка = Ложь;
    
    // Получаем текущую строку табличной части
    ТекущаяСтрока = ЭлементыФормы.МТД_Поставщики.ТекущаяСтрока;
    Если ТекущаяСтрока = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Получаем владельца (например, Номенклатуру) из текущей строки
    ТекущийВладелец = ТекущаяСтрока.Номенклатура;
    Если Не ЗначениеЗаполнено(ТекущийВладелец) Тогда
        Предупреждение("Сначала необходимо выбрать Номенклатуру в строке!");
        Возврат;
    КонецЕсли;
    
    // Формируем запрос для получения штрихкодов конкретно для текущей номенклатуры
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Штрихкоды.Штрихкод КАК Штрихкод
        |ИЗ
        |   РегистрСведений.Штрихкоды КАК Штрихкоды
        |ГДЕ
        |   Штрихкоды.Владелец = &Владелец";
    
    Запрос.УстановитьПараметр("Владелец", ТекущийВладелец);
    РезультатЗапроса = Запрос.Выполнить().Выгрузить();
    
    // Заполняем список выбора конкретного элемента управления
    Элемент.СписокВыбора.Очистить();
    Элемент.СписокВыбора.ЗагрузитьЗначения(РезультатЗапроса.ВыгрузитьКолонку("Штрихкод"));
    
КонецПроцедуры

При таком подходе список выбора будет формироваться индивидуально в момент клика по кнопке выбора в каждой конкретной строке табличной части, что полностью исключит конфликты данных между строками и предотвратит исчезновение ранее выбранных значений.

Причина 4: Отсутствие связи колонки с данными табличной части

Иногда при ручной настройке формы разработчики забывают связать добавленную на форму колонку табличного поля с фактическим реквизитом табличной части объекта. Если у колонки не заполнено свойство Данные (Data):

Решение проблемы: проверьте свойства проблемной колонки на форме. Убедитесь, что в поле свойства Данные указан путь к соответствующему реквизиту табличной части (например, МТД_Поставщики.Штрихкод). Только при наличии этой связи значение будет успешно записываться в базу данных или в объектную структуру документа/справочника.

Резюме

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

← На главную