【问题标题】:Generate new worksheet based on column data for LARGE spreadsheets根据 LARGE 电子表格的列数据生成新工作表
【发布时间】:2016-10-20 23:32:17
【问题描述】:

我有一个包含 80 万行和 150 列的电子表格。我正在尝试根据列的内容创建新的工作表。因此,例如,如果 Y 列有很多元素(“alpha”、“beta”、“gamma”等),那么我想创建名为“alpha”、“beta”、“gamma”的新工作表,其中仅包含原始行中具有这些相应字母的行。我找到了两个适用于较小电子表格的脚本,但由于这个特定电子表格的大小,它们不起作用

这是我尝试过的两个脚本:

Sub parse_data()
Dim lr As Long
Dim ws As Worksheet
Dim vcol, i As Integer
Dim icol As Long
Dim myarr As Variant
Dim title As String
Dim titlerow As Integer
vcol = 1       
Set ws = Sheets("Sheet1")       
lr = ws.Cells(ws.Rows.Count, vcol).End(xlUp).Row
title = "A1:C1"           
titlerow = ws.Range(title).Cells(1).Row
icol = ws.Columns.Count
ws.Cells(1, icol) = "Unique"
For i = 2 To lr
    On Error Resume Next
    If ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(ws.Cells(i, vcol), ws.Columns(icol), 0) = 0 Then
        ws.Cells(ws.Rows.Count, icol).End(xlUp).Offset(1) = ws.Cells(i, vcol)
    End If
Next
myarr = Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
ws.Columns(icol).Clear
For i = 2 To UBound(myarr)
    ws.Range(title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
    If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
        Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = myarr(i) & ""
    Else
        Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
    End If
    ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
    Sheets(myarr(i) & "").Columns.AutoFit
Next
ws.AutoFilterMode = False
ws.Activate
End Sub

这会返回“溢出”

我尝试过的其他代码:

Sub columntosheets()

Const sname As String = "VOTERFILE_WITHABSENTEEINFORMATI" 'change to whatever starting sheet
Const s As String = "O" 'change to whatever criterion column
Dim d As Object, a, cc&
Dim p&, i&, rws&, cls&
Set d = CreateObject("scripting.dictionary")
With Sheets(sname)
    rws = .Cells.Find("*", , , , xlByRows, xlPrevious).Row
    cls = .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
    cc = .Columns(s).Column
End With
For Each sh In Worksheets
    d(sh.Name) = 1
Next sh

Application.ScreenUpdating = False
With Sheets.Add(after:=Sheets(sname))
    Sheets(sname).Cells(1).Resize(rws, cls).Copy .Cells(1)
    .Cells(1).Resize(rws, cls).Sort .Cells(cc), 2, Header:=xlYes
    a = .Cells(cc).Resize(rws + 1, 1)
    p = 2
    For i = 2 To rws + 1
        If a(i, 1) <> a(p, 1) Then
            If d(a(p, 1)) <> 1 Then
                Sheets.Add.Name = a(p, 1)
                .Cells(1).Resize(, cls).Copy Cells(1)
                .Cells(p, 1).Resize(i - p, cls).Copy Cells(2, 1)
            End If
            p = i
        End If
    Next i
    Application.DisplayAlerts = False
    .Delete
    Application.DisplayAlerts = True
    Application.ScreenUpdating = True
End With
Sheets(sname).Activate

End Sub

返回错误“excel没有足够的资源”。

是否可以在我的硬件上做我想做的事?

【问题讨论】:

  • 将您的 Integer 变量更改为 Single 并且顶部代码应该可以工作,尽管速度很慢。我会将其转换为使用数组。或者更好的是,你为什么要使用 Excel 来处理 800K+ 行?似乎数据库可能更合适。
  • SQL Server Express 是免费下载的,它可以像魅力一样处理数百万行。您遇到的错误是 Excel 在哭 老兄,我不是数据库,别管我。 Excel是一把强大的锤子。太糟糕了,不是每个数据驱动的问题都是钉子。
  • "你为什么不使用数据库?"对于使用 Excel 处理大量数据的发帖人来说,这是一个显而易见的问题,但我认为我们常常太快忘记刚开始编码时的情况 - 我知道我完全不知道 什么是“真正的”数据库,更不用说如何设置和使用数据库了。有时锤子是你唯一可以接触到的东西。
  • 这不是我正在创建的数据。这是我从网站下载的 .txt 文件。这可能是一个非常新手的问题,但是 SQL Server Express 的学习曲线有多大?我只需要计算几个统计数据。
  • @faeophyta,我是一个相对的 SQL 新手,我想说学习曲线(对于基本功能)不是太陡峭。您可以非常轻松地将.txt 文件加载到 SQL 中,然后从中进行查询。

标签: vba excel


【解决方案1】:

修改后的子程序可以参考另一篇文章'Macro for copying and pasting data to another worksheet'。

Sub CopySheet()

Dim wsAll As Worksheet
Dim wsCrit As Worksheet
Dim wsNew As Worksheet
Dim LastRow As Long
Dim LastRowCrit As Long
Dim I As Long

Set wsAll = Worksheets("All") ' change All to the name of the worksheet the existing data is on

LastRow = wsAll.Range("A" & Rows.Count).End(xlUp).Row

Set wsCrit = Worksheets.Add

' column G has the criteria eg project ref
wsAll.Range("A1:A" & LastRow).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=wsCrit.Range("A1"), Unique:=True

LastRowCrit = wsCrit.Range("A" & Rows.Count).End(xlUp).Row
For I = 2 To LastRowCrit

     wsAll.Copy Before:=Sheets("All")
     ActiveSheet.Name = wsCrit.Range("A2")
     Range("A1").CurrentRegion.AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=wsCrit.Range("A1:A2"), _
     Unique:=False
     wsCrit.Rows(2).Delete

Next I

Application.DisplayAlerts = False
wsCrit.Delete
Application.DisplayAlerts = True

End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    相关资源
    最近更新 更多