当前位置: 首页 > 知识库问答 >
问题:

为Excel VBA中的每一行创建一个新的工作簿

华升
2023-03-14

如图所示,我有原始数据(A2:C6),我想根据B列中的每个唯一值创建一个新工作簿。在该示例中,“颜色”列中有4种颜色和3种唯一颜色,因此我将创建3个不同的新工作簿(Red.xlsx、Yellow.xlsx和Orange.xlsx),如图底部所示。

所以我想到的代码如下,但不确定如何检查工作簿是否已经创建:

Sub Move()

lr = [a1].CurrentRegion.Rows.Count
For each color in Range("B3:B" & lr)
Workbooks.Add.SaveAs FileName:= color

Workbooks("raw.xlsx").Activate
With [a1].CurrentRegion
.AutoFilter 2, color
.Copy Workbooks(color).Sheets(1).[a1]
.AutoFilter
End With

Workbooks(color).Close True

Next color

End Sub

我的代码的问题是,它会创建重复的工作簿,如红色。在本例中,xlsx两次。对于如何解决问题或采用完全不同的方法来实现相同的结果,我们将不胜感激!

共有2个答案

宗政天逸
2023-03-14
Option Explicit

Sub BackupToWorkbooks()
    
    Const dPath As String = "C:\Test"
    Const sName As String = "Sheet1"
    Const sFirst As String = "A1"
    Const sfRow As Long = 2 ' Header Row
    Const scCol As Long = 2 ' Color Column
    
    Dim swb As Workbook: Set swb = ThisWorkbook
    Dim sws As Worksheet: Set sws = swb.Worksheets(sName)
    Dim rg As Range: Set rg = sws.Range(sFirst).CurrentRegion
    Dim strg As Range
    Set strg = rg.Resize(rg.Rows.Count - sfRow + 1).Offset(sfRow - 1)
    Dim sdrg As Range: Set sdrg = strg.Resize(strg.Rows.Count - 1).Offset(1)
    Dim scrg As Range: Set scrg = sdrg.Columns(scCol)
    
    Dim cData As Variant: cData = ArrUniqueColumnRange(scrg)
    Dim tAddress As String: tAddress = strg.Address
    Dim cAddress As String: cAddress = scrg.Address

    Application.ScreenUpdating = False
    
    Dim dwb As Workbook
    Dim dws As Worksheet
    Dim dtrg As Range
    Dim dcrg As Range
    Dim drg As Range
    Dim n As Long
    Dim dName As String
    For n = 0 To UBound(cData)
        sws.Copy
        Set dwb = ActiveWorkbook
        Set dws = dwb.Worksheets(1)
        Set dtrg = dws.Range(tAddress)
        dName = cData(n)
        dtrg.AutoFilter scCol, "<>" & dName
        If Application.Subtotal(103, dtrg.Columns(scCol)) > 1 Then
            Set dcrg = dws.Range(cAddress)
            Set drg = dcrg.SpecialCells(xlCellTypeVisible).EntireRow
            drg.Delete
        End If
        dws.AutoFilterMode = False
        Application.DisplayAlerts = False
        dwb.SaveAs dPath & "\" & dName & ".xlsx", xlOpenXMLWorkbook
        Application.DisplayAlerts = True
        dwb.Close SaveChanges:=False
    Next n

    Application.ScreenUpdating = True

    MsgBox "Color worksheets backed up.", vbInformation, "Backup To Workbooks"

End Sub


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose:      Returns the unique values from the first column of a range,
'               in an array.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function ArrUniqueColumnRange( _
    ByVal rg As Range) _
As Variant
    If rg Is Nothing Then Exit Function
    
    Dim Data As Variant
    Dim rCount As Long
    
    With rg.Columns(1)
        rCount = .Rows.Count
        If rCount = 1 Then
            ReDim Data(1 To 1, 1 To 1): Data(1, 1) = .Value
        Else
            Data = .Value
        End If
    End With
    
    With CreateObject("Scripting.Dictionary")
        .CompareMode = vbTextCompare
        Dim Key As Variant
        Dim r As Long
        For r = 1 To rCount
            Key = Data(r, 1)
            If Not IsError(Key) Then
                If Len(Key) > 0 Then
                    .Item(Key) = Empty
                End If
            End If
        Next r
        If .Count = 0 Then Exit Function ' only error values and/or blanks
        ArrUniqueColumnRange = .Keys
    End With

End Function
和和裕
2023-03-14

您可以使用检查文件是否存在

DIR("path\to\file.ext")

DIR如果存在,则返回TRUE;如果不存在,则返回FALSE。

您还可以使用UniQUE消重结果:

For each c in Application.Unique(Range("B3:B" & lr))
    Debug.Print c
    Next

我在这里使用了c,因为Color已被Excel使用。我的VBA抛出了错误,但即使您的没有,您也应该避免使用在语言中已经有含义的变量名。

 类似资料:
  • 我正在尝试使用一个包含多行数据的Excel工作表,并使用行中的一个值作为新工作簿名称为每一行创建单独的工作簿。这些工作簿将保存为逗号分隔的工作簿,以便它们可以上传到机器的控制器中。我可以手动打开一个新工作簿并从基本工作簿中获取单元格的外部引用,但对如何编写循环以使其自动在行中移动并创建新工作簿以及如何使用其中一个值作为新工作簿的名称感到困惑。 基本工作簿的结构是从A到J的行,其中A列包含我要将新工

  • 我正在处理一个Excel工作簿,我希望工作簿为每一行新数据创建一个新工作表。下面的代码确实可以做到这一点,但问题是Excel使用每一行第一列中的文本作为新工作表的名称。我想更改它并使另一列成为新工作表名称的来源。请告知我需要更改哪一行才能完成此操作。谢谢您的帮助!

  • 我有以下代码,可以很好地将相关数据复制到我的工作表中。我为J列中的每个唯一部门手动创建每个工作表,然后运行此宏。我想要一个基于J列中的唯一值动态创建工作表的宏。我在网上找到了很好的资源,但当它到达已经为其创建了工作表的行时,我发现的资源似乎会出错。在手动创建其他工作表之前,我包含了我当前使用的代码以及我的清单表的屏幕截图

  • 我正在尝试为Excel文件中的每一行创建一个单独的XML文档。第1行列出了标记名,A列标识了每行的文档标题。 我在VBA方面相当缺乏经验,但这正是我迄今为止根据对类似问题的多个答案得出的结论。 我还没有完成“GetElementsByTagName”部分,因为该部分导致了问题。对于下一行,我得到错误“Object variable or With block variable not set”。

  • 数据 第一页用于数据输入。每行代表一张服务票。每列将表示有关服务事件的数据,如序列号或型号。 期望的结果 对于包含特定字段(列a ~“票证号”)中数据的每一行,Excel将基于模板创建一个新的工作表(服务票证),并将相应行中的数据放入指定的单元格中。 提前感谢您提供的任何帮助。

  • 我正在尝试自动创建报告。我有一个名称位于a列的工作簿。我正在尝试编写一个宏,该宏扫描a列,对于a列中的每个唯一名称,我希望该宏创建一个新工作簿,并将与该名称匹配的每一行数据复制到新工作簿的第二页。我还试图使用一个模板作为第一页。每个名称的模板都是相同的,因此不是唯一的。基本上,宏将扫描A列,并为每个唯一的名称创建一个工作簿,其中包含第二页上的相应数据,第一页将是一个模板,其中包含引用第二页的公式,