在生成新工作簿的同时在单个工作簿中循环工作表

时间:2017-01-13 23:20:43

标签: excel vba excel-vba

我需要在一个工作簿中循环浏览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

2 个答案:

答案 0 :(得分: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,但仅限于我们知道的地方,活动工作表是新创建的工作簿中新复制的工作表

答案 1 :(得分:0)

您的主要错误在于Current变量在迭代worksheet集合时持有当前 Worksheets这一事实,而ActiveSheet是目前" Active"在您Activate新工作表(并且循环激活)之前,工作表并且不会更改

并且在每个ActiveSheet.Copy之后,新创建的工作簿将成为ActiveWorkbook,而其唯一的工作簿将成为ActiveSheet

因此您必须使用Current代替ActiveSheet

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

所以你可以编码:

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

最后,像上面这样的操作将为您提供与粘贴的纸张一样多的打开工作簿,而您可能希望在每次迭代时保存并关闭它们,从而使您获得原始的&#39;仅限工作簿:

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