【问题标题】:How can I reduce/compact this repetitive VBA code?如何减少/压缩这个重复的 VBA 代码?
【发布时间】:2019-07-07 03:14:26
【问题描述】:

我正在尝试学习如何减少代码的重复性。我以为我现在可以侥幸逃脱并稍后学习,但我收到了“程序太大”的错误。我知道我可以分成单独的子程序,然后编写一个调用每个子程序的子程序,但我宁愿解决问题的根源,我知道这是不必要的重复。

我了解循环的基础知识,但我不明白如何将它应用到我的代码中。这可能是因为我不了解高级逻辑,或者因为我很难发现代码中有助于我弄清楚如何编写循环的模式。

以下是一段非常非常长的代码中的两个示例。

示例 1:使用工作簿 (datafile17) 中的 COUNTIFS 将值填充到另一个工作簿/工作表 (Raw17) 的单元格中。

Dim datafile17 As Workbook
Set datafile17 = Workbooks("WorkbookName")

'First Set
 Dim EU3 As Range, EU4 As Range, EU5 As Range, EU6 As Range, EU7 As Range, EU8 As Range
    Set EU3 = Raw17.Range("F2")
    Set EU4 = Raw17.Range("F3")
    Set EU5 = Raw17.Range("F4")
    Set EU6 = Raw17.Range("F5")
    Set EU7 = Raw17.Range("F6")
    Set EU8 = Raw17.Range("F7")

    datafile17.Activate
       EU3 = Application.WorksheetFunction.CountIfs(Range("X:X"), "U", Range("C:C"), school, Range("J:J"), 3)
       EU4 = Application.WorksheetFunction.CountIfs(Range("X:X"), "U", Range("C:C"), school, Range("J:J"), 4)
       EU5 = Application.WorksheetFunction.CountIfs(Range("X:X"), "U", Range("C:C"), school, Range("J:J"), 5)
       EU6 = Application.WorksheetFunction.CountIfs(Range("X:X"), "U", Range("C:C"), school, Range("J:J"), 6)
       EU7 = Application.WorksheetFunction.CountIfs(Range("X:X"), "U", Range("C:C"), school, Range("J:J"), 7)
       EU8 = Application.WorksheetFunction.CountIfs(Range("X:X"), "U", Range("C:C"), school, Range("J:J"), 8)

'Second Set
 Dim EAB3 As Range, EAB4 As Range, EAB5 As Range, EAB6 As Range, EAB7 As Range, EAB8 As Range
    Set EAB3 = Raw17.Range("E2")
    Set EAB4 = Raw17.Range("E3")
    Set EAB5 = Raw17.Range("E4")
    Set EAB6 = Raw17.Range("E5")
    Set EAB7 = Raw17.Range("E6")
    Set EAB8 = Raw17.Range("E7")

     datafile17.Activate
       EAB3 = Application.WorksheetFunction.CountIfs(Range("X:X"), "AB", Range("C:C"), school, Range("J:J"), 3)
       EAB4 = Application.WorksheetFunction.CountIfs(Range("X:X"), "AB", Range("C:C"), school, Range("J:J"), 4)
       EAB5 = Application.WorksheetFunction.CountIfs(Range("X:X"), "AB", Range("C:C"), school, Range("J:J"), 5)
       EAB6 = Application.WorksheetFunction.CountIfs(Range("X:X"), "AB", Range("C:C"), school, Range("J:J"), 6)
       EAB7 = Application.WorksheetFunction.CountIfs(Range("X:X"), "AB", Range("C:C"), school, Range("J:J"), 7)
       EAB8 = Application.WorksheetFunction.CountIfs(Range("X:X"), "AB", Range("C:C"), school, Range("J:J"), 8)

'I have 18 more of these sets. Then I repeat the whole thing twice more with datafile18/Raw18 and datafile19/Raw19 respectively. 

示例 2:每个块循环通过另一个工作簿(data17)上的选项卡,将值粘贴到不同工作簿/工作表中的某个单元格上(概述)。

data17.Activate
'For Column D(4)
Overview.Range("B3") = Application.VLookup(fullschcode, G3.Range("A1:AA150"), 4, False)
Overview.Range("B7") = Application.VLookup(fullschcode, G4.Range("A1:AA150"), 4, False)
Overview.Range("B11") = Application.VLookup(fullschcode, G5.Range("A1:AA150"), 4, False)
Overview.Range("B15") = Application.VLookup(fullschcode, G6.Range("A1:AA150"), 4, False)
Overview.Range("B19") = Application.VLookup(fullschcode, G7.Range("A1:AA150"), 4, False)
Overview.Range("B23") = Application.VLookup(fullschcode, G8.Range("A1:AA150"), 4, False)


'For column J (10)
Overview.Range("E3") = Application.VLookup(fullschcode, G3.Range("A1:AA150"), 10, False)
Overview.Range("E7") = Application.VLookup(fullschcode, G4.Range("A1:AA150"), 10, False)
Overview.Range("E11") = Application.VLookup(fullschcode, G5.Range("A1:AA150"), 10, False)
Overview.Range("E15") = Application.VLookup(fullschcode, G6.Range("A1:AA150"), 10, False)
Overview.Range("E19") = Application.VLookup(fullschcode, G7.Range("A1:AA150"), 10, False)
Overview.Range("E23") = Application.VLookup(fullschcode, G8.Range("A1:AA150"), 10, False)

'This one has way less repetition than my first example, but I still have 8 total sets of this type.

我找到了其他一些答案,包括来自this helpful post 的最佳答案,但我仍然坚持如何将其应用于我的情况。同样,这可能是因为我没有掌握循环的高级逻辑,但我正在尝试。

其他说明:

  1. “fullschcode”和“school”是我之前分配的变量 使用输入框的代码取决于我需要数据的学校。
  2. 我通过论坛跟踪注意到,你们中的许多人可能认为使用 COUNTIFS 和 VLOOKUP 是完成某些任务的糟糕方法 任务。虽然我对改进这些功能的建议持开放态度, 我现在主要关心的是重复。我和 COUNTIFS 一起去了 VLOOKUP 功能,因为我了解它们。以前有人 向我建议我通过 Access 运行所有这些数据,并且 虽然我很欣赏这个建议并想学习,但我必须权衡 当我需要可用数据时的学习曲线。 我的部门以前使用打印的手工完成所有这些 数据透视表并手动输入数字。相比之下,我 在努力提高这些流程的效率方面做得很好。

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    这是您的第一组的一种方法:

    鉴于这些声明:

    Dim datafile17 As Workbook, datafile17WS As Worksheet
    Dim myWB As Workbook, myWS As Worksheet
    Dim I As Long
    
    Set datafile17 = Workbooks("workbookName")
    Set datafile17WS = datafile17.Worksheets("worksheetname")
    Set myWB = ThisWorkbook
    Set myWS = myWB.Worksheets("Raw17")
    

    您可以将您的第一组缩减为循环。

    'First Set
    With datafile17WS
        For I = 2 To 7
            myWS.Cells(I, 6) = Application.WorksheetFunction.CountIfs(.Range("X:X"), "U", .Range("C:C"), school, .Range("J:J"), I + 1)
        Next I
    End With
    

    请注意,正如已经多次提到的,不需要Activate 方法。

    【讨论】:

    • 我觉得自己很愚蠢,在数学上自卑。我从来没有想过 i 的值只是一个数字,因此可以根据需要在工作簿中循环遍历两组整数,即使它们具有不同的起点或模式。那么,有没有一种合乎逻辑的方法来循环遍历不连续的数字?当我查看其他循环示例时,我对 i 感到不知所措,但也许我现在会更好地掌握。至于Activate,我在一个帖子上看到了它,并认为它适用于我。是否总是更喜欢使用 With 来代替?
    • 哦,还有一个稍微不相关的问题,可能需要删除,但我想我会试着问一下。为什么在您的示例(以及大多数其他示例)中,您同时声明了工作簿和工作表,而不是仅仅声明工作表?例如,如果工作簿只有一张工作表,为什么不直接声明工作表?
    • @Kat 搜索关于避免使用SelectActivate 的SO 文章。在我看来,Workbook 声明是可选的。但是,如果您可能指的是多个工作簿,它可能会很方便。您当然可以将工作表定义为ThisWorkbook.Worksheets("sheetName"),其中包括工作簿参考。同样,如果您可能指的是另一个工作表(可能随着项目的扩展),声明工作簿可能会很方便。
    • @Kat 对于非连续数字,有很多方法取决于 non-consecutive 值的性质以及您正在尝试做的事情。查看Step 关键字的一种用途。对于完全随机的值,您始终可以将它们存储在数组中,然后逐步遍历数组。
    猜你喜欢
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多