VBA Excel Mac Словарь класса на Mac Получить атрибуты ключей () - PullRequest
0 голосов
/ 07 ноября 2019

Атрибут Get Keys () работает медленно с набором данных приличного размера. Есть ли способ назначать ключи без циклического прохождения каждой записи по отдельности?

Я могу найти только примеры циклов for или do для назначения ключей по отдельности.


Public Property Get Keys() As String()

'Here is the existing code (status bar updated only so the user knows the
'program is still working).

    Dim vlist() As String, i As Long, myKey As Variant, myArr() As Variant, okVP As KeyValuePair, StatBar As String
    StatBar = Application.StatusBar

    If Me.Count > 0 Then
        ReDim vlist(0 To Me.Count - 1)        

        For i = LBound(vlist) To UBound(vlist)
            Set okVP = KeyValuePairs(i + 1)
            vlist(i) = okVP.Key
            If i Mod 5000 = 0 Then
                Application.StatusBar = StatBar & ": " & "Gathering Keys: " & Format(i, "#,##0") & " of " & Format(UBound(vlist), "#,##0")
'                Debug.Print i & " of " & UBound(vlist)
                DoEvents
            End If
        Next i
        Keys = vlist
    End If
    Application.StatusBar = StatBar
End Property

Текущий подход занимает> 5 мин. для ~ 135K записей.

1 Ответ

0 голосов
/ 07 ноября 2019

Нет, вы не можете избежать итерации элементов. В Windows вы, вероятно, могли бы использовать CopyMemory Win32 API для массового копирования массивов, но я бы не стал доверять этим функциям для работы на Mac.

Рассмотрите возможность замены KeyValuePair Dictionary на Вступление Тима Холла Dictionary замена .

Теперь трудно сказать, не видя реализацию класса [_NewEnum] и член по умолчанию (у вас есть такие?), Но насколько яможет сказать, что вы перебираете коллекцию объектов с циклом For...Next - и это самый медленный из возможных способов перебора любой коллекции объектов.

Коллекции объектов хотите, чтобы был повторен с For Each...Next. Просто, может сократить время выполнения на несколько порядков .

Обновление пользовательского интерфейса Application и запуск DoEvents (даже один раз каждые 5K итераций) еще больше замедляют цикл... и это не то, что вы хотите делать в Property Get члене в любом случае.

Похоже, KeyValuePairs - это набор KeyValuePair объектов? 135K из них означают довольно много накладных расходов - в .NET KeyValuePair - это struct (тип значения), а не object (ссылочный тип);они оптимизированы по-разному, и работают по-разному тоже. В любом случае, если у вас есть коллекция KeyValuePair объектов, самый быстрый способ их итерировать - это цикл For Each.

ReDim result(0 To KeyValuePairs.Count - 1)
Dim i As Long
Dim kvp As KeyValuePair
For Each kvp In KeyValuePairs
    result(i) = kvp.Key
    i = i + 1
Next

Более того, из-за того, как работают массивы в VBA, и всех связанных с этим головных болейс набранными массивами, я бы подумал, , возвращая , было бы безопаснее, если бы он был обернут в указатель Variant или "возвращался" через параметр ByRef (но это неработа для Property Get участника).

...