Ещё немного функционального стиля в 1С или Как нам отфильтровать таблицу значений

0. GlebHappy 113 15.05.20 18:37 Сейчас в теме
Потребовалось накладывать хитрые отборы на таблицу значений в сотни строк и десятки колонок, однако Скопировать со структурой отбора мне не подошло.
Пришлось немного покреативить, подсмотрев, как это делается в других языках - возможно, получилось несколько топорно, но тем не менее - работает.

Перейти к публикации

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Steelvan 16.05.20 12:07 Сейчас в теме
Скорость своего творчества проверял ?
Новиков; t278; awk; r2d255; +4 Ответить
2. CyberCerber 574 16.05.20 15:45 Сейчас в теме
Но что-то я не понял, чем это лучше простого перебора? Тут даже несколько переборов будет, на каждую часть условия. И если по первой части отобрали почти все строки, мы опять их все проходить будем...
Тогда уж можно было передавать полноценное условие на строку вида "Колонка1 = А И Колонка2 < Б ИЛИ Колонка3 = В". Так мы сразу проверяем полное условие за один проход, можем использовать ИЛИ и т.д.
Deslime; wolfsoft; gubanoff; Xershi; vladimirmatancev; +5 Ответить
3. GlebHappy 113 16.05.20 20:40 Сейчас в теме
(2) Да, такой вариант будет работать - но не потеряется ли читаемость условия?
5. CyberCerber 574 17.05.20 05:41 Сейчас в теме
(3) Как по мне, оно будет более читаемое, чем ваше, потому что это всем знакомый формат, а не что-то новое.
4. PowerBoy 2981 16.05.20 22:10 Сейчас в теме
Запросом будет быстрей, на больших таблицах - точно.
the1; nomad_irk; vladimirmatancev; +3 Ответить
13. ImHunter 197 18.05.20 08:05 Сейчас в теме
(4) Весьма спорное утверждение;)
Запросом будет быстрей, на больших таблицах - точно.

Как по-твоему ТЗ попадает на сервер? Делается куча запросов по передаче и вставке каждой строки ТЗ во временную таблицу БД. Т.е., сам запрос, вероятно, быстро отработает. Но будет куча накладных расходов.

Насчет (0) - выглядит на мой взгляд красиво. Обязательно попробую попробовать.
14. nomad_irk 48 18.05.20 09:57 Сейчас в теме
(13)А ничего, что ТЗ на клиенте не умеет жить от слова совсем? :)
16. ImHunter 197 18.05.20 10:03 Сейчас в теме
(14) Как бы, ну и что? К статье это вообще не имеет отношения. Запрос, например, тоже на клиенте не живет.
17. nomad_irk 48 18.05.20 10:05 Сейчас в теме
(16) Так зачем ТЗ передавать на сервер? Она там уже всегда.
18. ImHunter 197 18.05.20 10:24 Сейчас в теме
(17) Имеется в виду передача ТЗ в СУБД для выполнения запроса. Ведь Запрос только с данными СУБД и работает.
При использовании параметра запроса типа ТЗ, платформа неявно создает ВТ. Отсюда, кстати, требование типизации ТЗ. И потом происходит построчное наполнение ВТ.
19. nomad_irk 48 18.05.20 10:27 Сейчас в теме
(18)В любом случае, это работает быстрее, т.к. реализуется средствами платформы.
20. ImHunter 197 18.05.20 10:29 Сейчас в теме
(19) А мы тут никакие ВК и не обсуждаем;) Все только платформой и делается.
6. acanta 17.05.20 06:13 Сейчас в теме
По стандартам 7.7 вычислить/шаблон было не 1с совместимо, из за невозможности синтаксического контроля. Хотя позже я видела несколько тиражных решений, со статусом 1с совместимо, использующих эти методы.
В 8ке что то изменилось (кроме того что в поставку стало возможным не включать код)?
7. vladimirmatancev 17.05.20 09:48 Сейчас в теме
Перебор - некрасиво и громоздко.

Для Каждого СтрТЗ Из ТЗ Цикл

А где тут без перебора?
Deslime; D_astana; CyberCerber; wolfsoft; gubanoff; t278; awk; +7 Ответить
8. awk 716 17.05.20 10:45 Сейчас в теме
(7) Статья явный перебор. :)
CyberCerber; gubanoff; wazup666; +3 Ответить
9. acanta 17.05.20 11:08 Сейчас в теме
Обычная ситуация, допустим у нас таблица значений с кодами товаров, периодами и суммами продаж. Необходимо дополнить ее колонками с какими то расчетным показателями, реквизитами товаров, наименованием и т.п.
В запросе делаем соединение тз со справочником и вычисляем все что вычисляется.
А если периоды нужно разделить, то соединяем тз с самой тз столько раз, сколько максимально периодов может получиться.
После чего отбираем по требуемому диапазону. Так?
10. logarifm 1077 17.05.20 19:23 Сейчас в теме
Нахрена изобретать сей велосипед, когда ТЗ можно сделать источником данных построителя запроса и наложить любые отборы!!!!
VitaliyCeban; blindcat2006; Vlad_2008; wazup666; +4 Ответить
11. oleganatolievich 146 17.05.20 21:21 Сейчас в теме
Для Каждого СтрТЗ Из ТЗ Цикл
Если Вычислить(Выражение) Тогда

ну такое...

(10) плюсую.
22. aspirator23 426 18.05.20 12:04 Сейчас в теме
(10) При том что почти во всех типовых конфигурациях есть в БСП функция на построителе для таких отборов. И работает очень быстро - мне даже кажется быстрее самодельного запроса.
30. Sergafan10 21.05.20 15:43 Сейчас в теме
(22) не подскажете адрес такой функции. Поискал в БСП 3.0.1.19 - не нашёл. Может плохо искал?
12. acanta 17.05.20 21:50 Сейчас в теме
В случае дробления периодов имхо перебор не самое худшее решение. Мне попалась ситуация, в которой больше 15 полей в запросе из табличной части (табеля) выбивало программу.
Если построчно нет неявных запросов к базе, а только 2*2 то почему это должно быть проблемой?
15. ImHunter 197 18.05.20 09:59 Сейчас в теме
Вообще, появление таких способов - это недоработка 1С (кто бы сомневался;). Ведь есть платформенный объект СравнениеЗначений. Почему бы не расширить функционал этого объекта, чтобы писать свой код сравнения... И почему бы не использовать такие объекты при сортировках и фильтрах...
21. Goleff74 166 18.05.20 10:49 Сейчас в теме
Для коллекции значений смысл имеет на клиенте. Для ТЗ - такое.
23. Darklight 22 18.05.20 14:18 Сейчас в теме
Жесть - ну вы даёте - для того чтобы применить несколько условий соединённых операцией "И"- Вы устраиваете перебор всей таблицы, пускай и каждый раз сокращающейся (и то не факт) после применения каждого условия.Это даже не стрельба из пушки - это стрельба из пулемёта типа "Миниган" по воробьям. Да ещё и с применением функции Вычислить - со всеми её недостатками и ограничениями (главный из них - отсутствие поддержки в iOS и требование небезопасного режима выполнения от сеанса), не говоря уже о снижении производительности в многократном циклическом вызове!

Ну ладно бы ещё - ожидать действительно правильной динамической реализации функционального подхода - когда код-реализация алгоритма перебора и фильтрации сначала генерируется целиком (с одним циклом перебора) - а потом уже выполняется единой инструкцией "Выполнить" (ах да - для web-клиента это не возможно... а какой тут нафиг WEB-Клиент - он таблицы значений вообще не поддерживает; но если сделать поддержку для клиентской коллекции ДанныеФормы, то для неё придётся сделать отдельную ветку алгоритма с циклическим (одним циклом) вызовов проверки условий через "Вычислить") - но это снижение производительности только для WEB-Клиента будет, не так уж часто используемого на практике).

Ну, а то, что если уже делать такую функцию - то надо сделать поодержку и других коллекций "ДеревоЗначений", "СписокЗначений", "Структура", "Соответствие", "Массив" (для последние коллекций имеется в виду, что фильтр будет на Значение, которое может содержать какое-то составное значение - например Структуру).

Ну а, на мой взгляд, пока поддержки а-ля LINQ не появится в 1С - все эти способы лишены практического смысла. Чаще всего условия всё-таки проверяются на равенство (хотя вот, да, бывают случаи на неравенство - хотя такой фильтр тоже возможно часто эффективно сделать на инверсию равенства - одним перебором, тем более когда есть одновременно и на равенство и на неравенство условия) - тогда такой алгоритм всегда нужно реализовывать через "НайтиСтроки" - эта встроенная функция работает достаточно быстро.

Ну а если уж так надо сделать более сложные условия (что бывает нужно не так уж часто) - то лучше воспользоваться механизмом СКД (именно СКД - т.к. тут и по таблицам значений (а остальные коллекции нужно будет к ней приводить) можно строить сложные условия, причём в этом случае обращения к СУБД не будет - одна беда - тонкий клиент(ы) не поддерживается). Ну и выгрузка результат в ТЗ из СКД выполняется типовым процессором вывода.

Вот такую универсальную функцию-обёртку было бы хорошо сделать и опубликовать!

Но это - сугубо моё личное мнение....
24. ImHunter 197 18.05.20 14:31 Сейчас в теме
(23) Ну... Можно много рассуждать на темы если бы да кабы.
А вот чел взял да и сделал.
26. Darklight 22 18.05.20 14:58 Сейчас в теме
(24)Ну можно много чего взять и сделать, был бы практический смысл. Я просто высказал, своё мнение, не более того
27. Sergafan10 19.05.20 10:26 Сейчас в теме
Функция ОтборВТЗПоУсловию(ТЗ, ТЗОтборов) Экспорт
	
	Построитель = Новый ПостроительЗапроса;
	Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТЗ);

	Для Каждого х ИЗ ТЗОтборов Цикл
		Отбор = Построитель.Отбор.Добавить(х.НаименованиеОтбора);//Наименование колонки, по которой будет отбор
		Отбор.ВидСравнения = ВидСравнения[х.ВидСравненияОтбора];//"Больше", "Равно", и тд
		Отбор.Значение = х.ЗначениеОтбора;
		Отбор.Использование = Истина;   		
	КонецЦикла;

	Построитель.Выполнить();
	
	Возврат Построитель.Результат.Выгрузить();
	
КонецФункции
Показать
ImHunter; Vlad_2008; Darklight; +3 Ответить
28. aspirator23 426 21.05.20 09:31 Сейчас в теме
(27) см (22) У них универсальнее
29. Sergafan10 21.05.20 15:42 Сейчас в теме
(28) где? что? не поленился, поискал в БСП 3.0.1.19 (не крайняя, конечно, но и не хлам), такую функцию. Так вот, там только одно упоминание о построителе запроса, в обработке сравнения табличных документов.
31. aspirator23 426 21.05.20 15:48 Сейчас в теме
(29) вот эта функция. Типовая, но насчет БСП - это я погорячился
// Отбирает из переданной таблицы строки по заданным критериям.
//
// Параметры:
//  Источник - ТаблицаЗначений, РезультатЗапроса, ОбластьЯчеекТабличногоДокумента - таблица-источник.
//  СтруктураКритериев - Структура - названия отборов и значения, по которым нужно отобрать строки.
//  СтруктураСложныхКритериев - Структура - если свойство передано, то значение содержит вид сравнения.
//
// Возвращаемое значение:
//  РезультатЗапроса - таблица с нужными строками.
//
Функция ОтобратьСтрокиПоКритериям(Источник, СтруктураКритериев, СтруктураСложныхКритериев = Неопределено) Экспорт

	Перем ВидСравненияСложный;

	Если СтруктураСложныхКритериев = Неопределено Тогда
		СтруктураСложныхКритериев = Новый Структура;
	КонецЕсли;

	ПостроительЗапроса = Новый ПостроительЗапроса;
	ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(Источник);

	Для Каждого Критерий Из СтруктураКритериев Цикл
		НовыйОтбор = ПостроительЗапроса.Отбор.Добавить(Критерий.Ключ);

		СтруктураСложныхКритериев.Свойство(Критерий.Ключ, ВидСравненияСложный);

		Если ВидСравненияСложный = Неопределено Тогда
			НовыйОтбор.Установить(Критерий.Значение);
		Иначе
			НовыйОтбор.Использование = Истина;
			НовыйОтбор.ВидСравнения = ВидСравненияСложный;
			НовыйОтбор.Значение = Критерий.Значение;
		КонецЕсли;
	КонецЦикла;

	Возврат ПостроительЗапроса.Результат;

КонецФункции // ОтобратьСтрокиПоКритериям()
Показать
33. Cyberhawk 120 28.06.20 15:25 Сейчас в теме
(31)
ОтобратьСтрокиПоКритериям
В какой конфигурации такое есть?
34. aspirator23 426 28.06.20 20:38 Сейчас в теме
(33) В нескольких, где есть оперативный учет, встречал. Например: УПП, УТ 10, розницах старой и новой...
32. МихаилМ 23.05.20 21:35 Сейчас в теме
Знач ТЗ неправильно сильно
Оставьте свое сообщение
Вопросы с вознаграждением