В работе с платформой 1С:Предприятие 8 часто возникает задача: как сделать так, чтобы пользователь мог не просто просматривать данные в форме списка, а и выбирать их для дальнейшей обработки. Стандартная форма выбора (ФормаВыбора) ограничена по функционалу, тогда как форма списка позволяет гибко настраивать отображение, фильтрацию и даже добавлять собственные команды. Но как превратить обычную форму списка в удобный инструмент выбора?

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

Особое внимание уделим случаям, когда форма списка как форма выбора становится единственным рабочим решением — например, при работе с большими объёмами данных или когда требуется предварительная фильтрация по сложным критериям. Вы узнаете, как передавать выбранные значения обратно в вызывающую форму и какие события для этого использовать.

📊 Как часто вы используете формы списка в 1С вместо стандартных форм выбора?
Постоянно
Иногда
Редеко
Никогда

Зачем заменять стандартную форму выбора на форму списка?

Стандартная форма выбора в (ФормаВыбора) удобна для простых сценариев: выбор одного элемента из небольшого списка, например, контрагента или номенклатуры. Однако она имеет ограничения:

  • 🔹 Отсутствие гибкой фильтрации — нельзя добавить собственные поля для отбора или динамически менять условия.
  • 🔹 Ограниченное отображение — колонки фиксированы, нельзя скрывать/показывать их по условию.
  • 🔹 Нет поддержки пакетного выбора — невозможно выбрать несколько элементов одновременно (если не использовать обходные пути).
  • 🔹 Сложно кастомизировать — добавление собственных кнопок или логики требует обхода стандартных механизмов.

Форма списка решает эти проблемы. Она позволяет:

  • 🔧 Настраивать произвольные колонки с группировкой, условным оформлением и вычисляемыми полями.
  • 🔍 Добавлять сложные фильтры с динамическим изменением условий (например, фильтр по дате с учётом текущего пользователя).
  • 📋 Реализовывать пакетный выбор с передачей массива значений обратно.
  • ⚡ Интегрировать дополнительные команды (например, предварительный просмотр выбранного элемента).

Кроме того, форма списка лучше подходит для работы с большими объёмами данных. Например, если в справочнике Номенклатура десятки тысяч позиций, стандартная форма выбора будет тормозить при открытии, тогда как форма списка может реализовать постраничную загрузку или отложенную подгрузку данных.

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

Способы открытия формы списка как формы выбора

Есть несколько способов использовать форму списка для выбора элементов. Рассмотрим два основных подхода: через открытие формы модально и через событие выбора (ПриВыборе).

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

1. Модальное открытие с возвратом значения

Самый распространённый вариант — открыть форму списка модально и дождаться, пока пользователь выберет элемент. Пример кода для управляемой формы:

&Процедура ВыбратьЭлемент(Команда)

ФормаСписка = ПолучитьФорму("Справочник.Номенклатура.ФормаСписка");

ФормаСписка.Открыть();

Если ФормаСписка.Модальность = Истина Тогда

ВыбранныйЭлемент = ФормаСписка.ВыбранноеЗначение;

Если НЕ ВыбранныйЭлемент = Неопределено Тогда

Сообщить("Выбран: " + ВыбранныйЭлемент.Наименование);

КонецЕсли;

КонецЕсли;

КонецПроцедуры

2. Использование события ПриВыборе

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

&Процедура ЭлементыФормыСпискаПриВыборе(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)

СтандартнаяОбработка = Ложь;

ВыбранныйОбъект = ЭлементыФормы.Список.ТекущиеДанные;

Закрыть(ВыбранныйОбъект);

КонецПроцедуры

В вызывающей форме результат можно получить через параметр ЗначениеЗавершения:

ФормаСписка = ПолучитьФорму("Справочник.Номенклатура.ФормаСписка");

ФормаСписка.Открыть();

ВыбранныйЭлемент = ФормаСписка.ЗначениеЗавершения;

⚠️ Внимание: При использовании события ПриВыборе убедитесь, что в настройках колонки табличного поля установлено свойство Выбор = Истина. Иначе двойной клик не будет срабатывать.

- Установлено ли свойство `Выбор = Истина` для колонок таблицы?

- Реализована ли обработка события `ПриВыборе` или модального закрытия?

- Передаются ли данные корректно между формами (через `ЗначениеЗавершения` или параметры)?

- Оптимизирована ли форма для работы с большими объёмами данных?-->

Пример: форма списка для выбора номенклатуры с фильтром

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

Шаг 1. Создание формы списка

В конфигураторе создаём форму списка для справочника Номенклатура. Добавляем табличное поле с колонками:

  • 📌 Наименование (основное поле)
  • 📌 Группа (для фильтрации)
  • 📌 Остаток (вычисляемое поле, показываем остатки на текущем складе)
  • 📌 Цена (текущая цена продажи)

Шаг 2. Добавление фильтров

В форму добавляем элементы управления для фильтрации:

- Поле ввода для поиска по наименованию (ПолеПоиска).

- Поле выбора группы (ПолеГруппы).

- Флажок "Только с остатками" (ФлажокОстатков).

В обработчике изменения фильтров обновляем список:

&Процедура ПриИзмененииФильтра()

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Наименование КАК Наименование,

| Номенклатура.Группа КАК Группа

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Наименование ПОДОБНО &Поиск

| И (&Группа = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) ИЛИ Номенклатура.Группа = &Группа)";

Если ФлажокОстатков.Значение Тогда

Запрос.Текст = Запрос.Текст + "

| И Номенклатура.ОстатокНаСкладе(&Склад) > 0";

КонецЕсли;

Запрос.УстановитьПараметр("Поиск", "%" + ПолеПоиска.Значение + "%");

Запрос.УстановитьПараметр("Группа", ПолеГруппы.Значение);

Запрос.УстановитьПараметр("Склад", ТекущийСклад());

Результат = Запрос.Выполнить();

ЭлементыФормы.Список.Значение = Результат.Выгрузить();

КонецПроцедуры

Шаг 3. Обработка выбора

Добавляем обработчик двойного клика для возврата выбранного элемента:

&Процедура СписокПриВыборе(Элемент, ВыбраннаяСтрока, Колонка)

Закрыть(ВыбраннаяСтрока.Ссылка);

КонецПроцедуры

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

💡

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

Сравнение подходов: управляемые vs обычные формы

Реализация формы списка как формы выбора отличается для управляемых и обычных форм. Основные различия представлены в таблице:

Критерии Управляемые формы Обычные формы
Способ открытия Через ПолучитьФорму() + Открыть() Через ОткрытьФормуМодально()
Передача параметров Через свойство Параметры или конструктор Через параметры метода ОткрытьФормуМодально()
Обработка выбора Событие ПриВыборе или ЗначениеЗавершения Событие ПриВыбореСтроки + Закрыть() с параметром
Производительность Лучше за счёт отложенной загрузки данных Хуже при больших объёмах (загрузка всех данных сразу)
Гибкость настройки Высокая (динамическое изменение колонок, группировок) Ограничена (статическая структура формы)

Для новых конфигураций рекомендуется использовать управляемые формы, так как они предоставляют больше возможностей для кастомизации и лучше оптимизированы. Однако в устаревших конфигурациях (например, на базе 1С:Управление торговлей 10.3) придётся работать с обычными формами.

Пример кода для обычной формы:

Процедура ВыбратьНоменклатуру()

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("РежимВыбора", Истина);

Результат = ОткрытьФормуМодально("Справочник.Номенклатура.ФормаСписка", ПараметрыФормы);

Если Результат.КлючЗавершения = "Выбор" Тогда

Сообщить("Выбрано: " + Результат.Значение.Наименование);

КонецЕсли;

КонецПроцедуры

💡

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

Типичные ошибки и как их избежать

При использовании формы списка как формы выбора разработчики часто сталкиваются с типичными проблемами. Рассмотрим самые распространённые из них и способы их решения.

1. Не передаётся выбранное значение

Частая ошибка — забывают установить ЗначениеЗавершения при закрытии формы. Например, в управляемой форме нужно явно передать значение:

Закрыть(ВыбранныйЭлемент, ?(ВыбранныйЭлемент <> Неопределено, "Выбор", Неопределено));

2. Форма тормозит при открытии

Если в форме списка загружаются все данные справочника (например, 50 000 позиций номенклатуры), интерфейс будет "подвисать". Решения:

  • 🔄 Использовать постраничную загрузку (свойство ПостраничныйПросмотр = Истина).
  • 🔍 Добавить обязательные фильтры (например, по группе или складу).
  • 📊 Загружать только необходимые колонки (избегать выборки всех реквизитов).

3. Двойной клик не срабатывает

Проверьте:

  • 🔘 Установлено ли свойство Выбор = Истина для колонки таблицы.
  • 🔘 Есть ли обработчик события ПриВыборе.
  • 🔘 Не перекрыто ли событие стандартной обработкой (проверьте параметр СтандартнаяОбработка).

4. Не обновляется список после изменения фильтров

Если данные в таблице не меняются при изменении фильтров, проверьте:

  • 🔄 Вызывается ли процедура обновления списка (например, ПриИзмененииФильтра()).
  • 🔄 Корректно ли формируется запрос (используйте Сообщить(Запрос.Текст) для отладки).
  • 🔄 Не кэшируются ли данные (иногда помогает ЭлементыФормы.Список.Очистить() перед загрузкой).
⚠️ Внимание: В формах с динамическим списком (где данные подгружаются по мере прокрутки) событие ПриВыборе может срабатывать некорректно, если пользователь быстро кликает по строкам. В таких случаях лучше использовать кнопку "Выбрать" вместо двойного клика.
Как отладить передачу данных между формами?

Для отладки передачи данных между формами используйте следующие приёмы:

1. В вызывающей форме перед открытием формы списка добавьте Сообщить("Открываем форму с параметрами: " + ПараметрыФормы).

2. В форме списка при открытии выведите Сообщить("Полученные параметры: " + Параметры).

3. При закрытии формы списка проверьте значение ЗначениеЗавершения с помощью Сообщить().

4. Если передаётся сложный объект (например, структура), используйте Сообщить(Новый СериализаторJSON.Записать(ЗначениеЗавершения)) для анализа его содержимого.

Оптимизация производительности

Форма списка как форма выбора может стать "бутылочным горлышком" производительности, если не оптимизировать её работу. Вот ключевые рекомендации:

1. Минимизируйте объём загружаемых данных

  • 📉 Загружайте только необходимые колонки (избегайте ВЫБРАТЬ *).
  • 📉 Используйте отбор по умолчанию (например, только активные элементы справочника).
  • 📉 Для больших справочников настройте постраничный просмотр с размером страницы 50–100 строк.

2. Оптимизируйте запросы

  • 🔧 Используйте индексированные поля в условиях отбора (например, Ссылка или Код вместо Наименование).
  • 🔧 Избегайте подзапросов в основных запросах — заменяйте их временными таблицами.
  • 🔧 Для вычисляемых полей (например, остатков) используйте кеширование или предварительный расчёт.

3. Улучшайте пользовательский опыт

  • ⚡ Добавьте индикатор загрузки для длинных операций.
  • ⚡ Реализуйте автоподстановку при вводе в поле поиска (например, через ПолеВводаАвтоПодстановка).
  • ⚡ Для часто используемых фильтров сохраняйте последние значения в настройках пользователя.

Пример оптимизированного запроса для формы выбора номенклатуры с остатками:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 100

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Наименование КАК Наименование,

| Номенклатура.Артикул КАК Артикул

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.ПометкаУдаления = ЛОЖЬ

| И Номенклатура.ЭтоГруппа = ЛОЖЬ

| И Номенклатура.Наименование ПОДОБНО &Поиск

|УПОРЯДОЧИТЬ ПО

| Наименование

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ОстаткиНоменклатуры.Номенклатура КАК Ссылка,

| ОстаткиНоменклатуры.Номенклатура.Наименование КАК Наименование,

| ОстаткиНоменклатуры.Номенклатура.Артикул КАК Артикул,

| СУММА(ОстаткиНоменклатуры.КоличествоОстаток) КАК Остаток

|ИЗ

| РегистрНакопления.ОстаткиНоменклатуры КАК ОстаткиНоменклатуры

|ГДЕ

| ОстаткиНоменклатуры.Номенклатура В (&СписокНоменклатуры)

| И ОстаткиНоменклатуры.Склад = &Склад

|СГРУППИРОВАТЬ ПО

| ОстаткиНоменклатуры.Номенклатура,

| ОстаткиНоменклатуры.Номенклатура.Наименование,

| ОстаткиНоменклатуры.Номенклатура.Артикул";

Запрос.УстановитьПараметр("Поиск", "%" + ПолеПоиска.Значение + "%");

Запрос.УстановитьПараметр("Склад", ТекущийСклад());

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

СписокНоменклатуры = Новый Массив;

Запрос1 = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ ПометкаУдаления = ЛОЖЬ И ЭтоГруппа = ЛОЖЬ");

Результат1 = Запрос1.Выполнить();

Выборка1 = Результат1.Выбрать();

Пока Выборка1.Следующий() Цикл

СписокНоменклатуры.Добавить(Выборка1.Ссылка);

КонецЦикла;

Запрос.УстановитьПараметр("СписокНоменклатуры", СписокНоменклатуры);

Результат = Запрос.Выполнить();

Пакетный выбор: как вернуть несколько элементов

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

Шаг 1. Настройка табличного поля

В форме списка настраиваем табличное поле:

  • 🔘 Устанавливаем свойство МножественныйВыбор = Истина.
  • 🔘 Добавляем колонку с флажками (ТипЗначения = Булево).

Шаг 2. Обработка выбора

Добавляем кнопку "Выбрать отмеченные" и обработчик:

&Процедура ВыбратьОтмеченные(Команда)

ВыбранныеЭлементы = Новый Массив;

Для Каждого Строка Из ЭлементыФормы.Список.ВыбранныеСтроки Цикл

ВыбранныеЭлементы.Добавить(Строка.Ссылка);

КонецЦикла;

Закрыть(ВыбранныеЭлементы);

КонецПроцедуры

Шаг 3. Получение результата в вызывающей форме

В вызывающей форме обрабатываем массив:

Результат = ОткрытьФормуМодально("Справочник.Номенклатура.ФормаСпискаПакетныйВыбор");

Если ТипЗнач(Результат) = Тип("Массив") Тогда

Для Каждого Элемент Из Результат Цикл

Сообщить("Выбран: " + Элемент.Наименование);

КонецЦикла;

КонецЕсли;

Для удобства пользователя можно добавить:

  • 🔹 Кнопки "Отметить все" / "Снять отметки".
  • 🔹 Подсчёт количества выбранных элементов.
  • 🔹 Фильтрацию по отмеченным (например, показать только выбранные строки).
⚠️ Внимание: При пакетном выборе больших массивов данных (более 1000 элементов) может возникнуть ошибка переполнения стека. В таких случаях передавайте не сами объекты, а их ссылки или идентификаторы, а затем загружайте данные порциями.

Интеграция с другими механизмами 1С

Форма списка как форма выбора может интегрироваться с другими механизмами платформы 1С:Предприятие, расширяя её функциональность.

1. Работа с правами доступа

Если в форме выбора нужно учитывать права пользователя, добавьте проверку в запрос:

Запрос.Текст = Запрос.Текст +

" И Номенклатура.Группа В (

| ВЫБРАТЬ РазрешеннаяГруппа.Ссылка

| ИЗ Справочник.ГруппыНоменклатуры КАК РазрешеннаяГруппа

| ГДЕ РазрешеннаяГруппа.Ссылка В (&РазрешенныеГруппы)

|)";

РазрешенныеГруппы = ПолучитьРазрешенныеГруппыНоменклатуры(ТекущийПользователь());

Запрос.УстановитьПараметр("РазрешенныеГруппы", РазрешенныеГруппы);

2. Использование расширений

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

3. Интеграция с внешними системами

Если данные для формы выбора берутся из внешней системы (например, через HTTP-сервис или REST API), реализуйте загрузку данных в фоновом режиме:

&Процедура ЗагрузитьДанныеИзAPI()

HTTPСоединение = Новый HTTPСоединение("api.example.com");

Ответ = HTTPСоединение.Получить("/nomenclature?filter=" + ПолеПоиска.Значение);

Данные = Новый ЧтениеJSON;

Данные.УстановитьСтроку(Ответ.ПолучитьТекст());

ЭлементыФормы.Список.Значение = ПрочитатьJSON(Данные);

КонецПроцедуры

4. Сохранение пользовательских настроек

Чтобы пользовательские настройки формы (ширина колонок, фильтры) сохранялись между сеансами, используйте механизм ПользовательскиеНастройки:

&Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

СтандартнаяОбработка = Ложь;

Настройки = ПользовательскиеНастройки.Создать(

"Справочник.Номенклатура.ФормаВыбора",

Новый УникальныйИдентификатор()

);

Если Настройки.Существует("ШиринаКолонок") Тогда

ЭлементыФормы.Список.ЗагрузитьНастройки(Настройки.Получить("ШиринаКолонок"));

КонецЕсли;

КонецПроцедуры

&Процедура ПриЗакрытии(Отказ)

Настройки = ПользовательскиеНастройки.Создать(

"Справочник.Номенклатура.ФормаВыбора",

Новый УникальныйИдентификатор()

);

Настройки.Установить("ШиринаКолонок", ЭлементыФормы.Список.СохранитьНастройки());

КонецПроцедуры

💡

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

FAQ: ответы на частые вопросы

Можно ли использовать форму списка как форму выбора в мобильном приложении 1С?

Да, но с оговорками. В мобильном клиенте 1С:Предприятие формы списка поддерживаются, однако:

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

Рекомендуется использовать упрощённые формы с минимальным количеством колонок и оптимизированными запросами.

Как передать в форму списка параметры фильтрации из вызывающей формы?

Параметры можно передать несколькими способами:

  1. Через конструктор формы (для управляемых форм):
  2. Форма = ПолучитьФорму("Справочник.Номенклатура.ФормаСписка", , Истина);
    

    Форма.Параметры.Группа = ТекущаяГруппа;

    Форма.Открыть();

  3. Через глобальные переменные