Sub SplitDataAndSaveToNewWorkbooks()
    Dim lastRow As Long
    Dim curRow As Long
    Dim sheetName As String
    Dim newWorkbook As Workbook
    Dim savePath As String
'On Error Resume Next '当代码运行错误时忽略,继续向下运行


    ' 清除上一次运行拆分的子表内容
    Application.DisplayAlerts = False
    For Each subTable In ThisWorkbook.Worksheets
    If subTable.Name <> 'data' And subTable.Name <> 'How to operate' Then
        subTable.Cells.Clear
        Application.DisplayAlerts = False
        subTable.Delete
        Application.DisplayAlerts = True
    End If
    Next subTable
    Application.DisplayAlerts = True


    '获取保存路径,这里为源数据表所在路径下的一个子文件夹'SubTables'
    savePath = ThisWorkbook.path & '\SubTables\'
    If Dir(savePath, vbDirectory) = '' Then
        MkDir savePath
    End If

    With Worksheets('data') '修改为你的数据所在的Sheet名称
        lastRow = .Cells(.Rows.Count, 'A').End(xlUp).Row '修改为你的数据所在的列
        For curRow = 2 To lastRow '从第二行开始循环,第一行是标题
            sheetName = .Cells(curRow, 'X').Value '以第X列作为分割列
            If Not SheetExists(sheetName) Then ' SheetExists 函数用来判断是否存在同名的Sheet
                Worksheets.Add After:=Worksheets(Worksheets.Count) '添加新的Sheet
                ActiveSheet.Name = sheetName '以分割列的值命名新的Sheet
            End If
            .Rows(1).Copy Destination:=Worksheets(sheetName).Rows(1)
            .Rows(curRow).Copy Destination:=Worksheets(sheetName).Rows(Worksheets(sheetName).Cells(Worksheets(sheetName).Rows.Count, 'X').End(xlUp).Row + 1) '拷贝当前行到对应的Sheet
            Worksheets(sheetName).Columns.AutoFit '自适应单元格宽度
        Next
    End With
    
    For Each subTable In ThisWorkbook.Worksheets
        If subTable.Name <> 'data' Then
        '判断是否为由'data'表拆分得到的子表
            Dim isSubTable As Boolean
                isSubTable = False
            For curRow = 2 To lastRow
            If subTable.Name = Worksheets('data').Cells(curRow, 'X').Value Then
                isSubTable = True
            Exit For
            End If
         Next curRow
        '如果是'data'表拆分得到的子表,则保存到SubTables文件夹
         If isSubTable Then
        '拼接文件完整路径和文件名
         Dim filePath As String
            filePath = savePath & subTable.Name & '.xlsx'
        '如果文件已经存在,则删除旧文件
        If Dir(filePath) <> '' Then
            Kill filePath
        End If
        
        Set newWorkbook = Workbooks.Add
        subTable.UsedRange.Copy newWorkbook.Worksheets(1).UsedRange
        newWorkbook.Worksheets(1).Columns.AutoFit '自适应单元格宽度
        newWorkbook.SaveAs filePath
        newWorkbook.Close SaveChanges:=False
        End If
    End If
    Next subTable

    Worksheets('How to operate').Activate
    MsgBox 'The data has been split and saved to SubTables.'
    
End Sub

Function SheetExists(shtName As String) As Boolean
    '判断Sheet是否存在
    SheetExists = False
    For Each sht In ThisWorkbook.Sheets
        If sht.Name = shtName Then
            SheetExists = True
            Exit Function
        End If
    Next sht
End Function

代码说明:

  1. 清除上一次运行拆分的子表内容: 循环遍历工作簿中的所有工作表,如果工作表名称不为'data'或'How to operate',则清空工作表内容并删除工作表。
  2. 获取保存路径: 获取源数据表所在的路径,并在该路径下创建一个名为'SubTables'的文件夹,用于保存拆分后的工作簿。
  3. 循环拆分数据: 循环遍历源数据表'data'中的每行数据,将第X列的值作为新工作表的名称。
  4. 创建新工作表: 如果新工作表的名称不存在,则创建一个新的工作表并以第X列的值命名。
  5. 复制数据到新工作表: 将源数据表的第一行复制到新工作表的首行,将当前行数据复制到新工作表的最后一行。
  6. 自适应单元格宽度: 自动调整新工作表中所有列的宽度,以适应数据内容。
  7. 保存工作簿: 将所有拆分后的工作簿保存到'SubTables'文件夹下,文件名与工作表名称相同。
  8. 错误处理: 使用'SheetExists'函数判断工作表名称是否已存在,防止重复创建工作表。

代码运行中断问题分析及解决方法:

错误提示'此名称已被使用'可能出现的原因:

  • 源数据表中的分割列(第X列)的值不唯一,导致创建重复的工作表名称。

解决方法:

  1. 确保分割列的值是唯一的。
  2. 如果无法保证分割列的值唯一,可以在创建工作表名称时添加一个唯一的标识符,例如序号或时间戳。

修改后的代码:

Sub SplitDataAndSaveToNewWorkbooks()
    Dim lastRow As Long
    Dim curRow As Long
    Dim sheetName As String
    Dim newWorkbook As Workbook
    Dim savePath As String
    Dim i As Integer

    ' 清除上一次运行拆分的子表内容
    Application.DisplayAlerts = False
    For Each subTable In ThisWorkbook.Worksheets
        If subTable.Name <> 'data' And subTable.Name <> 'How to operate' Then
            subTable.Cells.Clear
            Application.DisplayAlerts = False
            subTable.Delete
            Application.DisplayAlerts = True
        End If
    Next subTable
    Application.DisplayAlerts = True

    '获取保存路径
    savePath = ThisWorkbook.path & '\SubTables\'
    If Dir(savePath, vbDirectory) = '' Then
        MkDir savePath
    End If

    With Worksheets('data')
        lastRow = .Cells(.Rows.Count, 'A').End(xlUp).Row
        For curRow = 2 To lastRow
            sheetName = .Cells(curRow, 'X').Value
            i = 1
            Do While SheetExists(sheetName)
                sheetName = .Cells(curRow, 'X').Value & '_' & i
                i = i + 1
            Loop
            Worksheets.Add After:=Worksheets(Worksheets.Count)
            ActiveSheet.Name = sheetName
            .Rows(1).Copy Destination:=Worksheets(sheetName).Rows(1)
            .Rows(curRow).Copy Destination:=Worksheets(sheetName).Rows(Worksheets(sheetName).Cells(Worksheets(sheetName).Rows.Count, 'X').End(xlUp).Row + 1)
            Worksheets(sheetName).Columns.AutoFit
        Next
    End With

    ' 保存数据到新工作簿
    For Each subTable In ThisWorkbook.Worksheets
        If subTable.Name <> 'data' Then
            Dim isSubTable As Boolean
            isSubTable = False
            For curRow = 2 To lastRow
                If subTable.Name = Worksheets('data').Cells(curRow, 'X').Value Then
                    isSubTable = True
                    Exit For
                End If
            Next curRow
            If isSubTable Then
                Dim filePath As String
                filePath = savePath & subTable.Name & '.xlsx'
                If Dir(filePath) <> '' Then
                    Kill filePath
                End If
                Set newWorkbook = Workbooks.Add
                subTable.UsedRange.Copy newWorkbook.Worksheets(1).UsedRange
                newWorkbook.Worksheets(1).Columns.AutoFit
                newWorkbook.SaveAs filePath
                newWorkbook.Close SaveChanges:=False
            End If
        End If
    Next subTable

    Worksheets('How to operate').Activate
    MsgBox 'The data has been split and saved to SubTables.'
End Sub

Function SheetExists(shtName As String) As Boolean
    SheetExists = False
    For Each sht In ThisWorkbook.Sheets
        If sht.Name = shtName Then
            SheetExists = True
            Exit Function
        End If
    Next sht
End Function

修改说明:

  • 在创建新的工作表名称之前,添加了一个循环判断,如果名称已存在,则在名称后面添加一个序号,直到名称不重复为止。
  • 确保每次循环中都创建新的工作表名称,即使遇到重复的分割列值。
Excel VBA: 拆分数据并保存到新工作簿

原文地址: https://www.cveoy.top/t/topic/p3ah 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录