Фильтры в табличном документе на управляемых формах (как в екселе)

24.01.25

Интеграция - Загрузка и выгрузка в Excel

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

Доброго дня.

Возникла задача загрузки табелей из файлов ексель в ЗУП и захотелось мне красоты навести, фильтры там всякие, так эта статья и появилась.

Некоторые задумки подобрал в этой статье Фильтр в отчете, табличном документе на основе фильтра Excel

 

 

Файл читаем в реквизит формы ТаблДокументДляРазбора и инициализируем возможные значения отборов для фильтров, в нашем случае фильтра три - "Месяц", "Подразделение" и "ФизЛицо".

 

&НаСервере
Процедура ПрочитатьФайл(АдресФайла)
	
	ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресФайла);
	ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
	ДвоичныеДанные.Записать(ИмяФайла);	                         

	ТаблДокументДляРазбора.Прочитать(ИмяФайла);  

	ТаблДокументДляРазбора.ФиксацияСлева = 9;

	ОбластьПерваяСтрока = ТаблДокументДляРазбора.Область("R1:R4");
	ОбластьПерваяСтрока.ВысотаСтроки = 15;
	
	//Сброс фильтров по строкам перед открытием 
    СнятьФильтры(ТаблДокументДляРазбора);
	
	АдресВХ = ПоместитьВоВременноеХранилище(ТаблДокументДляРазбора, ЭтаФорма.УникальныйИдентификатор);
	

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

	текМассивЗначений = табДанные.ВыгрузитьКолонку(текПолеОтбора);
	Элементы.ОтборСотрудникСтрока.СписокВыбора.ЗагрузитьЗначения(текМассивЗначений);
		
	ТабДанные = Построитель.Результат.Выгрузить(); 
	текПолеОтбора = "Месяц";                        
		
	ТабДанные.Свернуть(текПолеОтбора);  	 	
	ТабДанные.Сортировать(текПолеОтбора + " Возр");  
		 
	текМассивЗначений = табДанные.ВыгрузитьКолонку(текПолеОтбора);
	Элементы.ОтборПериодСтрока.СписокВыбора.ЗагрузитьЗначения(текМассивЗначений);
				
КонецПроцедуры	

&НаСервере 
Процедура СнятьФильтры(ТаблДокументДляРазбора)
	
	ОбластьСтрока = ТаблДокументДляРазбора.Область(1,,ТаблДокументДляРазбора.ВысотаТаблицы);
	ОбластьСтрока.Видимость = Истина;
	
КонецПроцедуры 

Отборы инициализируем с помощью построителя запроса, для этого в него передаем, область табличного документа с данными на которые будет накладываться фильтр. Ограничим загружаемую в построитель область. Нужно помнить, что первая строка передаваемой области станет заголовками таблицы значений, которую вернет построитель. Поэтому у меня - это строка 5, последняя строка - ТаблДокументДляРазбораюВысотаТаблицы. По колонкам ограничим область номерами колонок наших фильтров. В данном коде самая первая колонка это "НомерКолонкиПериод" (6), последняя - "НомерКолонкиПодразделение"(10).

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

Потом прописываем обработчики для полей фильтров на форме. Для этого можно использовать событие "ПриИзменении". Либо события "ОбработкаВыбора" и "Очистка", в обработчике события "Очистка" я выключаю использование фильтра, для этого для каждого фильтра добавлен реквизит флОчисткаОтбораХХХ тип булево, где ХХХ - имя фильтра. Эти реквизиты инициализируются при создании формы.

Код обработчиков "ОбработкаВыбора", "Очистка" и функция применения фильтра представлена ниже.


&НаКлиенте
Процедура ОтборСотрудникСтрокаОбработкаВыбора(Элемент, ВыбранноеЗначение, ДополнительныеДанные, СтандартнаяОбработка)
	
	СтандартнаяОбработка 	 = Ложь;
	ОтборСотрудникСтрока	 = ВыбранноеЗначение;
	флОчисткаОтбораСотрудник = Ложь;
	
	ПрименитьФильтр();

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

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

	Если Элемент.Имя = "ОтборПериодСтрока" Тогда 
		флОчисткаОтбораПериод = Истина;
	ИначеЕсли Элемент.Имя = "ОтборПодразделениеСтрока" Тогда 
		флОчисткаОтбораПодразделение = Истина; 
	ИначеЕсли Элемент.Имя = "ОтборСотрудникСтрока" Тогда 
		флОчисткаОтбораСотрудник = Истина;
	КонецЕсли;                
		
    ПрименитьФильтр();
	
КонецПроцедуры

&НаКлиенте
Процедура ПрименитьФильтр()
	
	текОтборПериодСтрока	    = СокрЛП(ОтборПериодСтрока);
	текОтборПодразделениеСтрока = СокрЛП(ОтборПодразделениеСтрока);
	текОтборСотрудникСтрока		= СокрЛП(ОтборСотрудникСтрока);	
		
	Для НомерСтроки = 6 По ТаблДокументДляРазбора.ВысотаТаблицы Цикл
		
		текВидимость = Истина;

		//Обработаем применение фильтров
		//фильтр Период
		текОбластьПериод = ТаблДокументДляРазбора.Область(НомерСтроки, НомерКолонкиПериод, НомерСтроки, НомерКолонкиПериод);

		//фильтр Подразделение
		текОбластьПодразделение = ТаблДокументДляРазбора.Область(НомерСтроки, НомерКолонкиПодразделение, НомерСтроки, НомерКолонкиПодразделение);

		//фильтр Сотрудник
		текОбластьСотрудник = ТаблДокументДляРазбора.Область(НомерСтроки, НомерКолонкиФИО, НомерСтроки, НомерКолонкиФИО);
		
		Если Не флОчисткаОтбораПериод Тогда 
			текВидимость = текВидимость И (СтрСравнить(текОтборПериодСтрока, СокрЛП(текОбластьПериод.Текст)) = 0);
		КонецЕсли;	               
		
		Если Не флОчисткаОтбораПодразделение Тогда 
			текВидимость = текВидимость И (текОтборПодразделениеСтрока = СокрЛП(текОбластьПодразделение.Текст));	
		КонецЕсли;

		Если Не флОчисткаОтбораСотрудник Тогда 
			текВидимость = текВидимость И (текОтборСотрудникСтрока = СокрЛП(текОбластьСотрудник.Текст));	
		КонецЕсли;
		
		ОбластьСтрока = ТаблДокументДляРазбора.Область(НомерСтроки, , НомерСтроки);
		ОбластьСтрока.Видимость = текВидимость;
		
	КонецЦикла;
		
КонецПроцедуры

Вот, казалось бы, и все. Но тесты привели к странным результатам, первый выбранный фильтр применялся 28 секунд на файле в 35 тысяч строк, изменение фильтра отрабатывало примерно 2 секунды.

Результаты замера производительности ниже

 

 

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

Насколько я понимаю, там происходит неявный вызов сервера, данные кэшируются и потом фильтр отрабатывает быстро без обращения к серверу.

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

Если не использовать временное хранилище, а просто передавать Табличный документ параметром процедуры с директивой &НаКлиентеНаСервереБезКонтекста, то ускорения не происходит. Так как происходит все тот же неявный вызов сервера.

Чтобы каждый раз не передавать документ на сервер, был создан реквизит "АдресВХ" который инициализируется при чтении файла, т.о. у нас на сервере есть копия табличного документа.
С которым мы можем работать без контекста формы.

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

&НаСервереБезКонтекста
Функция ПрименитьФильтрБК(АдресВХ, НомерКолонкиПериод, флОчисткаОтбораПериод, ОтборПериодСтрока, НомерКолонкиПодразделение, флОчисткаОтбораПодразделение, ОтборПодразделениеСтрока, НомерКолонкиФИО, флОчисткаОтбораСотрудник, ОтборСотрудникСтрока)
	
	РезультатНомераОтображаемыхСтрок = Новый Массив;
	
	времТД = ПолучитьИзВременногоХранилища(АдресВХ);
	
	текОтборПериодСтрока	    = СокрЛП(ОтборПериодСтрока);
	текОтборПодразделениеСтрока = СокрЛП(ОтборПодразделениеСтрока);
	текОтборСотрудникСтрока		= СокрЛП(ОтборСотрудникСтрока);	
		
	Для НомерСтроки = 6 По времТД.ВысотаТаблицы Цикл
		
		текВидимость = Истина;

		//Обработаем применение фильтров
		//фильтр Период
		текОбластьПериод = времТД.Область(НомерСтроки, НомерКолонкиПериод, НомерСтроки, НомерКолонкиПериод);

		//фильтр Подразделение
		текОбластьПодразделение = времТД.Область(НомерСтроки, НомерКолонкиПодразделение, НомерСтроки, НомерКолонкиПодразделение);

		//фильтр Сотрудник
		текОбластьСотрудник = времТД.Область(НомерСтроки, НомерКолонкиФИО, НомерСтроки, НомерКолонкиФИО);
		
		Если Не флОчисткаОтбораПериод Тогда 
			текВидимость = текВидимость И (СтрСравнить(текОтборПериодСтрока, СокрЛП(текОбластьПериод.Текст)) = 0);
		КонецЕсли;	               
		
		Если Не флОчисткаОтбораПодразделение Тогда 
			текВидимость = текВидимость И (текОтборПодразделениеСтрока = СокрЛП(текОбластьПодразделение.Текст));	
		КонецЕсли;

		Если Не флОчисткаОтбораСотрудник Тогда 
			текВидимость = текВидимость И (текОтборСотрудникСтрока = СокрЛП(текОбластьСотрудник.Текст));	
		КонецЕсли;
		
		Если текВидимость Тогда 
			РезультатНомераОтображаемыхСтрок.Добавить(НомерСтроки);
		КонецЕсли;	
		
	КонецЦикла;
	
	Возврат РезультатНомераОтображаемыхСтрок;
	
КонецФункции

Ниже код обработчика выбора фильтра с вызовом функции ПрименитьФильтрБК()

&НаКлиенте
Процедура ОтборПериодСтрокаОбработкаВыбора(Элемент, ВыбранноеЗначение, ДополнительныеДанные, СтандартнаяОбработка)

	СтандартнаяОбработка  = Ложь;
	ОтборПериодСтрока	  = ВыбранноеЗначение;
	флОчисткаОтбораПериод = Ложь;
	
	//ПрименитьФильтр();
	МассивСтрокДляОтображения = ПрименитьФильтрБК(АдресВХ, НомерКолонкиПериод, флОчисткаОтбораПериод, ОтборПериодСтрока, НомерКолонкиПодразделение, флОчисткаОтбораПодразделение, ОтборПодразделениеСтрока, НомерКолонкиФИО, флОчисткаОтбораСотрудник, ОтборСотрудникСтрока);
	
	ОбластьСтрока = ТаблДокументДляРазбора.Область(6,,ТаблДокументДляРазбора.ВысотаТаблицы);
	ОбластьСтрока.Видимость = Ложь;
	
	Для каждого текЭлементМассива Из МассивСтрокДляОтображения Цикл
	
		ОбластьСтрока = ТаблДокументДляРазбора.Область(текЭлементМассива,,текЭлементМассива);
		ОбластьСтрока.Видимость = Истина;
	
	КонецЦикла;
	
КонецПроцедуры

Как видно, тут все просто: получаем массив строк для отображения с помощью функции ПрименитьФильтрБК, скрываем все строки с данными, а потом включаем видимость у нужных строк.

Скриншоты результатов замера, выводы делайте сами.

 

 

P.s. Данная статья не претендует на истину в последней инстанции и появилась как результат поисков причины просадки производительности при наложении фильтров на стороне клиента. Задача решалась в рамках другой более объемной задачи, просьба не сильно пинать за корявость кода. )

Пример наложения фильтров в табличном документе

См. также

SALE! 20%

Загрузка и выгрузка в Excel Оптовая торговля Печатные формы Бухгалтер Пользователь Платформа 1С v8.3 Управляемые формы Платформа 1C v8.2 1C:Бухгалтерия 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Розница 2 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление холдингом 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Бухгалтерский учет Управленческий учет Платные (руб)

Универсальная обработка для загрузки документов из Excel в 1С. Забудьте о ручном вводе: загружайте документы из Excel в 1С за секунды! Не требует указания параметров (номера колонок, номер первой строки таблицы и т.д.) и предварительной настройки. Просто выбираете файл Excel, документ 1С и нажимаете кнопку "Загрузить". Обработка сама находит таблицу в файле Excel, необходимые для загрузки данные в ней (номенклатура, количество, НДС, цена, сумма) и загружает ее в 1С.

6000 5100 руб.

09.11.2016    238556    1084    905    

1020

Загрузка и выгрузка в Excel Маркетплейсы Программист Бухгалтер Пользователь Платформа 1С v8.3 Бухгалтерский учет 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет Управленческий учет Платные (руб)

Реальный помощник, с помощью которого Вы преобразуете необходимые документы для Wildberries, OZON, ЯндексМаркет, Мегамаркет, Aliexpress, Детский мир, МагнитЭкспресс (быв.Казань-Экспресс), Леруа Мерлен, ЭНФАНТА (Акушерство), ЛаМода, Летуаль, Твой дом, Золотое Яблоко в документы "Отчет комиссионера (агента) о продажах" и другие. Работает в 1С:БП 3.0, 1С:БП 3.0 КОРП, 1С:УТ 11, 1С:УНФ, 1С:КА 2, 1С:ERP Управление предприятием. Возможность подключить любые маркетплейсы. Анализ продаж ОZON. 30 дней БЕСПЛАТНОГО пользования!

3600 руб.

12.08.2021    36805    377    68    

164

Загрузка и выгрузка в Excel Логистика, склад и ТМЦ Ценообразование, анализ цен Файловый обмен (TXT, XML, DBF), FTP Бухгалтер Пользователь Платформа 1С v8.3 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Эволюция не стоит на месте - новая удобная версия функциональной обработки для Вашего бизнеса! Что же Вы получаете? Удобный и интуитивно понятный интерфейс с 3-мя этапами работы. 2 режима - автоматический и ручной. Чтение XLSX, XLSM, CSV, XML/YML форматов без офиса, на любом сервере! Визуальное связывание колонок файла и реквизитов простым перетаскиванием колонок. Создание или обновление номенклатуры с иерархией, характеристик, доп. реквизитов, упаковок, загрузка практически неограниченного количества картинок на одну номенклатуру (с возможностью загрузки в несколько потоков одновременно), с хранением в томах или в базе. Загрузка номенклатуры поставщиков или поиск по их данным номенклатуры. Загрузка доп. реквизитов в характеристики. Загрузка штрихкодов с генерацией новых. Создание элементов справочников и ПВХ "на лету" для выбранных реквизитов. (Обновление от 22.01.2025, версия 9.9 - 9.14)

16800 руб.

20.11.2015    157644    384    378    

516

Загрузка и выгрузка в Excel Бухгалтер Пользователь Платформа 1С v8.3 1С:Управление торговлей 10 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Оптовая торговля, дистрибуция, логистика Бухгалтерский учет Управленческий учет Платные (руб)

Загрузка данных отчета о реализации товаров из сервиса "Детский мир" для конфигурации 1С: Бухгалтерия предприятия, редакция 3.0; Управление торговлей, редакция 11; Управление торговлей, редакция 10.3; Управление нашей фирмой, редакция 3.0 и Розница, редакция 3.0 в документ "Отчет комиссионера (агента) о продажах".

4800 руб.

23.01.2022    11481    61    0    

39

SALE! 30%

Загрузка и выгрузка в Excel Документооборот и делопроизводство (СЭД) Учет документов Распознавание документов и образов Бухгалтер Пользователь Управляемые формы 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Розница 2 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление холдингом 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Бухгалтерский учет Управленческий учет Платные (руб)

Универсальная программа для распознавания сканов или фото товарных документов в 1С. Не требует указания параметров и предварительной настройки. Просто выбираете файл (PDF, JPG, DOC, XLS, HTML) выбираете документ 1С и нажимаете кнопку "Распознать и загрузить".

8400 5880 руб.

04.06.2019    108558    317    173    

328

Загрузка и выгрузка в Excel Розничная торговля Логистика, склад и ТМЦ Ценообразование, анализ цен Прайсы Системный администратор Программист Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Управленческий учет Платные (руб)

Загрузка номенклатуры из файлов Excel (xls, xlsx, ods, csv, mxl) в УТ11, КА 2, ERP 2, Розница 2. Задействованы все возможности конфигурации - заполнение реквизитов номенклатуры, дополнительных реквизитов и сведений, характеристики, доп.реквизиты и сведения характеристик. Дополнительные обработки для расширения возможностей.

11100 руб.

29.10.2014    217718    662    529    

457
Оставьте свое сообщение