【问题标题】:Slow vlookup and countifs慢速查找和计数
【发布时间】:2017-11-15 13:39:44
【问题描述】:

我试图用我有多少寄存器的计数填满一张表,有相同的日期、星期和小时,并且该计数除以我可以找到同一周的年数。

我已经在 VBA 中完成了这段代码,但它真的很慢,所以如果你能帮助我改进这个解决方案,我将非常感激。

    Sub formulacion()
    Dim a As Integer
    Dim b As Integer
    Dim years As Integer
    Dim rango_semana As Range
    Dim rango_dia As Range
    Dim rango_hora As Range
    Dim rango_sede As Range
    Dim rango_busqueda As Range



    a = 2
    For a = 2 To 319
        If Sheets("Dinamicos").Cells(5, a) <> "" Then
        b = 6
            For b = 6 To 20

            semana = Sheets("Dinamicos").Cells(3, a)
            dia = Sheets("Dinamicos").Cells(5, a)
            hora = Sheets("Dinamicos").Cells(b, 1)
            sede = Sheets("Dinamicos").Cells(4, 1)
            LastRow = Sheets("Base").Cells(Sheets("Base").Rows.Count, "A").End(xlUp).Row
            Set rango_semana = Sheets("Base").Range("AK2:AK" & LastRow)
            Set rango_dia = Sheets("Base").Range("AG2:AG" & LastRow)
            Set rango_hora = Sheets("Base").Range("AJ2:AJ" & LastRow)
            Set rango_sede = Sheets("Base").Range("J2:J" & LastRow)
            Set rango_busqueda = Sheets("Base").Range("AK2:AN" & LastRow)

            lookupvalue = Application.VLookup(semana, rango_busqueda, 4, False)
               If IsError(lookupvalue) Then
               years = 1
              'Si lo encuentra lo devuelve
               Else
               years = lookupvalue
               End If

            Sheets("Dinamicos").Cells(b, a) = (WorksheetFunction.CountIfs(rango_semana, semana, rango_dia, dia, rango_hora, hora, rango_sede, sede)) / years

            Next b
        End If
        b = 6
  Next a


  End Sub

【问题讨论】:

  • 如果代码有效并且您只需要帮助改进代码,那么这对于本网站来说过于宽泛,应该在codereview.stackexchange.com
  • 1.您可以从设置 For .. Next 循环之外的所有范围开始。似乎没有必要为循环的每次迭代不断地设置和重置它们。 2.application.match比vlookup快。

标签: vba performance excel processing-efficiency


【解决方案1】:

一些 var 赋值在嵌套的 For ... Next 循环迭代中发生变化;其他人没有。不要一直重新分配不变的变量。

Application.Match 比 Application.Vlookup 快。

在循环和嵌套循环中使用a 和b 中的值之前,您不必设置和重置它们。它们在进入循环时被分配它们的起始值。

lastRow = Worksheets("Base").Cells(Worksheets("Base").Rows.Count, "A").End(xlUp).Row
Set rango_semana = Worksheets("Base").Range("AK2:AK" & lastRow)
Set rango_dia = Worksheets("Base").Range("AG2:AG" & lastRow)
Set rango_hora = Worksheets("Base").Range("AJ2:AJ" & lastRow)
Set rango_sede = Worksheets("Base").Range("J2:J" & lastRow)
Set rango_busqueda = Worksheets("Base").Range("AK2:AN" & lastRow)
sede = Worksheets("Dinamicos").Cells(4, 1)

For a = 2 To 319
    If Worksheets("Dinamicos").Cells(5, a) <> "" Then
        semana = Worksheets("Dinamicos").Cells(3, a)
        dia = Worksheets("Dinamicos").Cells(5, a)

        For b = 6 To 20

            hora = Sheets("Dinamicos").Cells(b, 1)

            lookupvalue = Application.Match(semana, rango_busqueda.Columns(1), False)
            If IsError(lookupvalue) Then
               years = 1
              'Si lo encuentra lo devuelve
            Else
               years = rango_busqueda.Cells(lookupvalue, 4).Value2
            End If

            Worksheets("Dinamicos").Cells(b, a) = (WorksheetFunction.CountIfs(rango_semana, semana, rango_dia, dia, rango_hora, hora, rango_sede, sede)) / years

        Next b
    End If
Next a

最后,请记住,Sheets 与 Worksheets 不同。

【讨论】:

    猜你喜欢
    • 2011-11-24
    • 2012-03-14
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 2014-08-01
    • 1970-01-01
    相关资源
    最近更新 更多