【问题标题】:Need a VBA code to convert Excel sheet columns into tab in new Excel sheet需要 VBA 代码将 Excel 工作表列转换为新 Excel 工作表中的选项卡
【发布时间】:2017-05-12 17:58:03
【问题描述】:

我有一个包含 3000 列的 Excel 工作表,我需要转换此工作表,使一个选项卡仅包含 254 列,其余的将转到下一个选项卡。所以我需要一个可以执行相同功能的 VBA 代码(宏)。

到目前为止,我只编写了以下代码,它创建了 3000 个选项卡,每个选项卡有一列,而且由于我没有为空白列设置任何条件,所以它也将进入无限循环。

Sub SpliteIntoMultipleTab()
    '
    ' createtemplates Macro
    Dim WS As Worksheet
    Dim SS As Worksheet
    Dim TemplateName As String
    Dim tempstr As String
    '
    Dim CurCol As String
    Dim Template As String
    Dim xColIndex As Integer
    Dim xRowIndex As Integer
    Dim WSCount As Integer
    '==========================================================================
    'Declarations
    CurCol = 1
    Template = "Sheet1"
    '==========================================================================
    Set SS = Worksheets(Template)
    If WS Is Nothing Then

Start:

    With ActiveWorkbook
        Set WS = .Sheets.Add(After:=ActiveSheet)
        WSCount = Sheets.Add(After:=Sheets(Worksheets.Count))
        On Error Resume Next
        Set WS = Worksheets("temp")
        WS.Name = SS.Range("A1").Value
      End With
    Else
    End If

    SS.Activate
    xIndex = Application.ActiveCell.Column
    xRowIndex = Application.ActiveSheet.Cells(Rows.Count, xIndex).End(xlUp).Row
    Range(Cells(1, xIndex), Cells(xRowIndex, xIndex)).Select
    Selection.Copy
    WS.Select
    WS.Range("A1").Select
    ActiveSheet.Paste
    SS.Columns(1).EntireColumn.Delete
    CurCol = CurCol + 1
    GoTo Start
End Sub

【问题讨论】:

  • 你拥有的和你想要的有什么区别?

标签: sql-server vba excel macros


【解决方案1】:

使用整数除法和取模,例如取第 1000 列

1000 \ 254 = 3 

1000 mod 254 = 238 

给出第 3 页和第 238 列。

所以使用 \mod 从 1 循环到 3000。

您的代码非常不标准,我无法理解它,我建议您从我的代码开始,这是一个将数据块分成单独工作表的说明性示例。然后将代码复制到新工作簿中

只运行一次CreateSheetAndPopulateWithBlockOfData 以创建一个数据块。 运行 Test 运行 BreakBlockIntoChunks 例程,您可以试验块大小。

Option Explicit

Private Const csSHEETNAME As String = "Source"

Sub TestCreateSheetAndPopualteWithBlockOfData()

    Dim wsSource As Excel.Worksheet
    Set wsSource = CreateSheetAndPopulateWithBlockOfData(ThisWorkbook, csSHEETNAME, 20, 100)

End Sub

Sub Test()
    Dim wsSource As Excel.Worksheet
    Set wsSource = ThisWorkbook.Worksheets.Item(csSHEETNAME)


    'Stop
    Dim wbResults As Excel.Workbook
    Set wbResults = Workbooks.Add
    BreakBlockIntoChunks wsSource, 5, wbResults
End Sub

Function BreakBlockIntoChunks(ByVal wsSource As Excel.Worksheet, ByVal lColumnChunkSize As Long, ByVal wbDestinationWorkbook As Excel.Workbook)

    Dim rngDataBlock As Excel.Range
    Set rngDataBlock = wsSource.Cells(1, 1).CurrentRegion

    Dim lSourceColumnCount As Long
    lSourceColumnCount = rngDataBlock.Columns.Count

    Dim lSourceRowCount As Long
    lSourceRowCount = rngDataBlock.Rows.Count

    Dim lColumnLoop As Long
    For lColumnLoop = 1 To lSourceColumnCount

        Dim lCurrentSheet As Long
        lCurrentSheet = ((lColumnLoop - 1) \ lColumnChunkSize) + 1

        Dim wsCurrentSheet As Excel.Worksheet

        If lCurrentSheet > wbDestinationWorkbook.Worksheets.Count Then Set wsCurrentSheet = wbDestinationWorkbook.Worksheets.Add

        If wsCurrentSheet Is Nothing Then Set wsCurrentSheet = wbDestinationWorkbook.Worksheets.Item(lCurrentSheet) '* runs first loop


        '**ADD your sheet naming logic here perhaps

        Dim lCurrentColumn As Long
        lCurrentColumn = ((lColumnLoop - 1) Mod lColumnChunkSize) + 1


        Dim rngSource As Excel.Range
        Set rngSource = wsSource.Range(wsSource.Cells(1, lColumnLoop), wsSource.Cells(lSourceRowCount, lColumnLoop))

        Dim rngDestination As Excel.Range
        Set rngDestination = wsCurrentSheet.Range(wsCurrentSheet.Cells(1, lCurrentColumn), wsCurrentSheet.Cells(lSourceRowCount, lCurrentColumn))

        rngDestination.Value2 = rngSource.Value2 '* <---Copies without using clipboard



    Next lColumnLoop



End Function

Function CreateSheetAndPopulateWithBlockOfData(ByVal wb As Excel.Workbook, ByVal sSheetName As String, ByVal lRowsDeep As Long, ByVal lColumnsWide As Long) As Excel.Worksheet

    Dim ws As Excel.Worksheet
    Set ws = wb.Worksheets.Add
    ws.Name = sSheetName

    Dim rngBlock As Excel.Range
    Set rngBlock = ws.Range(ws.Cells(1, 1), ws.Cells(lRowsDeep, lColumnsWide))

    rngBlock.Formula = "=RANDBETWEEN(1,100000)"
    rngBlock.Value2 = rngBlock.Value2

    Set CreateSheetAndPopulateWithBlockOfData = ws
End Function

【讨论】:

  • 我是 VBA 新手,所以不太了解。你能详细说明一下吗?谢谢。
  • @Mohit:如果不是 VBA,你还知道哪些编程语言?
  • 我正在用 MSSQL 编写存储过程。
【解决方案2】:

你可以试试这个:

Sub SpliteIntoMultipleTab()
    Dim colNum As Long, iCol As Long
    With Worksheets("Sheet1").UsedRange
        colNum = .Columns.count
        Do
            Worksheets.Add(After:=Worksheets(Worksheets.count)).Range("A1:IT1").Resize(.Rows.count).Value = .Columns(iCol + 1).Resize(, 254).Value
            iCol = iCol + 254
            colNum = colNum - 254
        Loop While colNum > 0
    End With
End Sub

它只复制并大大加快速度

【讨论】:

  • 是的!它工作正常,但需要一些更正,因为我们有 3000 列,所以一个选项卡包含 254 列,所以它应该创建大约 12 个选项卡,然后它应该停止,但它会进入无限循环并且转换正在进行中。谢谢。
  • 当我测试它工作正常时:它在将所有列复制到 254 列选项卡(但最后一个列较少)后停止。您可以单步执行您的代码,看看发生了什么以及为什么 colNum 没有低于零
  • @MohitVijay 你通过了吗?
  • 我试过了,但它仍然会循环,在 64 个标签后它会因错误而停止。我的数据文件有 2597 列,理想情况下它应该在 11 个选项卡后停止,但它会转到 64 个选项卡,然后停止并出现错误。
  • 它给出了以下错误。运行时错误“1004”:应用程序定义的或对象定义的错误。在这条线上。 Worksheets.Add(After:=Worksheets(Worksheets.Count)).Range("A1:IT1").Resize(.Rows.Count).Value = .Columns(iCol + 1).Resize(, 254).Value
猜你喜欢
  • 2021-09-01
  • 1970-01-01
  • 2021-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多