【问题标题】:Convert Excel workbook to a CSV in VBA在 VBA 中将 Excel 工作簿转换为 CSV
【发布时间】:2020-02-14 21:49:26
【问题描述】:

我在将 Excel 工作簿转换为 CSV 的 VBA 脚本中出现错误。 VBA 脚本通过 Microsoft Word VBA 脚本运行。

Private Sub CommandButton1_Click()

Dim objExcel As New Excel.Application
Dim wb_xl As Excel.Workbook
Dim wb As Excel.Worksheet

Set wb_xl = objExcel.Workbooks.Open("O:\documents\folder.xlsx")
wb_xl.SaveAs FileName:="O:\documents\folder.csv", FileFormat:=xlCSV
Set wb = objExcel.Workbooks.Open("O:\documents\folder.csv")
wb_xl.Close savechanges:=False

End Sub

这看起来很简单,正在生成 CSV,但我收到一个错误:

运行时错误“1004”:无法访问“folder.csv”

错误在第 8 行 (wb_xl.SaveAs...)。

【问题讨论】:

  • 不是您真正要问的,但是....“wb”不是工作表吗?打开 .csv 文件时,您正在将工作表设置为工作簿对象。我从未尝试将工作表设置为工作簿对象,但这似乎是使用错误的对象...
  • 如果您执行SaveAs,那现在不是活动工作簿吗?如果已经打开,则无法打开。
  • 但我认为@FrankBall 是正确的......可能应该将wb 重命名为ws 以避免混淆并将Open 更改为实际的工作簿对象
  • @FrankBall 正确,但这是一个 type mismatch 错误,会在工作簿打开后立即抛出。
  • 打开任务管理器并确保您没有在后台运行任何其他 Excel 实例。您可能已经打开了此文件的副本,并且它被保存在内存中。

标签: excel vba csv


【解决方案1】:
Dim objExcel As New Excel.Application

如果这现在没有造成任何问题,那将是以后的问题。拆分声明和赋值,一般避免自动实例化对象,尤其是在创建时会产生外部进程的对象。

Dim objExcel As Excel.Application
Set objExcel = New Excel.Application

...完成后不要忘记.Quit该实例:

'...
objExcel.Quit

现在,错误 1004。

wb_xl.SaveAs FileName:="O:\documents\folder.csv", FileFormat:=xlCSV

这看起来很简单,正在生成 CSV

不合格的xlCSV 常量没什么大不了的,但请记住,它只有在引用了Excel 库时才有效;考虑对其进行限定:

wb_xl.SaveAs FileName:="O:\documents\folder.csv", FileFormat:=Excel.xlCSV

如果正在生成 CSV,则 SaveAs 调用有效,失败的语句将是以下语句:

Set wb = objExcel.Workbooks.Open("O:\documents\folder.csv")

你不能Open那个文件,它已经打开了——这就是为什么语句会抛出错误1004:如果你在Excel UI中用.xlsm文件尝试过,你会得到更详细的错误消息:

但错误信息与 .csv 文件不同:

我在即时窗格中输入此错误消息,并打开了一个新的空白工作簿:

ThisWorkbook.SaveAs "C:\Dev\test123.csv", xlCSV
Set b = Workbooks.Open("C:\Dev\VBA\test123.csv")

我认为这正是您遇到的错误。

删除wb,您不需要它(注意:如果Open 成功,分配将引发类型不匹配错误,因为您不能分配@987654338 @object 到 Worksheet 引用;Dim wb As Excel.Worksheet 看起来不对)。也去掉Workbooks.Open操作,CSV已经打开了。

换句话说:

Private Sub CommandButton1_Click()

    Dim xlApp As Excel.Application
    Set xlApp = New Excel.Application

    Dim wb As Excel.Worksheet
    Set wb = xlApp.Workbooks.Open("O:\documents\folder.xlsx")

    wb.SaveAs FileName:="O:\documents\folder.csv", FileFormat:=Excel.xlCSV
    wb.Close savechanges:=False

    xlApp.Quit

End Sub

【讨论】:

  • CSV 可能已经打开,但如果她只是从多张工作表中导出一张工作表(这就是 SaveAs to csv 所做的),她可能只想看到那张工作表。即使她执行了另存为,在文件关闭并重新打开之前,其他工作表仍然可用。如果是这种情况,将有问题的工作表复制到新文件然后执行另存为将是处理只有一张工作表可用而无需关闭文件然后重新打开它的方法。
  • @FrankBall 很公平,但是 OP 没有迭代该工作簿中的任何工作表,所以要么只有 1 张工作表,要么代码没有做它需要做的事情(或者很幸运打开时总是只有正确的工作表处于活动状态)......但在 OP 中没有任何迹象表明会出现这种情况,并且这个答案显示了 OP 错误 1004 的清晰重现,以及一个解决方案。
  • 她不必遍历工作表,当您将 SaveAs 保存为 csv 时,Excel 只会获取第一张工作表。如果她的文件在第一张纸上汇总了多张纸上的数据,那么 SaveAs 到 csv 将是一种简单的方法,可以将数据放入一个整洁的通用包中以供其他应用程序访问。
  • @FrankBall 没有。如果有多个带有可导出数据的工作表,则通过 UI prompts whether to only export the active sheet 保存为 CSV。从 VBA 代码中,没有提示 - 但只有 ActiveSheet(不一定是第一张工作表)被导出到 CSV。
  • 你是对的,它只是被导出的活动工作表。我支持的做这种事情的用户总是确保第一张表是被导出的,我只是按照他的假设进行操作。我现在比昨天聪明了 0.0002%。
猜你喜欢
  • 2019-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多