Огромная таблица - медленная скорость расчета по формулам - PullRequest
0 голосов
/ 04 мая 2018

У меня есть таблица Excel с около 300 000 записей. Я применяю формулу Vlookup к первой строке, а затем пытаюсь скопировать и вставить специальные как формулы в оставшиеся строки. Но вычисления, как правило, занимают много времени и показывают прогресс в многопоточности, который действительно медленный.

Может кто-нибудь предложить способ сделать это, чтобы сэкономить время.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Если вы застряли с ним, лучше всего оптимизировать формулы, избегая распространенных ошибок. Вы упомянули, что используете VLOOKUP, почему бы не попробовать INDEX/MATCH комбинированный, он более универсален и работает быстрее, чем VLOOKUP. Другие методы оптимизации включают в себя:

  • избегая летучих формул
  • с использованием вспомогательных столбцов
  • расположите столбцы таким образом, чтобы последовательность вычислений была слева направо, сверху вниз, очень похоже на чтение английского текста
  • Использовать структурированные и именованные ссылки
  • Включить ручной расчет, чтобы формулы не пересчитывались каждый раз, когда вы вносите даже малейшие изменения

Вы также можете использовать таймер для измерения времени расчета в Excel, чтобы сравнить различные подходы, например, предложенные Чарльзом Уильямсом, из статьи в Microsoft Developer Network. Вставьте этот код в редактор VBA:

#If VBA7 Then
    Private Declare PtrSafe Function getFrequency Lib "kernel32" Alias _
        "QueryPerformanceFrequency" (cyFrequency As Currency) As Long
    Private Declare PtrSafe Function getTickCount Lib "kernel32" Alias _
         "QueryPerformanceCounter" (cyTickCount As Currency) As Long
#Else
    Private Declare Function getFrequency Lib "kernel32" Alias _                                            "QueryPerformanceFrequency" (cyFrequency As Currency) As Long
    Private Declare Function getTickCount Lib "kernel32" Alias _
        "QueryPerformanceCounter" (cyTickCount As Currency) As Long
#End If
Function MicroTimer() As Double
'

' Returns seconds.
    Dim cyTicks1 As Currency
    Static cyFrequency As Currency
    '
    MicroTimer = 0

' Get frequency.
    If cyFrequency = 0 Then getFrequency cyFrequency

' Get ticks.
    getTickCount cyTicks1                            

' Seconds
    If cyFrequency Then MicroTimer = cyTicks1 / cyFrequency 
End Function

Sub RangeTimer()
    DoCalcTimer 1
End Sub
Sub SheetTimer()
    DoCalcTimer 2
End Sub
Sub RecalcTimer()
    DoCalcTimer 3
End Sub
Sub FullcalcTimer()
    DoCalcTimer 4
End Sub

Sub DoCalcTimer(jMethod As Long)
    Dim dTime As Double
    Dim dOvhd As Double
    Dim oRng As Range
    Dim oCell As Range
    Dim oArrRange As Range
    Dim sCalcType As String
    Dim lCalcSave As Long
    Dim bIterSave As Boolean
    '
    On Error GoTo Errhandl

' Initialize
    dTime = MicroTimer              

    ' Save calculation settings.
    lCalcSave = Application.Calculation
    bIterSave = Application.Iteration
    If Application.Calculation <> xlCalculationManual Then
        Application.Calculation = xlCalculationManual
    End If
    Select Case jMethod
    Case 1

        ' Switch off iteration.

        If Application.Iteration <> False Then
            Application.Iteration = False
        End if

        ' Max is used range.

        If Selection.Count > 1000 Then
            Set oRng = Intersect(Selection, Selection.Parent.UsedRange)
        Else
            Set oRng = Selection
        End If

        ' Include array cells outside selection.

        For Each oCell In oRng
            If oCell.HasArray Then
                If oArrRange Is Nothing Then 
                    Set oArrRange = oCell.CurrentArray
                End If
                If Intersect(oCell, oArrRange) Is Nothing Then
                    Set oArrRange = oCell.CurrentArray
                    Set oRng = Union(oRng, oArrRange)
                End If
            End If
        Next oCell

        sCalcType = "Calculate " & CStr(oRng.Count) & _
            " Cell(s) in Selected Range: "
    Case 2
        sCalcType = "Recalculate Sheet " & ActiveSheet.Name & ": "
    Case 3
        sCalcType = "Recalculate open workbooks: "
    Case 4
        sCalcType = "Full Calculate open workbooks: "
    End Select

' Get start time.
    dTime = MicroTimer
    Select Case jMethod
    Case 1
        If Val(Application.Version) >= 12 Then
            oRng.CalculateRowMajorOrder
        Else
            oRng.Calculate
        End If
    Case 2
        ActiveSheet.Calculate
    Case 3
        Application.Calculate
    Case 4
        Application.CalculateFull
    End Select

' Calculate duration.
    dTime = MicroTimer - dTime
    On Error GoTo 0

    dTime = Round(dTime, 5)
    MsgBox sCalcType & " " & CStr(dTime) & " Seconds", _
        vbOKOnly + vbInformation, "CalcTimer"

Finish:

    ' Restore calculation settings.
    If Application.Calculation <> lCalcSave Then
         Application.Calculation = lCalcSave
    End If
    If Application.Iteration <> bIterSave Then
         Application.Iteration = bIterSave
    End If
    Exit Sub
Errhandl:
    On Error GoTo 0
    MsgBox "Unable to Calculate " & sCalcType, _
        vbOKOnly + vbCritical, "CalcTimer"
    GoTo Finish
End Sub

Вы также можете проверить ссылки в разделе «Ссылки» для получения дополнительных предложений и методов оптимизации производительности Excel. Хотя во второй ссылке сказано:

"Обычно быстрее использовать вычисления формулы Excel и функции листа, чем использовать пользовательские функции VBA." 2

Хотя это может быть правдой, если мы говорим о самом процессе вычислений, но если вы выполняете свои вычисления в VBA, ваш вывод будет статичным. Поэтому, если вы делаете, скажем, финансовое моделирование, сценарии «что если» и т. Д., Будет болезненно ждать 15 минут для каждого изменения минут, если включен автоматический расчет, поскольку формулы активно ссылаются на ячейки, отслеживая любые изменения.

Надеюсь, это поможет ..


Ссылки

Производительность Excel: повышение производительности вычислений

Производительность Excel: Советы по оптимизации препятствий производительности

Производительность Excel: улучшения производительности и ограничения

0 голосов
/ 04 мая 2018

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

подробности см. В моем блоге: https://fastexcel.wordpress.com/2012/03/29/vlookup-tricks-why-2-vlookups-are-better-than-1-vlookup/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...