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

16.05.20

Разработка - Универсальные функции

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

Возникла задача.
Есть таблица значений с колонкой Период типа Дата.

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

Встроенная функция Скопировать(...)  с отбором строк по переданной структуре нам в данном случае не помощник - соответствие не точное.

Перебор - некрасиво и громоздко.

Загрузка ТЗ во временную таблицу запроса и отбор им - стрельба из пушки по воробьям.

Немного покумекал и придумал следующее:

ОтфильтрованнаяТЗ = ФильтрТЗ(ТЗ, "{ИмяКолонки1} + {ИмяКолонки2} <= {ИмяКолонки3} >> {ИмяКолонки2} <> 0");

Функция принимает в качестве аргумента таблицу значений и последовательно применяет к ней условия, разграниченные разделителем >> - получается что-то вроде конвейера.

Значение в фигурных скобках обозначает значение в соответствующей колонке. В итоге выражение должно давать в результате Истина или Ложь, в зависимости от этого строка ТЗ будет передана в обработку на следующий этап конвейера.

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

Сама функция выглядит достаточно просто, но, возможно, её можно упростить и ещё:

Функция Фильтр(Знач ТЗ, ВыражениеФильтрации) Экспорт
	МассивВыражений = МассивВыражений(ВыражениеФильтрации);
	
	Для Каждого Выражение Из МассивВыражений Цикл
		ПромежуточнаяТЗ = ТЗ.СкопироватьКолонки();
		
		Для Каждого СтрТЗ Из ТЗ Цикл
			Если Вычислить(Выражение) Тогда
				ЗаполнитьЗначенияСвойств(ПромежуточнаяТЗ.Добавить(), СтрТЗ);
			КонецЕсли;
		КонецЦикла;
		
		ТЗ = ПромежуточнаяТЗ;
	КонецЦикла;
	
	Возврат ТЗ;
КонецФункции

Функция МассивВыражений(ВыражениеФильтрации)
	ВыражениеРазделенное = СтрРазделить(СтрЗаменить(ВыражениеФильтрации, ">>", "$"), "$", Ложь);
	МассивВыражений = Новый Массив;
	
        Для Каждого Выражение Из ВыражениеРазделенное Цикл
		ВыражениеОбработанное = СтрЗаменить(Выражение, "{", "СтрТЗ.");
		ВыражениеОбработанное = СтрЗаменить(ВыражениеОбработанное, "}", "");
		
		МассивВыражений.Добавить(ВыражениеОбработанное);
	КонецЦикла;
	
	Возврат МассивВыражений;
КонецФункции

 

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2664    0    John_d    8    

53

GUID в 1С 8.3 - как с ними быть

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4597    atdonya    22    

45

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

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

30.11.2023    3956    ke.92@mail.ru    16    

61

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    8804    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

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

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2071    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

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

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16140    133    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7242    quazare    8    

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

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

Насчет (0) - выглядит на мой взгляд красиво. Обязательно попробую попробовать.
14. nomad_irk 71 18.05.20 09:57 Сейчас в теме
(13)А ничего, что ТЗ на клиенте не умеет жить от слова совсем? :)
16. ImHunter 312 18.05.20 10:03 Сейчас в теме
(14) Как бы, ну и что? К статье это вообще не имеет отношения. Запрос, например, тоже на клиенте не живет.
17. nomad_irk 71 18.05.20 10:05 Сейчас в теме
(16) Так зачем ТЗ передавать на сервер? Она там уже всегда.
18. ImHunter 312 18.05.20 10:24 Сейчас в теме
(17) Имеется в виду передача ТЗ в СУБД для выполнения запроса. Ведь Запрос только с данными СУБД и работает.
При использовании параметра запроса типа ТЗ, платформа неявно создает ВТ. Отсюда, кстати, требование типизации ТЗ. И потом происходит построчное наполнение ВТ.
19. nomad_irk 71 18.05.20 10:27 Сейчас в теме
(18)В любом случае, это работает быстрее, т.к. реализуется средствами платформы.
20. ImHunter 312 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 741 17.05.20 10:45 Сейчас в теме
(7) Статья явный перебор. :)
CyberCerber; gubanoff; wazup666; +3 Ответить
9. acanta 17.05.20 11:08 Сейчас в теме
Обычная ситуация, допустим у нас таблица значений с кодами товаров, периодами и суммами продаж. Необходимо дополнить ее колонками с какими то расчетным показателями, реквизитами товаров, наименованием и т.п.
В запросе делаем соединение тз со справочником и вычисляем все что вычисляется.
А если периоды нужно разделить, то соединяем тз с самой тз столько раз, сколько максимально периодов может получиться.
После чего отбираем по требуемому диапазону. Так?
10. logarifm 1117 17.05.20 19:23 Сейчас в теме
Нахрена изобретать сей велосипед, когда ТЗ можно сделать источником данных построителя запроса и наложить любые отборы!!!!
корум; VitaliyCeban; blindcat2006; Vlad_2008; wazup666; +5 Ответить
11. rabid_otter 134 17.05.20 21:21 Сейчас в теме
Для Каждого СтрТЗ Из ТЗ Цикл
Если Вычислить(Выражение) Тогда

ну такое...

(10) плюсую.
22. aspirator23 339 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 312 18.05.20 09:59 Сейчас в теме
Вообще, появление таких способов - это недоработка 1С (кто бы сомневался;). Ведь есть платформенный объект СравнениеЗначений. Почему бы не расширить функционал этого объекта, чтобы писать свой код сравнения... И почему бы не использовать такие объекты при сортировках и фильтрах...
21. Goleff74 214 18.05.20 10:49 Сейчас в теме
Для коллекции значений смысл имеет на клиенте. Для ТЗ - такое.
23. Darklight 32 18.05.20 14:18 Сейчас в теме
Жесть - ну вы даёте - для того чтобы применить несколько условий соединённых операцией "И"- Вы устраиваете перебор всей таблицы, пускай и каждый раз сокращающейся (и то не факт) после применения каждого условия.Это даже не стрельба из пушки - это стрельба из пулемёта типа "Миниган" по воробьям. Да ещё и с применением функции Вычислить - со всеми её недостатками и ограничениями (главный из них - отсутствие поддержки в iOS и требование небезопасного режима выполнения от сеанса), не говоря уже о снижении производительности в многократном циклическом вызове!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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