非常大的ex​​cel文件 - 如何在工作表之间复制数据?

时间:2012-09-17 20:41:51

标签: excel vba

我需要将一些csv文件导入excel 2010并创建一个非常简单但非常大的数据库 整个故事将是 - 五列和几千行 VBA也很简单 - 将数据从一张纸复制到另一张 - 反之亦然 但我需要关心内存需求,因为文件大小可能非常大。

Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim r1 As Range
Dim r2 As Range
Set ws1 = Sheets("01")
Set ws2 = Sheets("02")
Set r1 = ws1.Range("A1:B10") ' for example
Set r2 = ws2.Range("C5:D14")
r1.Copy Destination:=r2 'first way
r2.Value = r1.Value ' second way

这两种方法在记忆/耗时范围内是否有任何差异?
在和,我将有超过10,000行。文件的大小是多少?

2 个答案:

答案 0 :(得分:6)

您可以使用ADO查询文本文件,就像它们是数据库表一样。这允许您编写SQL查询以从文本文件中提取数据。如果您愿意,可以执行任何文本文件甚至.xls文件。

这样做的代码/过程非常简单。您需要先引用Microsoft ActiveX Data Objects 2.X Library,然后使用以下内容:

Dim cn as New ADODB.Connection
Dim rs as New ADODB.Recordset
Dim i as Integer

With cn
    .Provider = "Microsoft.Jet.OLEDB.4.0"
    .ConnectionString = "Data Source=C:\SomeFolder;" & _
                        "Extended Properties=""text; HDR=Yes;FMT=Delimited"""
    .Open

    With rs
        .Open "SELECT * from fileName.txt", cn

        'Loop through each row in query
        While Not (.EOF Or .BOF)
            'Loop through each column in row
            For i = 0 to .Fields.Count - 1
                Debug.Print .Fields(i).Value 'Print value of field to Immediate Window
            Next i

            .MoveNext
        Wend

        .Close
    End With

    .Close
End With

Set rs = Nothing
Set cn = Nothing

这将遍历您的文本文件并显示VBA立即窗口中第一列的值。它还假定您的文件具有标题行。如果没有,则需要将ConnectionString中的 HDR 更改为

代码会自动尝试为您推断类型,但如果您遇到问题而没有发现正确的类型(例如前导零),那么您可以明确定义文件的架构。重要的是要注意,如果你去模式路由,那么你的ConnectionString参数,如 HDR FMT 将被忽略。除非您在架构定义中覆盖它们,否则它们将保留注册表中定义的默认设置。有关schema.ini文件的更多信息,请访问:http://msdn.microsoft.com/en-us/library/windows/desktop/ms709353(v=vs.85).aspx

这是另一个有用的链接:http://msdn.microsoft.com/en-us/library/ms974559.aspx。这是Microsoft Scripting Guys撰写的一篇文章,也是我最初了解该过程的方法。

最后,如果您将此进程与.xls文件一起使用,那么您应该知道不应该查询OPEN .xls文件。 OPEN .xls文件存在令人讨厌的内存泄漏错误(此处有更多信息:http://support.microsoft.com/default.aspx?scid=kb;en-us;319998&Product=xlw)。只要您查询CLOSED .xls文档,那么您就不应该有任何问题= D. SQL FROM子句中的语法略有不同,因为您必须以特定工作表为目标,但IIRC我编写的脚本专家文章解释了如何执行此操作。

答案 1 :(得分:2)

此代码块对我所参与的项目有一些细节,但应该有助于您开始介绍如何通过VBA导入CSV文件(稍微清理一下):

Public Sub ImportCSV(strPath As String, strFile As String, strExt As String, wbDestination As Workbook, Optional wsDest As Worksheet, Optional strRange As String, Optional blHeaders As Boolean = True)
'imports given CSV file into given sheet at given range _
    defaults to comma separated delimiters

Dim wsDestination As Worksheet
Dim strFileName As String
strFileName = strPath & strFile & ".csv"


If wsDest Is Nothing Then Set wsDestination = wbDestination.Worksheets.Add(, wbDestination.Worksheets(wbDestination.Worksheets.Count)) Else: Set wsDestination = wsDest
If strRange = "" Then strRange = "$A$1"

With wsDestination.QueryTables.Add(Connection:="TEXT;" & strFileName, Destination:=wsDestination.Range(strRange))
        .FieldNames = False
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = False
        .AdjustColumnWidth = False
        .RefreshPeriod = 0
        .TextFilePromptOnRefresh = False
        .TextFilePlatform = 437
        .TextFileStartRow = 1
        .TextFileParseType = xlDelimited
        .TextFileTextQualifier = xlTextQualifierDoubleQuote
        .TextFileConsecutiveDelimiter = False
        .TextFileTabDelimiter = False
        .TextFileSemicolonDelimiter = False
        .TextFileCommaDelimiter = True
        .TextFileSpaceDelimiter = False
        .TextFileTrailingMinusNumbers = True
        .Refresh BackgroundQuery:=False
        .Delete
    End With

If Not blHeaders Then wsDestination.Range(strRange).EntireRow.Delete

End Sub