【问题标题】:Wait for big files to open in Excel等待大文件在 Excel 中打开
【发布时间】:2016-02-22 09:26:59
【问题描述】:

我一直试图在 VBA 中遍历一堆大的 .csv 文件。它们中的每一个大约为 50MB。在每次迭代中,我都会打开一个新的 CSV 来操作数据,但是当 .csv 打开时,会出现一条下载消息,指出文件正在打开,并且进度条总是在 VBA 等待完成时卡住。

实际上 .csv 是打开的,因为如果我在进度条上单击“取消”,代码会继续运行良好,但我必须在每次迭代时执行手动操作。

我的猜测是 VBA 在文件未打开或类似的情况下进入下一步,所以如果我执行睡眠或类似的操作,它可能会起作用,但我尝试的方法现在不起作用。 (我已经尝试过 Application.EnableEvents = False)。这是我的代码:

Sub GetOptions()

Application.DisplayAlerts = False
Application.EnableEvents = False

Set Dates = Sheets("Dates")
Set Res = Sheets("Options")

Dim dateToday As Date

ETF = "SPY"
nrows = Dates.Cells(Rows.Count, 1).End(xlUp).Row


For i = 708 To nrows

    If Dates.Cells(i, 2).Value = "B" Then
        dateToday = Dates.Cells(i, 1).Value
        dateYear = Year(dateToday)
        stringOpening = "P:\Options Database\CSV\" & dateYear & "\bb_" & dateYear & "_" & GetMonth(dateToday) & "\bb_options_" & Format(dateToday, "yyyymmdd") & ".csv"
        Workbooks.Open stringOpening, UpdateLinks:=0, ReadOnly:=True
        Set Options = Workbooks("bb_options_" & Format(dateToday, "yyyymmdd")).Sheets(1)

        Do things...

        Workbooks("bb_options_" & Format(dateToday, "yyyymmdd")).Close SaveChanges:=False
    End If
Next i


End Sub

【问题讨论】:

  • 我建议你先用小文件测试和完成你的代码。让您的代码在一组小(或中等)文件上正确运行并适应它,然后才转移到大文件,这将更容易评估问题。
  • Thx 但我已经在较小的文件上尝试过它并且它可以正常工作,它只会在大文件(> 30-40MB)时卡住
  • 你的P盘映射到什么地方?网络文件夹,还是别的什么?

标签: vba excel loops csv


【解决方案1】:

一个技巧是:

  1. 将它们作为读/写文件打开,
  2. 等待表示完全打开的写入状态
  3. 将文件设置为只读

此代码循环,直到文件进入写入状态:

Sub myWaitForFileOpen()
Dim wb As Workbook
Set wb = Application.Workbooks.Open("C:\File.xls")

Do Until wb.ReadOnly = False
    wb.Close
    Application.Wait Now + TimeValue("00:00:01")
    Set wb = Application.Workbooks.Open("C:\File.xls")
Loop
'Then the code that needs that Workbook open here!
'Or Call That other macro here!
End Sub

这是您的完整代码,它将以读/写方式打开 CSV,直到它完全加载,然后将其恢复为只读:

Sub GetOptions()
Dim wB As Workbook

Application.DisplayAlerts = False
Application.EnableEvents = False

Set Dates = Sheets("Dates")
Set Res = Sheets("Options")

Dim dateToday As Date

ETF = "SPY"
nrows = Dates.Cells(Rows.Count, 1).End(xlUp).Row


For i = 708 To nrows
    If Dates.Cells(i, 2).Value = "B" Then
        dateToday = Dates.Cells(i, 1).Value
        dateYear = Year(dateToday)
        stringOpening = "P:\Options Database\CSV\" & dateYear & "\bb_" & dateYear & "_" & GetMonth(dateToday) & "\bb_options_" & Format(dateToday, "yyyymmdd") & ".csv"

        Set wB = Workbooks.Open(stringOpening, UpdateLinks:=0, ReadOnly:=False)

        Do Until wB.ReadOnly = False
            wB.Close

            Application.Wait Now + TimeValue("00:00:01")

            Set wB = Application.Workbooks.Open("C:\My Files\AAA.xls")
        Loop
        wB.ReadOnly = True
        Set Options = wB.Sheets(1)


        Do
            'things...
        Loop

        wB.Close SaveChanges:=False
    End If
Next i

End Sub

【讨论】:

  • 我很困惑这是如何工作的?在我看来,它试图打开文件,该文件以只读方式打开,直到它完全打开,然后它被转换为读写。我认为这是有道理的,但答案似乎是只读的,然后关闭它,稍等片刻,然后再次尝试打开它。这如何使它打开一个大文件?似乎它会一遍又一遍地不断打开和关闭文件。
  • 经过测试,这确实是我得到的……也许自从 2015 年发布以来发生了一些变化?
  • 哦,我打开的文件一开始是只读的...更改了它并且它有效...仍然不明白为什么,但确实如此。
  • @JasonBrady : 老实说...我不记得我为什么在阅读时这样做了,close 在我看来也很可疑!^^ 我仍然同意一般的想法,但是那部分现在对我来说是个谜!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 1970-01-01
  • 2019-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多