【问题标题】:Looping through two worksheet arrays in two workbooks循环遍历两个工作簿中的两个工作表数组
【发布时间】:2017-02-21 17:16:19
【问题描述】:

我正在尝试创建并循环遍历两个不同的数组,每个数组包含 20 个工作表。工作表来自两个不同的工作簿,“每月”和“每周”。

我有以下内容(经过一些建议的修改):

    Dim Monthly As Excel.Workbook
    Set Monthly = Workbooks("name of monthly workbook")
    Dim Weekly As Excel.Workbook
    Set Weekly = Workbooks.Open("path to weekly workbook")

    Dim mWshtNames As Variant
    Dim mWshtNameCrnt As Variant
    Dim wWshtNames As Variant
    Dim wWshtNameCrnt As Variant

    mWshtNames = Array(Monthly.Worksheets("Reading Monthly"), Monthly.Worksheets("Writing Monthly"), Monthly.Worksheets("Science Monthly"))
'and so on, to include 20 worksheets
    wWshtNames = Array(Weekly.Worksheets("Reading Weekly"), Weekly.Worksheets("Writing Weekly"), Weekly.Worksheets("Science Weekly"))
'and so on, to include 20 worksheets

        For Each mWshtNameCrnt In mWshtNames
            For Each wWshtNameCrnt In wWshtNames
                MsgBox "Monthly sheet is " + mWshtNameCrnt.Name
                MsgBox "Weekly sheet is " + wWshtNameCrnt.Name
                'the real code will loop here; I am using MsgBox to test that the loop is working.
            Next wWshtNameCrnt
        Next mWshtNameCrnt

代码的最终目标是从每个 Weekly 工作表中的特定单元格复制数据并将其粘贴到相应 Monthly 工作表中的相应单元格中;所以循环需要像一对一的关系。

当前结果(12 个消息框):

  • “月刊是阅读月刊”、“周刊是阅读周刊”、“周刊是每周写作”、“周刊是科学周刊”
  • “月刊是每月写作”、“周刊是每周阅读”、“周刊是每周写作”、“周刊是科学周刊”
  • “月刊是科学月刊”、“周刊是阅读周刊”、“周刊是每周写作”、“周刊是科学周刊”

预期结果(6 个消息框):

  • “月表是月读”、“周表是周读”
  • “月表是每月写作”,“周表是每周写作”
  • “月刊是科学月刊”、“周刊是科学周刊”

@Jeeped 的答案具有相同的有效结果,其中即时窗口返回 9 个结果,而预期为 6 个。我想我需要“Next wWshtNameCrnt”和“Next mWshtNameCrnt”同时激活,但不知道怎么写。

【问题讨论】:

  • 不应该 'and so on, to include 20 workbooks'and so on, to include 20 workSHEETs 吗?
  • 您应该使用For 循环来迭代数组,并使用For Each 循环来迭代对象集合。您的 cmets 表明数组包含 workbooks,但您的代码另有说明,并且数组实际上包含 worksheets。此外,您的数组正在存储 Worksheet 对象,而不仅仅是它们的名称,因此变量的名称具有误导性......并且 mWshtNameswWshtNames 很难阅读并且容易将一个误认为另一个。 monthlySheetsweeklySheets 怎么样?
  • 也就是说,我不知道你的问题是什么。
  • 好的,让我提出一些建议。放弃 lorem ipsum 的东西,给我们一些明确的信息 - 月表可以是“Jan”、“Feb”、“March”,然后每周可以是“Wk1”、“Wk2”、“Wk3”——然后你可以描述你的'期待与你得到的(在你的帖子中,而不是在 cmets 中) - 再次考虑 Jeeped's answer below,它肯定能满足你的需要。
  • FWIW,关于如何创建“还需要指定工作簿的工作表”数组的问题并没有真正意义——您的代码已经这样做了。如果您需要从Worksheet 引用返回Workbook,只需调用.Parent

标签: arrays vba excel


【解决方案1】:

所以循环需要像一对一的关系。

因此嵌套循环是行不通的。当您迭代外循环中的每个项目时,内循环迭代其所有项目每次外循环进行新迭代,借用您的表关系词汇表,这将是一个 多对多关系

如果是“一对一”,那么您只需要 1 个循环,并且您的两个数组具有相同的大小。所以创建一个从LBound(anyOfTheseArrays) To UBound(anyOfTheseArraysButPreferablyTheSameYouUseToGetTheLBound) 出发的For 循环:

Dim index As Long
For index = LBound(mWshtNames) To UBound(mWshtNames)
    Debug.Print mWshtNames(index).Name, wWshtNames(index).Name
Next

对于每个数组中的 3 个项目,这将为您提供 3 行输出到 立即 窗格 (Ctrl+G),这比 MsgBox 调用更实用,至少对于调试而言。

【讨论】:

  • 忍者让我领先了 47 秒! :D
【解决方案2】:

您似乎想循环浏览每月的工作表,并为每个工作表循环浏览每周的工作表。

Option Explicit

Sub bleh()
    Dim Monthly As Excel.Workbook, Weekly As Excel.Workbook

    Set Monthly = Workbooks("name of monthly workbook")
    Set Weekly = Workbooks.Open("path to weekly workbook")

    Dim m As Long, w As Long
    Dim mWshtNames As Variant, wWshtNames As Variant

    'define 20 monthly workSHEET names
    mWshtNames = Array("Lorem", "Ipsum", "Dolor", "sit", "amet", _
                       "consectetur", "adipiscing", "elit", "Sed", "vel", _
                       "cursus", "purus", "Vivamus", "nec", "ex", _
                       "et", "lorem", "fringilla", "consectetur", "Fusce")
    'define 20 weekly workSHEET names
    wWshtNames = Array("Pellentesque", "quis", "viverra", "lorem", "ac", _
                       "sodales", "turpis", "Morbi", "in", "vulputate", _
                       "lectus", "Donec", "aliquam", "suscipit", "nunc", _
                       "eget", "bibendum", "augue", "interdum", "porta")

        For m = LBound(mWshtNames) To UBound(mWshtNames)
            With Monthly.Worksheets(mWshtNames(m))
                Debug.Print .Name
                For w = LBound(wWshtNames) To UBound(wWshtNames)
                    With Weekly.Worksheets(wWshtNames(w))
                        Debug.Print .Name
                    End With
                Next w
            End With
        Next m

End Sub

这会遍历每个月的工作表并将其.Name property 发送到VBE 的Immediate window。当每月工作表处于“活动状态”时,它会循环遍历所有每周工作表并将其 .Name 发送到即时窗口。

虽然代码没有任何目的,但它从使用该名称的进程中调用该名称,因此至少它会验证该名称。

【讨论】:

    【解决方案3】:

    完全跳过嵌套循环。工作表通过 subject 相互对应,但只是在名称上巧合。不要在进入循环之前生成所有完整名称(和/或工作表),而是通过结合主题和工作表类型来创建 索引 并获取 Worksheet 参考 循环内:

    Dim Monthly As Excel.Workbook
    Set Monthly = Workbooks("name of monthly workbook")
    Dim Weekly As Excel.Workbook
    Set Weekly = Workbooks.Open("path to weekly workbook")
    
    Dim subjects() As String
    subjects = Split("Reading,Writing,Science", ",")
    Dim weeklySheet As Worksheet
    Dim monthlySheet As Worksheet
    
    Dim subject As String
    For Each subject In subjects
        Set weeklySheet = Weekly.Worksheets(subject & " Weekly")
        Set monthlySheet = Montly.Worksheets(subject & " Monthly")
        MsgBox "Monthly sheet is " + monthlySheet.Name
        MsgBox "Weekly sheet is " + weeklySheet.Name
        '"Real" code here.
    Next
    

    请注意,这还允许您使用强类型引用,例如 WorksheetString,而不必将所有内容都声明为 Variant

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多