首页 > 解决方案 > 如何暂停 VBA 脚本执行,直到打开下载的 .csv 文件以允许在两个工作簿之间复制工作表?

问题描述

我有一个脚本,可以从 Yahoo Finance 下载并创建/打开一个新的 Excel .csv 历史股票数据工作簿。然后,我从该 .csv 工作簿中复制 worksheet(1) 的内容,并在 ThisWorkbook(包含我的宏/脚本的那个)中创建一个新工作表(最后)并将数据粘贴到其中。我已将浏览器 (Chrome) 配置为始终打开 .csv 文件下载。这是一些示例代码:

Sub Macro1()

    Dim urlLink As String
    Dim csvWorkbook As Workbook
    
    urlLink = "https://query1.finance.yahoo.com/v7/finance/download/AAPL?period1=1592179200&period2=1623715200&interval=1d&events=history&includeAdjustedClose=true"
    ActiveWorkbook.FollowHyperlink Address:=urlLink, NewWindow:=True
    Set csvWorkbook = ActiveWorkbook
    csvWorkbook.Sheets(1).Copy after:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)

End Sub

urlLink 是一个示例查询,用于以 .csv 格式从 Yahoo Finance 下载历史数据。将默认浏览器设置为始终打开 .csv 类型的文件。执行 ActiveWorkbook.FollowHyperlink 时,将打开另一个 Excel 实例并打开 AAPL.csv。这个新的 AAPL.csv 将成为活动工作簿,然后下一行代码将在 ThisWorkbook(包含您的脚本的工作簿)中创建一个新工作表,并将 AAPL.csv Sheet(1) 的内容复制到其中。

我的问题是,当我单步执行代码时它工作正常,但在全速运行时失败(即不在调试模式下)。澄清一下,假设您从一个新的空白工作簿开始,如果您单步执行上述代码,您将获得一个名为 AAPL 的新工作表,其中包含 253 行数据(我想要的我们的数据),但如果您完整运行它速度,您将添加一个名为 Sheet1(2) 的新空白表。

我发现这是因为在全速下,新的 .csv 文件没有被创建/打开,所以当 Set csvWorkbook = ActiveWorkbook 运行时,仍然只有 1 个工作簿打开(ThisWorkbook)所以下一个代码行只是复制工作表(1) 将 ThisWorkbook 复制到新工作表中,而不是将 Sheet(1) 从 AAPL.csv 复制到其中(因为在运行该行代码时它不存在)。

请注意,新创建的工作簿的名称并不总是已知的,因为如果该下载文件夹中已经有一个 APPL.csv,它将下一个命名为 APPL(1).csv 等等,所以我可以'不要只使用新创建的 .csv 工作簿的名称来引用它,因为我不知道它会是什么。

因此,我要求一种在执行 ActiveWorkbook.FollowHyperlink 时或之后在调试模式下模拟单步执行代码的方法。我试过简单地放置一个 MsgBox ,认为要求用户单击 OK 继续执行会有所帮助,但它没有,而且从我读到的内容中,我认为 Wait 或类似的东西也没有帮助?这类似于暂停执行 VBA 脚本直到打开另一个特定的 Excel 工作簿的问题? 但我不明白该线程中给出的答案,并且不确定它是否真的适用?感谢您对此的任何帮助!

标签: excelvbacsvdownloadevent-handling

解决方案


您可以将 URL 直接传递给Workbooks.Open()

Dim wb, ws
Set wb = Workbooks.Open("https://query1.finance.yahoo.com/v7/finance/download/AAPL?period1=1592179200&period2=1623715200&interval=1d&events=history&includeAdjustedClose=true")
Set ws = wb.Sheets(1)
'run text to columns if only one column of data
If ws.UsedRange.Columns.Count = 1 Then
    ws.Columns(1).TextToColumns Destination:=ws.Range("A1"), DataType:=xlDelimited, _
    TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Comma:=True
End If

推荐阅读