【问题标题】:"Invalid procedure call or argument" error in Do-While-Loop in Excel VBA?Excel VBA 中的 Do-While-Loop 中出现“无效的过程调用或参数”错误?
【发布时间】:2017-10-18 22:33:52
【问题描述】:

为什么会有

“无效的过程调用或参数”

Excel VBA 中的此 Do-While-Loop 错误?

我似乎找不到问题,我不相信有错字。错误指向带有星号的代码行。

请注意,Worksheets("DTR").Cells(i,3) 是一个日期。

For i = 2 To Total_rows_DTR
    m = Application.Match(Worksheets("DTR").Cells(i, 3), Worksheets("Holidays Table").Range("A2:A1048576"), 0)
    If Not IsError(m) Then
        If Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3), Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "Regular" Then
            x = 1
            '** Error occurs in the following line:
            Do While Application.WorksheetFunction.Weekday(Worksheets("DTR").Cells(i, 3) - x) = 1 Or Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3)-x, Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "Regular" Or Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3)-x, Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "SNWH" And Application.WorksheetFunction.Sum(Worksheets("DTR").Range("P" & i-x & ":S" & i-x)) > 0
                x = x + 1
            Loop
            If Application.WorksheetFunction.Sum(Worksheets("DTR").Range("P" & i & ":S" & i)) = 0 Then
                Worksheets("DTR").Cells(i, 26) = 0
            End If
        End If
    End If
Next i

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    1。第一个解决方案(更新条件见 2)

    看看你的循环……

    Do While Application.WorksheetFunction.Weekday(Worksheets("DTR").Cells(i, 3) - x) = 1 _
       Or Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3), Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "Regular" _
       Or Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3), Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "SNWH" _
       And Application.WorksheetFunction.Sum(Worksheets("DTR").Range("P" & i & ":S" & i)) > 0
        x = x + 1
    Loop
    

    在你只增加x 的地方,唯一的x 取决于循环的一部分是第一个Or 之前的右边。

    Application.WorksheetFunction.Weekday(Worksheets("DTR").Cells(i, 3) - x) = 1
    'only part that depends on x
    

    因此可以在循环之前检查所有其他语句,因为它们是静态的(相对于 x)。

    因此,您的循环在每次迭代中的计算量比以前少,因为 ABC 只计算一次。我们可以这样做,因为它们不会通过迭代循环而改变。

    A = Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3), Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "Regular"
    B = Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3), Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "SNWH"
    C = Application.WorksheetFunction.Sum(Worksheets("DTR").Range("P" & i & ":S" & i)) > 0
    
    Do While Application.WorksheetFunction.Weekday(Worksheets("DTR").Cells(i, 3) - x) = 1 _
       Or A _
       Or B _
       And C
        x = x + 1
    Loop
    

    2。自从 OP 将循环代码更改为…

    Do While Application.WorksheetFunction.Weekday(Worksheets("DTR").Cells(i, 3) - x) = 1 _
        Or Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3)-x, Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "Regular" _
        Or Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3)-x, Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "SNWH" _
        And Application.WorksheetFunction.Sum(Worksheets("DTR").Range("P" & i-x & ":S" & i-x)) > 0
        x = x + 1
    Loop
    

    ...如果 4 个条件中的每一个都依赖于 x,我们可以这样做:

    Dim RunLoop As Boolean
    Do
        'we split up the conditions into A-D so if an error occurs we know in which condition
        A = Application.WorksheetFunction.Weekday(Worksheets("DTR").Cells(i, 3) - x) = 1
        B = Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3) - x, Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "Regular"
        C = Application.WorksheetFunction.Index(Worksheets("Holidays Table").Range("B2:B1048576"), Application.WorksheetFunction.Match(Worksheets("DTR").Cells(i, 3) - x, Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "SNWH"
        D = Application.WorksheetFunction.Sum(Worksheets("DTR").Range("P" & i - x & ":S" & i - x)) > 0
        'now we check all coditions
        RunLoop = A Or B Or C And D
        'and exit the loop if the condition is false
        If RunLoop = False Then Exit Do
        x = x + 1
    Loop
    

    注意:我另外建议使用Option Explicit 并正确声明每个变量。

    【讨论】:

    • 是的,这是真的。实际上我刚才纠正了它。我使它们相对于 x 是动态的。编辑了主帖很抱歉
    • 当我观察整个循环的情况时,我想知道是否会有其他人做同样的事情。通过分析,您甚至更进一步。
    • @MarcSantos 由于您对条件的编辑,我改进了答案。请注意,如果我们以这种方式拆分条件,您可以看到在哪个条件下会发生错误。这样调试起来就容易多了。
    • @Peh 谢谢你的帮助。在我修复代码的逻辑后,我会回到这个问题上。我意识到我需要 2 Do-While-Loop 来实现我的目标,但我仍在试图弄清楚如何做到这一点。
    • 我弄清楚循环失败的主要原因是Application.WorksheetFunction.Match 部分。当我将其变为动态时(例如Application.WorksheetFunction.Match(Cells(i,3)-x)),当它在指定表中找不到匹配项时,将导致程序出错。所以我相应地修复了它。只是为了更新你
    【解决方案2】:

    您的Do...Loop 太复杂了。更多信息herehere

    【讨论】:

    • 我读过它,但它没有说明我的代码由于复杂性而破坏的循环限制
    • @MarcSantos - 你是认真的吗?
    【解决方案3】:

    在循环中编写极端大的条件不被视为干净的代码。如前所述,将条件拆分为单独的布尔函数并分别评估它们。像这样:

    Public Sub TestMe()
    
        While isIt1 Or isItRegular
            'do something
        Wend
    
    End Sub
    
    Public Function isIt1() As Boolean
    
        isIt1 = Application.WorksheetFunction.Weekday(Worksheets("DTR").Cells(i, 3) - x) = 1
    
    End Function
    
    Public Function isItRegular() As Boolean
    
        With Application.WorksheetFunction
            isItRegular = .index(Worksheets("Holidays Table").Range("B2:B1048576"), .match(Worksheets("DTR").Cells(i, 3), Worksheets("Holidays Table").Range("A2:A1048576"), 0)) = "Regular"
        End With
    
    End Function
    

    【讨论】:

    • 谢谢你,我实际上不太了解这门语言,因为我开始工作才大约一个月,而且有很多语法我不知道我会尝试分解我的代码.考虑到我的时间限制,组织代码一直很痛苦
    猜你喜欢
    • 2016-07-21
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    相关资源
    最近更新 更多