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