csv 等待大文件在Excel中打开

vs91vp4v  于 2023-07-31  发布在  其他
关注(0)|答案(3)|浏览(88)

我一直在尝试在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

字符串

ctzwtxfj

ctzwtxfj1#

一个诀窍是:
1.将它们作为读/写文件打开,
1.等待写入状态,该状态指示它已完全打开
1.将文件设置回只读
此代码循环直到文件进入写入状态:

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

bkkx9g8r

bkkx9g8r2#

这里有一个类似的方法,对我很有效。这个想法是在一个sub的开始,你检查工作簿是否已经加载。如果没有,则关闭sub(Exit Sub),并等待一秒钟,然后再次运行相同的函数。

重要:不能使用Application.Wait,否则Excel根本不会加载工作簿。在这里,你可能会陷入一个无休止的循环。但是使用Application.OnTime应该可以工作。

下面是一个代码示例:

Private Sub run_after_wb_loaded()
    ' delay start of procedure until workbook is loaded
    If ActiveWorkbook Is Nothing Then
        Application.OnTime EarliestTime:=Now + TimeValue("00:00:01"), Procedure:="run_after_wb_loaded"
        Exit Sub
    End If

    ' do stuff
End Sub

字符串

ycggw6v2

ycggw6v23#

如果您想打开文件并立即使用它,Excel可能会给予一个错误,因为Excel激活文件打开过程并执行下一个语句。对于不太长的文件,一个快速而肮脏的解决方案是引入一个与文件无关的额外代码,从而在文件打开过程中保持Excel忙碌。

相关问题