powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Быстрый поиск в двумерном массиве vba
66 сообщений из 66, показаны все 3 страниц
Быстрый поиск в двумерном массиве vba
    #39565823
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть у кого-нибудь такая функция? Только для текстовых массивов?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39565936
Казанский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlackeAngel,
поиск нужен в определенном столбце/строке или по всему массиву?
Массив отсортирован? (если да, поиск можно сделать на порядок быстрее)
Откуда берется массив? Если он считывается с листа Excel или из таблицы Word, можно задействовать методы Find для документа.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39565988
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Казанский,
Массив отсортирован, по одному столбцу.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39565989
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КазанскийОткуда берется массив? Если он считывается с листа Excel или из таблицы Word, можно задействовать методы Find для документа.
Берется из recordset'а и кладется в массив.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566205
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

Код: vbnet
1.
2.
3.
Dim ar() As Variant
ar = Range("A1:A10")
MsgBox WorksheetFunction.Match("SomeValue", ar, 0)
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566208
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
big-duke,
Это к чему?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566209
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для двумерного
Код: vbnet
1.
2.
3.
 Dim ar() As Variant
 ar = Range("A1:B10")
 MsgBox WorksheetFunction.VLookup("A", ar, 2, 0)
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566210
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngelbig-duke,
Это к чему?
Это к тому как искать в массиве.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566212
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
big-duke,
У меня уже в массиве, массив не берется с листа.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566214
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngelbig-duke,
У меня уже в массиве, массив не берется с листа.
Это для примера.
Используйте сразу ваш массив и WorksheetFunction.VLookup
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566221
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
big-duke,
На сколько это быстрее перебора? И на сколько это быстрее бинарного поиска? Или поиска половинного деления?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566229
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

Понятия не имею.

Вы спросили про функцию для поиска в массиве.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566231
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
big-duke, я просил быструю
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566234
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

У вас есть доказательства того, что WorksheetFunction.VLookup - медленная функция ?
Что мешает взять и сравнить ?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566236
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
big-duke,
Вот завтра и сравню на 3млн записях
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566237
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А пока жду ещё предложения...
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566241
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

1М записей ~ 400ms
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566244
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
big-duke,
Тогда мои данные будет этот метод обрабатывать 1,4E11ms... Что то не быстро...
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566245
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

А какой у вас лимит времени на обработку ?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566246
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
big-duke, час
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566249
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

тогда почему поиск в 1 миллионе строк за 400 миллисекунд это медленно ?
Сколько операций поиска нужно выполнить ?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566250
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
big-duke,
(500000строк*70000раз)*4раза.
Миллионы для того чтоб удобней время считать.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566253
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Могу только добавить что перебором массива это заняло 7 часов.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566280
Bobgos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlackeAngel,
Есть уверенность в том, что (500000строк*7000раз)*4раза это оптимальное решение вашей задачи. Вдруг достаточно будет 500000строк*1раз?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566281
Казанский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlackeAngel,
если поиск идет по отсортированному столбцу, можно использовать WorksheetFunction.VLookup или WorksheetFunction.Match с последним аргументом =1, это "интервальный" поиск, т.е. методом половинного деления или еще более оптимизированный. В случае миллионного массива это будет быстрее на 2-3 ПОРЯДКА. Правда, надо еще проверить, что найденное значение равно искомому:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Dim ar() As Variant, col() As Variant, n As Long, x, y
  ar = '... массив
  col = WorksheetFunction.Index(ar, 0, 1) 'выделить 1-й столбец массива
' в цикле
    x = '... искомое значение
    n = WorksheetFunction.Match(x, col, 1) 'интервальный поиск
    If col(n) = x Then 'найдено точное совпадение
      y = ar(n, 3) 'взять соотв. значение из другого столбца
    Else
      'действия, если не найдено
    End If
'конец цикла
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566283
Казанский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
исправление - массив col "вертикальный"
Код: vbnet
1.
    If col(n, 1) = x Then 'найдено точное совпадение
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566284
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Bobgos,к сожалению тут правильного ответа нет, но зато можете посмотреть как это происходит. В любом случае, мне надо оптимизировать этот код:
Код: vbnet
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.
Sub test()
    Dim arr1()
    Application.ScreenUpdating = False
    'range и массив рабочей книги
    ncolumn = Rows(1).Find(What:="Обозначение", LookIn:=xlValues, LookAt:=xlWhole).Column
    Columns(ncolumn + 1).Insert 'вставляем столбец справа
    Cells(1, ncolumn + 1).Value = "Карточки" 'вставляем заголовок столбца
    m = ActiveSheet.Cells(Rows.Count, ncolumn).End(xlUp).Row
    Set rn = ActiveSheet.Cells(2, ncolumn).Resize(m, 2)
    arr2 = rn.Value
    Set conn = New ADODB.Connection     'Создание соединения
    conn.ConnectionString = "Provider=SQLOLEDB.1;Password=132132;Persist Security Info=True;User ID=User;Initial Catalog=dbScanKD;Data Source=SQL05" 'Строка подключения
    conn.Open   'Открытие соединения
    Set rst = New ADODB.Recordset ' Создание объекта Recordset.
    rst.ActiveConnection = conn ' Подключение этого объекта к ранее открытому каналу связи.
    Ask = "SELECT DISTINCT [Oboznach] FROM [dbScanKD].[dbo].[vwScanKD] Where Not ([Oboznach] Like '%СБ'or [Oboznach] Like '%ТУ' or [Oboznach] Like '%ИМ' or [Oboznach] Like '%ДИ' or [Oboznach] Like '%РР' or [Oboznach] Like '%РИ' or [Oboznach] Like '%УД' or [Oboznach] Like '%ЛУ' or [Oboznach] Like '%ТБ' or [Oboznach] Like '%Э3' or [Oboznach] Like '%ПЭ3' or [Oboznach] Like '%Д7' or [Oboznach] Like '%К3' or [Oboznach] Like '%Д4' or [Oboznach] Like '%ДП' or [Oboznach] Like '%РИ' or [Oboznach] Like '%ПГ3' or [Oboznach] Like '%ПГ4' or [Oboznach] Like '%Г4' or [Oboznach] Like '%Э4' or [Oboznach] Like '%ТЭ4' or [Oboznach] Like '%ПИ' or [Oboznach] Like '%И2')"
    rst.Open Ask, conn, adOpenStatic, adLockBatchOptimistic  ' выполняем запрос.
    arr1 = rst.GetRows 'закидываем в массив
    conn.Close 'закрываем соединение
    arr1 = TransposeDim(arr1) 'переворачиваем массив из строк в столбец через функцию TransposeDim с сайта майкрософт
    For i = LBound(arr1) To UBound(arr1)
        For j = LBound(arr2) To UBound(arr2)
            If Len(arr2(j, 1)) > 0 Then
                If InStr(1, arr1(i, 0), "СБ") > 0 Then
                    If InStr(arr2(j, 1), "-") > 0 Then
                        m = Left(arr2(j, 1), InStr(1, arr2(j, 1), "-") - 1) + "СБ"
                        If InStr(1, arr2(j, 1) + "СБ", arr1(i, 0), vbTextCompare) > 0 Then
                            If CInt(arr1(i, 2)) = CInt(arr1(i, 3)) Then 'cравниваем числовые значения
                                arr2(j, 2) = arr1(i, 0)
                            Else
                                arr2(j, 2) = "нет страниц"
                            End If
                        Else
                            If InStr(1, m, arr1(i, 0), vbTextCompare) > 0 Then
                                If CInt(arr1(i, 2)) = CInt(arr1(i, 3)) Then 'cравниваем числовые значения
                                    arr2(j, 2) = arr1(i, 0)
                                Else
                                    arr2(j, 2) = "нет страниц"
                                End If
                            End If
                        End If
                    Else
                        If InStr(1, arr2(j, 1) + "СБ", arr1(i, 0), vbTextCompare) > 0 Then
                            If CInt(arr1(i, 2)) = CInt(arr1(i, 3)) Then 'cравниваем числовые значения
                                arr2(j, 2) = arr1(i, 0)
                            Else
                                arr2(j, 2) = "нет страниц"
                            End If
                        End If
                    End If
                Else
                    If arr2(j, 2) = Empty Then
                        If InStr(1, arr2(j, 1), arr1(i, 0), vbTextCompare) > 0 Then
                            For k = 1 To UBound(massoboz)
                                If InStr(arr2(j, 1), massoboz(k, 1)) > 0 Then
                                    arr2(j, 2) = "нет сборочного"
                                    Exit For
                                Else
                                    If CInt(arr1(i, 2)) = CInt(arr1(i, 3)) Then 'cравниваем числовые значения
                                        arr2(j, 2) = arr1(i, 0)
                                    Else
                                        arr2(j, 2) = "нет страниц"
                                    End If
                                End If
                            Next k
                        End If
                    End If
                End If
            End If
        Next j
    Next i
    ActiveSheet.Cells(2, ncolumn).Resize(UBound(arr2), UBound(arr2, 2)) = arr2'вываливаем на лист
    Application.ScreenUpdating = True
End Sub
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566398
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

можно услышать постановку словами?
Сколько значений ищутся, где они, где основной источник данных, в которых ищется?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566453
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Bobgos,

Интересно как double относится к BlackeAngel Только для текстовых массивов?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566495
Казанский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кросс на 8 страниц! http://www.cyberforum.ru/vba/thread2146804.html
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566511
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Казанский, ага) что то там народ спекся) а тут свежие умы)
Кстати, match не принимает string...
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566513
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Казанский,
Код: vbnet
1.
col = WorksheetFunction.Index(ar, 0, 1) 


Type mismatch.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566515
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Казанский,
Код: vbnet
1.
col = WorksheetFunction.Index(ar, 0, 1) 


ar As Variant, а не Range. Массив начинается с 0,0
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566547
Казанский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlackeAngelКстати, match не принимает string...Неправда.
BlackeAngelType mismatchСтроки длиннее 255 символов. В коде ниже можно смоделировать эту ситуацию.
Вам действительно необходимы такие длинные строки для поиска? Если различия гарантированно есть в первых 100 символах, можно сформировать массив поиска в цикле, заодно обрезав строки. Строку для поиска, ессно, тоже придется обрезать.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Option Compare Text 'сравнивать строки без учета регистра

Sub test()
Dim ar, col, n&, x, y
  ReDim ar(0 To 3, 0 To 1)
  ar(0, 0) = "apple": ar(0, 1) = 10
  ar(1, 0) = "banana": ar(1, 1) = 20 ': ar(1, 0) = String(256, "b")'если включить это, то Type Mismatch
  ar(2, 0) = "lemon": ar(2, 1) = 30
  ar(3, 0) = "mango": ar(3, 1) = 40
  col = WorksheetFunction.Index(ar, 0, 1) 'выделить 1-й столбец массива, у col нумерация с 1!
  For Each x In Array("LEMON", "pearch", "lemon")
    n = WorksheetFunction.Match(x, col, 1) 'интервальный поиск
    If col(n, 1) = x Then 'найдено точное совпадение
      y = ar(n - 1, 1) 'взять соотв. значение из другого столбца
      Debug.Print x, y
    Else
      Debug.Print x, "не найдено"
    End If
  Next
End Sub

Результат:

Код: plaintext
1.
2.
3.
LEMON          30 
pearch        не найдено
lemon          30 
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566548
Фотография big-duke
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть ощущение, что это задача не для VBA.
Я бы смотрел в сторону PowerQuery.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566550
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Казанский можно использовать WorksheetFunction.VLookup или WorksheetFunction.Match

В моем случае как оказалось нельзя.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566554
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хотя может его пугает то что у меня в массиве сразу и string и long?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566555
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КазанскийСтроки длиннее 255 символов.

Я бы сказал они не длиннее 50 символов.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566560
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Казанский,в общем не допираю в чем косяк
Код: vbnet
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.
Sub KD7_ZaprosPoisk()
    a = Timer
    Application.ScreenUpdating = False
    'удаляем предыдущую базу если вдруг есть ==>
    Set fso = CreateObject("Scripting.FileSystemObject")
    If fso.FileExists(ActiveWorkbook.FullName & ".mdb") Then fso.DeleteFile ActiveWorkbook.FullName & ".mdb", True
    'удаляем предыдущую базу если вдруг есть <==
    Dim dbConnectStr As String
    Dim Catalog As Object
    Dim cnt As ADODB.Connection
    Dim sCon$, rs As Object
    Dim sSQL$
    Set rs = CreateObject("ADODB.Recordset")
    Module5.sboboz 'сборочные шаблоны
    massoboz = Module5.oboz
    ncolumn = Rows(1).Find(What:="Обозначение", LookIn:=xlValues, LookAt:=xlWhole).Column
    Columns(ncolumn + 1).Insert
    Cells(1, ncolumn + 1).Value = "Карточки"
    'закидываем с листа в массив -->
    m = ActiveSheet.Cells(Rows.Count, ncolumn).End(xlUp).Row
    Set rn = ActiveSheet.Cells(2, ncolumn).Resize(m, 2)
    arr2 = rn.Value
    'закидываем с листа в массив <--
    'заполняем с сервера ====>
    Set conn = New ADODB.Connection
    conn.ConnectionString = "Provider=SQLOLEDB.1;Password=1qaz@WSX;Persist Security Info=True;User ID=User_for_macros_PDM;Initial Catalog=db_pdm_ScanKD;Data Source=RTVS-SQL05" 'Строка подключения
    conn.Open
    Set rst = New ADODB.Recordset
    rst.ActiveConnection = conn
    Ask = "SELECT [Oboznach],[izm],[Count_page], COUNT(*) as КоличествоЗаписей " _
    & "FROM [db_pdm_ScanKD].[dbo].[pdm_vwScanKD] " _
    & "Where Not ([Oboznach] Like '%ТУ' or [Oboznach] Like '%ИМ' or [Oboznach] Like '%ДИ' or [Oboznach] Like '%РР' or [Oboznach] Like '%РИ' or [Oboznach] Like '%УД' or [Oboznach] Like '%ЛУ' or [Oboznach] Like '%ТБ' or [Oboznach] Like '%Э3' or [Oboznach] Like '%ПЭ3' or [Oboznach] Like '%Д7' or [Oboznach] Like '%К3' or [Oboznach] Like '%Д4' or [Oboznach] Like '%ДП' or [Oboznach] Like '%РИ' or [Oboznach] Like '%ПГ3' or [Oboznach] Like '%ПГ4' or [Oboznach] Like '%Г4' or [Oboznach] Like '%ПГ3' or [Oboznach] Like '%Э4' or [Oboznach] Like '%ТЭ4' or [Oboznach] Like '%ПИ' or [Oboznach] Like '%И2') " _
    & " GROUP BY [Oboznach],[izm],[Count_page]"
    rst.Open Ask, conn, adOpenStatic, adLockBatchOptimistic
    arr1 = rst.GetRows
    conn.Close
    arr1 = TransposeDim(arr1) 'переворачиваем массив
    qSort arr1, LBound(arr1), UBound(arr1), 0 'сортировка
    For i = LBound(arr1) To UBound(arr1)
        arr1(i, 3) = CStr(arr1(i, 3))
    Next
    'заполняем с сервера <==
    Dim col As Variant, N As Long
    col = WorksheetFunction.Index(arr1, 0, 1) 'выделяем 1й столбец массива
    For i = LBound(arr2) To UBound(arr2)
        m = arr2(i, 1)
        m1 = m + "СБ"
        N = WorksheetFunction.Match(m1, col, 1)
        If col(N, 1) = m1 Then
            arr2(i, 2) = arr1(N, 0)
        Else
            N = WorksheetFunction.Match(m, col, 1)
            If col(N, 1) = m Then
                arr2(i, 2) = arr1(N, 0)
            Else
                m = Trim$(m)
                If InStr(1, m, "-") > 0 Then
                    m = Left(m, InStr(1, m, "-") - 1)
                End If
                m1 = m + "СБ"
                N = WorksheetFunction.Match(m1, col, 1)
                If col(N, 1) = m1 Then
                    arr2(i, 2) = arr1(N, 0)
                Else
                    N = WorksheetFunction.Match(m, col, 1)
                    If col(N, 1) = m Then
                        arr2(i, 2) = arr1(N, 0)
                    Else
                        arr2(i, 2) = Empty
                    End If
                End If
            End If
        End If
    Next i
    Stop
    ActiveSheet.Cells(2, ncolumn).Resize(UBound(arr2), UBound(arr2, 2)) = arr2
    Application.ScreenUpdating = True
    MsgBox Timer - a
End Sub


В строке
Код: vbnet
1.
col = WorksheetFunction.Index(arr1, 0, 1) 'выделяем 1й столбец массива


Ошибка 13, type mismatch. Массив arr1 вариант, в нем элементы все стринговые. Что не нравиться не пойму.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566577
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxBlackeAngel,

можно услышать постановку словами?
Сколько значений ищутся, где они, где основной источник данных, в которых ищется?ау
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566589
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymxBlackeAngel,
можно услышать постановку словами?
Сколько значений ищутся, где они, где основной источник данных, в которых ищется?
0. Взять данные с листа, взять данные с сервера, сравнить данные с сервера и данные с листа, если совпало точно/частично - записать в массив взятый с листа, вывалить на лист.
1. Столько сколько на листе, кол-во динамично.
2. Не понятно, что значит "где они"?
3. На сервере
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566610
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

загрузи свой лист во времянку на сервере и там джойнь и антиджойнь с основным набором
SQL сервер как раз предназначен для сортировок и поиска
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566614
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx,если б сервер был мой, или я мог в нём мог вносить изменения, я, логично предположить, искал бы решение в запросах. Так что, не гадаем, а используем vba excel.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566618
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx, но у меня появилась мысль о том ,что можно просто на локальном компьютере создать файл базы и там сделать запрос и все выбрать. Но тут сразу встретились подводные камни:
1. Как с сервера напрямую залить в файл
2. Как в запросе сделать входимости одной таблицы в другую
3. Как импортировать базу лист с ключом, чтоб последовательность или сортировка взятая с листа не слетела.
И это пока, на первый взгляд.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566646
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можно попробовать через dictionary
из двухмерного делаем одномерный ключ
ключ = индекс1 & "=" & индекс2
в него записываем
и так два раза
потом два dictionary сравниваем между собой
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566649
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx, это хорошо, если надо точное значение. Если частичное?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566655
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx, вот пример если интересно.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566737
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

я не до конца понял задачу
исходя из примера, тебе надо сравнить два линейных списка?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566738
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx,грубо говоря да.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566741
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

а если один элемент является подскрокой элемента из другого списка?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566746
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx, так по примеру видно, что этот вариант тоже подойдёт. Но проверять надо входит ли значения со второго листа в первый, а не наоборот.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566749
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx,4я строка листа итого примера, например.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566767
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.к. четкой постановки не услышал, то пока вот что
Код: vbnet
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.
Sub a1()
Dim a As Variant, b As Variant, s As String, i As Integer
Dim d As Object
Set d = CreateObject("Scripting.Dictionary")


Sheets("Лист экселя").Select
a = Sheets("Лист экселя").Range(Cells(1, 1), Cells(1000, 1))
s = ""
For Each v In a
    If v <> "" Then
       d(v) = 1
    End If
Next

Sheets("База сервака").Select
b = Sheets("База сервака").Range(Cells(1, 1), Cells(1000, 1))
For Each v In b
    If v <> "" Then
       i = CInt(d(v))
       If i < 2 Then
          d(v) = i + 2
       End If
    End If
Next

Sheets("Итго").Select
Range(Cells(1, 1), Cells(1000, 3)).Value = ""

i = 1
For Each v In d
    If d(v) = 1 Or d(v) = 3 Then
       Cells(i, 1) = v
    End If
    If d(v) = 2 Or d(v) = 3 Then
       Cells(i, 2) = v
    End If
    i = i + 1
Next


End Sub
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566769
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx,
Базу сервака заполнять надо не так, ТК она идёт напрямую в массив, либо, если знаете как, то напрямую из recordset в dictionary.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566771
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx, и что значит d(v) = 3 ?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566792
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngelandreymx, и что значит d(v) = 3 ?в объекте d, который dictionary, есть много элементов

текущий элемент с индексом, который текстовый и = v
а значение этого элемента - 1, 2 или 3
1 - только в первом массиве
2 - только во втором
3 - в обоих
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566794
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx, а от Cells отвязаться можно как то?
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566802
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Sheets("База сервака").Select
b = Sheets("База сервака").Range(Cells(1, 1), Cells(1000, 1))
For Each v In b вместо цикла по массиву
    If v <> "" Then
       i = CInt(d(v))
       If i < 2 Then
          d(v) = i + 2
       End If
    End If
Next


сделай цикл по рекордсету
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566804
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx,
Нет, я про эту часть
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
i = 1
For Each v In d
    If d(v) = 1 Or d(v) = 3 Then
       Cells(i, 1) = v
    End If
    If d(v) = 2 Or d(v) = 3 Then
       Cells(i, 2) = v
    End If
    i = i + 1
Next
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39566805
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngelandreymx,
Нет, я про эту часть
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
i = 1
For Each v In d
    If d(v) = 1 Or d(v) = 3 Then
       Cells(i, 1) = v
    End If
    If d(v) = 2 Or d(v) = 3 Then
       Cells(i, 2) = v
    End If
    i = i + 1
Next

всё, у меня уикенд, дальше сам, удачи :)
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39567370
Bobgos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlackeAngelandreymx,
Нет, я про эту часть
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
i = 1
For Each v In d If d(v) = 1 Or d(v) = 3 Then Cells(i, 1) = v End If If d(v) = 2 Or d(v) = 3 Then Cells(i, 2) = v End If i = i + 1 Next

BlackeAngel,
Попробуйте сразу написать запрос, который вернет только нужные Вам данные.
Это должно быть быстрее перебора массива
ADO и SELECT * FROM
http://www.sql.ru/forum/1118914-a/vba-excel-i-adodb-connection?hl=recordset
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39567371
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Bobgos,сейчас как раз под в этом направлении, но встала проблема о том что надо сразу же и подключаться и запрашивать с сервера.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39567398
BlackeAngel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BobgosЭто должно быть быстрее перебора массива

в разы быстрее получается
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39567445
Bobgos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlackeAngelBobgosЭто должно быть быстрее перебора массива

в разы быстрее получается
Возвращаясь к постановке вопроса, можно как с сервера так и из листа данные в рекордсет грузить. Для оптимизации откажитесь от transpose даже от MS .если match и index дают ошибки, наверное самый быстрый способ в Экселе через коллекции.
Как нетиповые варианты для поиска расхождений:
А) можно посмотреть на кубы типа на построить сводную в которой источником данных является sql a фильтром значений для того же поля столбец Эксель.
Б) вернуть данные из sql в строки ниже сравниваемых данных Экселе, сортировка по полю, тогда всегда две строки подряд будут идентичными и либо формулой, а лучше sql запросом выбрать уникальные значения.
И никакого перебора ))
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39567447
Bobgos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlackeAngelBobgos,сейчас как раз под в этом направлении, но встала проблема о том что надо сразу же и подключаться и запрашивать с сервера.
В ado есть command и execute.

И посмотрите, может в 7000 Эксель у вас есть более точные границы для where? Типа дата записи с.. по.. или ещё что. Вдруг ваши 500000 превратятся в 7000 и удалив полные дубликаты вы сможете найти только расхождения.

Но лучше уговорить админов нарисовать в sql db процедуру и не мучайте табличный редактор.
...
Рейтинг: 0 / 0
Быстрый поиск в двумерном массиве vba
    #39567455
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlackeAngel,

Если вы захотите продолжать ваши эксперименты в Excel без привлечения субд, то вам надо знать имя
интересующего вас алгоритма.
Это имя - внешнее соединение.
Когда оба соединяемых набора "достаточно большие" - используется соединение слиянием .
Для него требуется, чтобы оба источника данных были отсортированы по ключу слияния.
(То есть в вашем запросе для получения соединяемого множества из бд необходимо добавить соответствующий order by)

статья из википедии приведет вас обратно на sql.ru:
https://ru.wikipedia.org/wiki/Алгоритм_соединения_слиянием_сортированных_списков

Требуется сообразить, что там описан вариант для inner join.
Вам же, судя по всему, требуется вывести все записи с контрольного листа Excel
в соединении с теми записями из БД, которые подошли по условию сравнения.

Поэтому тамошний псевдокод, который кодирует вариант для inner join, должен быть переписан
для left outer join как-то так:

Код: vbnet
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.
//нужно соединить Таблицу 1 (из Excel) и Таблицу 2  (из внешней БД)
 //по условию: МояФункцияСравнения(Таблица1.Колонка1 , Таблица2.Колонка2) = (-1,0,1)

 //внимание, т.к. выводим все из Таблица1, то считаем, что именно в ней нет повторяющихся записей по полю сравнения.

// Таблица1.Сортировать(Колонка1); -- это
// Таблица2.Сортировать(Колонка2); -- и это тоже - начальные условия, 
// !!  данные должны  быть сортированы до начала алгоритма

 Таблица1.ВстатьНаПервуюЗапись;
 Таблица2.ВстатьНаПервуюЗапись;

//-------- начало --------------------------------------
// бежим по всем записям из левой таблицы, соединяя те строки из правой, которые подошли по условию

 ФлагВыводаЛевойЗаписи = 0
 
 Пока Таблица1.НеПоследняяЗапись 
 {
  
     Если Таблица2.НеПоследняяЗапись
           И МояФункцияСравнения(Таблица1.Колонка1 , Таблица2.Колонка2) = -1  -- '  Таблица1.Колонка1 < Таблица2.Колонка2
     {
        
        Если  ФлагВыводаЛевойЗаписи = 0
         {
           Вывести (Таблица1.ТекущаяЗапись, Пусто);
         }

        ФлагВыводаЛевойЗаписи = 0
        Таблица1.ПерейтиКСледующейЗаписи;
     }
  
     Если Таблица2.НеПоследняяЗапись
           И МояФункцияСравнения(Таблица1.Колонка1 , Таблица2.Колонка2) = 0   -- Таблица1.Колонка1 = Таблица2.Колонка2
     {
         Вывести (Таблица1.ТекущаяЗапись, Таблица2.ТекущаяЗапись);
         ФлагВыводаЛевойЗаписи = 1
         Таблица2.ПерейтиКСледующейЗаписи;
     }

     Если Таблица2.НеПоследняяЗапись
            И  МояФункцияСравнения(Таблица1.Колонка1 , Таблица2.Колонка2) = 1   -- Таблица1.Колонка1 > Таблица2.Колонка2          
     {
         Таблица2.ПерейтиКСледующейЗаписи;
     }
                  
     Если Таблица2.НетСледующихЗаписей
     {
         Вывести (Таблица1.ТекущаяЗапись, Пусто);
         Таблица1.ПерейтиКСледующейЗаписи;
     }                  
 }



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

либо сразу уносите задачу в БД (если получается сформулировать удобное условие соединения).
...
Рейтинг: 0 / 0
66 сообщений из 66, показаны все 3 страниц
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Быстрый поиск в двумерном массиве vba
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]