Форум программистов, компьютерный форум, киберфорум
bedvit
Войти
Регистрация
Восстановить пароль

Фильтр одномерного и двухмерного СОМ-массива (VARIANT)

Запись от bedvit размещена 15.10.2022 в 22:01
Показов 2302 Комментарии 0
Метки vb

Фильтр одномерного и двухмерного СОМ-массива (тип данных VARIANT) с любым количеством столбцов, с любым количеством условий.
Реализован параллельный алгоритм фильтрации (поддержка любого количества логических процессоров).
Часть библиотеки BedvitCOM (начиная с v2.0.1.0, в XLL c v3.2.1.0)

ArrayFilterV(VARIANT* array_in, VARIANT* array_parameters, VARIANT_BOOL array_out_index, VARIANT* array_out)
1. array_in - массив входящий (одномерный, двухмерный), тип данных VARIANT.
2. array_parameters - массив задаваемых параметров, тип данных VARIANT (6 параметров для одного условия, можно для одного и того же столбца, можно для разных). Количество условий не ограничено. Условия можно создать из списка, можно создать двухмерный массив и заполнить, можно забрать сразу с листа Excel.
3. array_out_index - режим вывода: 0- отфильтрованный массив, 1-массив индексов
4. array_out - массив результатов

Условия в массиве параметров применяются в порядке следования, если нет скобок или внутри скобок. Скобки задают приоритет выполнения условий (стандартно), потом "И" и "ИЛИ" в порядке очередности.
Параметры массива условий (сделал максимально близко к стандартной записи условий) - 6 параметров для каждой строки условия:
1.Логические операторы (0-ИЛИ, 1-И). Для первого условия можно не указывать.
2.Скобки открывающие (если нужны, можно несколько)
3.Столбец для фильтрации
4.Операторы сравнения (для сравнения значения заданного столбца со значением фильтра):
1 - меньше (для числа),
2 - равно (для числа и строки),
4 - больше (для числа),
8 - содержит подстроку (для строки),
16 - зарезервированное значение (регулярки),
32 - игнорировать регистр (для строки) ,
64 - зарезервированное значение (basic),
128 - зарезервированное значение (extended),
256 - LIKE (пока только знак подстановки "*")(для строки) (начиная с v3.5, в XLL c v4.6) полноценный Like (бинарный режим)
512-НЕ (для числа и строки)

Реализовано в виде бинарной маски, т.е. можно складывать, к примеру 8+512 - НЕ содержит подстроку, 1+2 - меньше или равно и т.д.
5.Значение фильтра (для фильтрации)
6.Скобки закрывающие (если нужны, можно несколько)

т.е. для каждого условия 6 параметров: И/ИЛИ,(((...,стобец, оператор сравнения, значение, ...)))

Условия можно задавать как простые:
'фильтр по первому столбцу, значение = 9
Array(,,1, 2, 9, "")

так и более сложные, к примеру (см.рис.)

Array(,"(((", 1, Содержит, "маша", , ИЛИ, , 1, Содержит, "вася", ")", И, , 1, НеРавно, "маша иванова", ")", ИЛИ, "(", 2, НеРавно, "'1", , ИЛИ, , 2, Равно, 1, "))", И, "(", 3, БольшеРавно, 12.5, , И, , 3, МеньшеРавно, 55.8, ")")
или в таком виде (как удобнее). В примере для операторов сравнения созданы псевдонимы (в виде слова, по факту это банарная маска, см. выше)
Array( _
,"(((", 1, Содержит, "маша", , _
ИЛИ, , 1, Содержит, "вася", ")", _
И, , 1, НеРавно, "маша иванова", ")", _
ИЛИ, "(", 2, НеРавно, "'1", , _
ИЛИ, , 2, Равно, 1, "))", _
И, "(", 3, БольшеРавно, 12.5, , _
И, , 3, МеньшеРавно, 55.8, ")" _
)


Тайминги: фильтрация 10 млн. строк с найденными 5 млн. = 0,2 секунды

Простые примеры (с замером скорости на 10 млн строк) и сложные (с выводом условий и результата):
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
Option Explicit
'операторы (aliases) псевдонимы
Const ИЛИ = 0, И = 1, РАВНО = 2, СОДЕРЖИТ = 8, НЕРАВНО = 512 + 2, МЕНЬШЕРАВНО = 1 + 2, БОЛЬШЕРАВНО = 4 + 2, МЕНЬШЕ = 1, БОЛЬШЕ = 4
 
'ОДНОМЕРНЫЙ МАССИВ, ПРОСТЫЕ УСЛОВИЯ, бинарная маска без слова-псевдонима
Sub TestArrayFilterV_1()
    'Dim bVBA As New BedvitCOM.VBA 'раннее связывание
    Dim bVBA As Object: Set bVBA = CreateObject("BedvitCOM.VBA") 'позднее связывание
    Dim arrResult
    'первоначальный массив данных
    Dim arrV: arrV = Array(1, 0, 1, 0, 1, 0)
    'массив условий (фильтр по первому столбцу, значение = 1)
    Dim p: p = Array(, , 1, 2, 1, "")
 
    ' фильтруем ===============================
    bVBA.ArrayFilterV arrV, p, 0, arrResult
    '========================================
    Debug.Print UBound(arrResult) + 1 'начало с 0
End Sub
 
 
 
'ДВУХМЕРНЫЙ МАССИВ, ПРОСТЫЕ УСЛОВИЯ, бинарная маска в виде слова-псевдонима
Sub TestArrayFilterV_2()
    'Dim bVBA As New BedvitCOM.VBA 'раннее связывание
    Dim bVBA As Object: Set bVBA = CreateObject("BedvitCOM.VBA") 'позднее связывание
    Dim arrResult, r, c, t, x
    Dim sizeRow As Long: sizeRow = 10000000
    Dim sizeCol As Long: sizeCol = 1
    Dim arrV: ReDim arrV(1 To sizeRow, 1 To sizeCol) 'первоначальный массив данных, далее хаполняем рендомно
     
    'массив условий (фильтр по первому столбцу, значение = 1)
    Dim p: p = Array(, , 1, РАВНО, 1, "")
     
    'заполняем первоначальный массив с данными
    For r = 1 To sizeRow
        For c = 1 To sizeCol
        arrV(r, c) = CLng(Rnd * 2)
        Next
    Next
     
    t = Timer
    ' фильтруем ===============================
    bVBA.ArrayFilterV arrV, p, 0, arrResult
    '========================================
    Debug.Print Timer - t
    Debug.Print UBound(arrResult) + 1 'начало с 0
End Sub
 
 
 
'ДВУХМЕРНЫЙ МАССИВ, СЛОЖНЫЕ УСЛОВИЯ, бинарная маска в виде слова-псевдонима
Sub TestArrayFilterV_3()
 
Dim arrParam, arrTest, arrRes, bCOMvba As Object: Set bCOMvba = CreateObject("BedvitCOM.VBA")
 
Cells.ClearContents
 
'создаем тестовый массив
arrTest = Array("маша иванова", "'1", 13, "маша иванова", 1, 13, "маша", "'1", 14, "вася", "'1", 14, "паша", 1, 50, "вася", 2, 52, "маша", 1, 60, "вася", 1, 65)
bCOMvba.Array1Dto2D arrTest, 1, 1, UBound(arrTest) / 3: bCOMvba.Transpose arrTest
Cells(1, 1).Resize(UBound(arrTest, 1), UBound(arrTest, 2)) = arrTest
 
'запись условий для фильтра:(((c1 like "маша" or like "вася") and c1<>"маша иванова") or (c2<>"1" or c2=1)) and (c3>=12,5 and c3<=55,8)
arrParam = Array(, "(((", 1, СОДЕРЖИТ, "маша", , ИЛИ, , 1, СОДЕРЖИТ, "вася", ")", И, , 1, НЕРАВНО, "маша иванова", ")", ИЛИ, "(", 2, НЕРАВНО, "'1", , ИЛИ, , 2, РАВНО, 1, "))", И, "(", 3, БОЛЬШЕРАВНО, 12.5, , И, , 3, МЕНЬШЕРАВНО, 55.8, ")")
'ИЛИ ТАК
arrParam = Array( _
, "(((", 1, СОДЕРЖИТ, "маша", , _
ИЛИ, , 1, СОДЕРЖИТ, "вася", ")", _
И, , 1, НЕРАВНО, "маша иванова", ")", _
ИЛИ, "(", 2, НЕРАВНО, "'1", , _
ИЛИ, , 2, РАВНО, 1, "))", _
И, "(", 3, БОЛЬШЕРАВНО, 12.5, , _
И, , 3, МЕНЬШЕРАВНО, 55.8, ")" _
)
bCOMvba.Array1Dto2D arrParam, 1, 1, UBound(arrParam) / 6: bCOMvba.Transpose arrParam
Cells(1, 5).Resize(UBound(arrParam, 1), UBound(arrParam, 2)) = arrParam
 
'применяем фильтр
bCOMvba.ArrayFilterV arrTest, arrParam, 0, arrRes
Cells(1, 12).Resize(UBound(arrRes, 1), UBound(arrRes, 2)) = arrRes
 
End Sub
Миниатюры
Нажмите на изображение для увеличения
Название: s014ArrayFilterV.png
Просмотров: 1008
Размер:	134.2 Кб
ID:	7734  
Метки vb
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru