【问题标题】:Looping through worksheets in a single workbook while generating new workbooks在生成新工作簿时循环浏览单个工作簿中的工作表
【发布时间】:2017-01-13 23:20:43
【问题描述】:

我需要在一个工作簿中循环浏览 47 个不同的工作表。

在每个工作表上运行的宏正在为该工作表创建一个新的单独工作簿。我的挑战是,一旦将原始工作簿中的工作表转换为新工作簿,我的宏现在开始循环遍历新工作簿上的工作表而不是原始工作表。我一直在尝试找出某种代码来计算原始工作簿上的每个工作表,然后在创建新工作簿后循环回原始工作簿。

Sub PriceListWest()
'
' PriceListWest Macro
'

Dim Current As Worksheet

Windows("West price list master.xlsm").Activate 'Original workbook'

For Each Current In Worksheets

    ActiveSheet.Select 'Selecting worksheet in original workbook'
    ActiveSheet.Copy 'Copying worksheet in original workbook'

    'Challenge lies here now the loop goes through the new workbook versus returning to original workbook'

    Cells.Select 
    Selection.Copy
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
      :=False, Transpose:=False
    Application.CutCopyMode = False
    Selection.EntireColumn.Hidden = False

Next

End Sub

【问题讨论】:

  • 您在哪里更改工作簿?获取对您的对象的引用并使用 那些 而不是使用全局变量、激活和选择。
  • 复制工作簿后,您要在原始工作簿中做什么?
  • ActiveSheet.Select ActiveSheet.Copy 更改为 Current.Copy 将解决您的问题,但我添加了一个更好的答案。

标签: vba excel


【解决方案1】:

使用SelectActivate 是一个坏习惯,除非您不时准确地跟踪哪个工作表/单元格处于活动状态。请参阅How to avoid using Select,了解如何避免这些命令的提示。

假设您现有的代码成功处理了第一个工作表,当它开始处理第二个工作表时,ActiveSheet 仍然是第一个工作表的最近创建的副本。这样该工作表就会被复制到另一个工作簿,而不是从原始工作簿中复制其中一个工作表。

以下代码使用对原始工作簿的引用,以及对您的代码已经创建的 Current 对象的引用,以确保引用正确的工作表:

Sub PriceListWest()
'
' PriceListWest Macro
'
    Dim wbMaster As Workbook
    Dim Current As Worksheet

    'Set a reference to the original workbook
    Set wbMaster = Workbooks("West price list master.xlsm")
    'Loop through each sheet in original workbook
    For Each Current In wbMaster.Worksheets
        'Copy the "current" sheet to a new workbook
        Current.Copy
        'The "Copy" command has now made the new workbook active, and
        ' "ActiveSheet" is the newly created sheet in that workbook

        With ActiveSheet
            'Copy entire sheet
            .Cells.Copy
            'Paste values
            .Cells.PasteSpecial Paste:=xlPasteValues, _
                                Operation:=xlNone, _
                                SkipBlanks:=False, _
                                Transpose:=False
            'Unhide all columns
            .Columns.Hidden = False
            'Set "active" cell to A1, just so the whole sheet isn't selected
            .Cells(1, 1).Select
        End With
    Next
    Application.CutCopyMode = False
End Sub

代码确实继续使用ActiveSheet,但仅在我们知道活动工作表是新创建的工作簿中新复制的工作表的地方。

【讨论】:

  • 感谢您的回复和文章......仍然有一些问题,因为我收到以下运行时错误“对象'_Worksheet'的方法'复制'失败”......来自以下行 Current.Copy
  • @user7410879 - 你有一些隐藏的工作表吗? (我以为您没有,因为您在原始代码中使用了 Copy 方法,但如果您这样做了,则需要更改代码以不尝试复制这些工作表。)
  • 啊,谢谢!我使用“If Current.Visible = True Then”这解决了我的问题
【解决方案2】:

您的主要错误在于您的Current 变量在迭代Worksheets 集合时保存了当前 worksheet,而ActiveSheet 是当前“活动”工作表并且没有'直到你 Activate 一个新的工作表才改变(并且循环不会激活

在每个ActiveSheet.Copy 之后,新创建的工作簿变为ActiveWorkbook,其唯一的工作表为ActiveSheet

所以你必须使用Current 而不是ActiveSheet

此外,对工作表的所有 Cells 进行操作非常耗时,并且可能会引发内存问题:最好参考 Worksheet 对象的 UsedRange 属性

所以你可以编码:

Option Explicit

Sub PriceListWest()
    '
    ' PriceListWest Macro
    '
    Dim Current As Worksheet

    For Each Current In Workbooks("West price list master").Worksheets
        Current.Copy '<--| copy current worksheet from 'original' workbook into a new workbook, this latter becomes the "active" workbook and it's only sheet the "Active" Sheet
        With ActiveSheet.UsedRange '<--| reference "Active" worksheet of current "Active" Workbook
            .value = .value
            .EntireColumn.Hidden = False
        End With
    Next
End Sub

最后,如上所示,打开的工作簿与粘贴的工作簿一样多,而您可能希望在每次迭代时保存并关闭它们,从而只留下“原始”工作簿:

Option Explicit

Sub PriceListWest()
    '
    ' PriceListWest Macro
    '
    Dim Current As Worksheet

    For Each Current In Workbooks("West price list master").Worksheets
        Current.Copy '<--| copy current worksheet from 'original' workbook into a new workbook, this latter becomes the "active" workbook and it's only sheet the "Active" Sheet
        With ActiveSheet.UsedRange '<--| reference "Active" worksheet of current "Active" Workbook
            .value = .value
            .EntireColumn.Hidden = False
        End With
        ActiveWorkbook.SaveAs filepathandname '<-- save current workbook
        ActiveWorkbook.Close '<--| close it
    Next
End Sub

【讨论】:

    猜你喜欢
    • 2014-12-23
    • 1970-01-01
    • 2014-09-15
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 2018-01-04
    • 2020-07-08
    • 2020-05-23
    相关资源
    最近更新 更多