0. GlebHappy 113 15.05.20 18:37 Сейчас в теме

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

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

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

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

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

Насчет (0) - выглядит на мой взгляд красиво. Обязательно попробую попробовать.
14. nomad_irk 47 18.05.20 09:57 Сейчас в теме
(13)А ничего, что ТЗ на клиенте не умеет жить от слова совсем? :)
16. ImHunter 194 18.05.20 10:03 Сейчас в теме
(14) Как бы, ну и что? К статье это вообще не имеет отношения. Запрос, например, тоже на клиенте не живет.
17. nomad_irk 47 18.05.20 10:05 Сейчас в теме
(16) Так зачем ТЗ передавать на сервер? Она там уже всегда.
18. ImHunter 194 18.05.20 10:24 Сейчас в теме
(17) Имеется в виду передача ТЗ в СУБД для выполнения запроса. Ведь Запрос только с данными СУБД и работает.
При использовании параметра запроса типа ТЗ, платформа неявно создает ВТ. Отсюда, кстати, требование типизации ТЗ. И потом происходит построчное наполнение ВТ.
19. nomad_irk 47 18.05.20 10:27 Сейчас в теме
(18)В любом случае, это работает быстрее, т.к. реализуется средствами платформы.
20. ImHunter 194 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 Сейчас в теме
Перебор - некрасиво и громоздко.

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

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

ну такое...

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

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

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

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

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

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

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

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

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

Вакансии

Автор новостных обзоров на тему 1С и бухучета
Санкт-Петербург
По совместительству

Программист 1С
Санкт-Петербург
зарплата до 150 000 руб.
Полный день

Программист 1С
Екатеринбург
зарплата от 80 000 руб. до 130 000 руб.
Полный день

Ведущий программист 1С
Москва
зарплата от 150 000 руб.
Полный день

Ведущий программист 1С (УТ 11)
Москва
зарплата до 200 000 руб.
Полный день