带有空格和范围的 MS Access VBA acImport 工作表名称

Posted

技术标签:

【中文标题】带有空格和范围的 MS Access VBA acImport 工作表名称【英文标题】:MS Access VBA acImport sheet name with spaces and range 【发布时间】:2013-04-10 14:53:33 【问题描述】:

我正在构建一个带有名为“Go”的按钮的表单,用于从 Excel 文件中导入特定范围的特定 Excel 工作表。另一个子/函数负责将文件名放在名为 text_filepathdata 的字段中的表单上。

我发现工作表名称中的空格有问题,但是可以通过使用特殊引号来解决。

Dim sheetname As String
sheetname = "'Commit Volumes!'"
DoCmd.Transferspreadsheet acImport, acSpreadsheetTypeExcel12, _
    "lcl_ImportedFile", text_filepathdata, True, sheetname

这行得通,但由于特殊引号,我无法在工作表名称之外指定范围...(即“'Commit Volumes!A6:Z5000'”不起作用,串联也不起作用像“'Commit Volumes'”和“A6:Z5000”这样的两部分)

我尝试了各种引用和连接方式,但唯一有效的是:

sheetname = "'Commit Volumes!'"
sheetname = "'Commit Volumes$'"
sheetname = "CommitVolumes!A6:Z5000"

无法修改 Excel 工作表,因为它来自另一个系统,并且文件(更新后)必须上传回该系统。

这是我的代码:

Private Sub button_Go_Click()
On Error GoTo Err_button_Go_Click

Dim sheetname As String
sheetname = "'Commit Volumes!'"

If IsNull(text_filepathdata) Or text_filepathdata = "" Then
    MsgBox "Please browse and select a valid file to import.", _
        vbCritical, "Invalid File"
Else
    DoCmd.OpenForm "f_PleaseWait_Processing", acNormal, , , acFormReadOnly, acWindowNormal
    If ifTableExists("lcl_ImportedFile") = True Then
        DoCmd.DeleteObject acTable, "lcl_ImportedFile"
    End If
    DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12,_
        "lcl_ImportedFile", text_filepathdata, True, sheetname

'Call module to process the imported data
        Call MainProcess
    End If

Exit_button_Go_Click:
    Exit Sub

Err_button_Go_Click:
    MsgBox Err.Number & " - " & Err.Description
    Resume Exit_button_Go_Click

End Sub

根据问题,我收到两条不同的错误消息。

如果名称中有空格,我会得到:运行时错误 3129:无效的 SQL 语句;预期为“DELETE”、“INSERT”、“PROCEDURE”、“SELECT”或“UPDATE”。

如果名称有问题,否则我会得到:运行时错误 3011:Microsoft Access 数据库引擎找不到对象“Commit Volumes$A1:Z5000”。确保对象存在并且正确拼写其名称和路径。如果“Commit Volumes$A1:Z5000”不是本地对象,请检查您的网络连接或联系服务器管理员。

任何帮助将不胜感激!

比尔

我尝试过的变体:

sheetname = "'Commit Volumes'!A6:Z5000"; 
sheetname = "'Commit Volumes!'A6:Z5000" 
sheetname = "'Commit Volumes$'A6:Z5000" 
sheetname = "'Commit Volumes'$A6:Z5000" 
sheetname = "'Commit Volumes'$A$6:$Z$5000" 
sheetname = "'Commit Volumes!'$A$6:$Z$5000" 
sheetname = "'Commit Volumes$'$A$6:$Z$5000"

【问题讨论】:

【参考方案1】:

如果文件以已知\set 格式从其他系统导出,您可以通过索引而不是名称来引用它:

例如:床单(1)、床单(2)。然后添加范围。

【讨论】:

【参考方案2】:

我也有同样的问题。当我创建一个范围字符串变量并将其传递给 DoCmd.TransferSpreadsheet 例程时,Access 更改了“!”字符到“$”并给了我一个错误。如果我将字符串常量传递给 DoCmd.TransferSpreadsheet 例程的 Range 参数,Access 不会更改该字符。也就是说,运行下面的代码,...

Dim strFilename As String
Dim strRange As String
Dim strTableName As String

strFilename = "YourWorkbookName.xlsx"
strRange = "Sheet5!A1:Z99"
strTableName = "tblImport"

DoCmd.TransferSpreadsheet _
  TransferType:=acImport, _
  SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
  TableName:=strTableName, _
  FileName:=strFilename, _
  HasFieldNames:=True, _
  Range:=strRange

...给了我 3011 运行时错误。

但是,当我将工作表名称和地址分成两个单独的变量并将它们传递给例程时,Access 很高兴。换句话说,当我运行代码时,...

Dim strAddress As String
Dim strFilename As String
Dim strSheetName As String
Dim strTableName As String

strAddress = "A1:Z99"
strFilename = "YourWorkbookName.xlsx"
strSheetName = "Sheet5"
strTableName = "tblImport"

DoCmd.TransferSpreadsheet _
  TransferType:=acImport, _
  SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
  TableName:=strTableName, _
  FileName:=strFilename, _
  HasFieldNames:=True, _
  Range:=strSheetName & "!" & strAddress

...我没有收到任何错误,Sheet5 工作表中的数据已正确导入到 tblImport。

需要注意的是,Sheet5 不是工作簿的第一张表,strAddress 中没有“$”字符。

编码愉快。

【讨论】:

【参考方案3】:

这是你需要的:

'Commit Volumes'!A6:Z5000

当工作表名称包含空格或破折号时,Excel 会在工作表名称本身周围放置单引号,而不是在整个引用周围。

所以:

sheetname = "'Commit Volumes'!A6:Z5000"

【讨论】:

嗨斯科特!我尝试了您建议的代码...我仍然收到相同的错误消息。错误消息没有返回我在代码中键入的内容...消息说:Microsoft Access 数据库引擎找不到对象“提交卷'$A6:AQ5000'。确保...等等。而不是说对象是“'Commit Volumes'!A6:AQ5000”,就像我在代码中一样。奇怪,嗯?它一定是对我在代码中输入的内容进行了不同的解释?还是别的什么? 一位程序员同事刚刚建议尝试像这样的多个变量:Dim sheetname as String Dim cellrange as String Dim sheetrange as String sheetname = "'Commit Volumes!'" cellrange = "A6:Z5000" sheetrange = sheetname & cellrange 这看起来很有希望,但没有奏效。 :( 请原谅我,但我无法让代码出现在多行上。 在黑暗中拍摄,但如果您尝试在工作表名称周围使用括号 [] 而不是 ' 不要使用感叹号 (!)、单引号 (') 或固定寻址符号 ($A$1)。对于您的示例,有效的格式如下所示:“Commit Volumes$A6:Z5000”【参考方案4】:

使用 sheetname = "Commit Volumes$" 没有范围,这似乎可以通过将表字段名称与 excel 列标题匹配来工作

【讨论】:

【参考方案5】:

我遇到了同样的问题。

终于发现可以用了:

sheetname = "提交卷!A6:Z5000" 例子 DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, "表名", _ filetoimport, False, "提交卷!A6:Z5000"

问候!

【讨论】:

【参考方案6】:

我尝试了上述建议的解决方案,但不幸的是它在我的情况下不起作用:当工作表的名称中有空格时,Access 的导入方法确实不喜欢它。

我做了一个解决方法:将代码中的工作表重命名为简短且没有空格的名称,例如:从“Data Q1 2016”到“WS1”。这样,您可以将值“WS1$”传递给导入函数的 Range 参数,Access 将导入给定工作表的使用范围

在导入第二个工作表时,我再次使用代码并将其重命名为“WS2”......等等。

总结:在代码运行时将工作表重命名为不带空格的短名称,并在末尾添加“$”符号以使其抓住使用的范围。

【讨论】:

【参考方案7】:

我找到了一种解决方案,可以在我需要的两种情况下使用。

上面的原始海报和所有在这里回答的尝试都无法偶然发现使其工作所需的特定格式。经过顽固的反复试验,我做到了,这不是我们任何人所期望的。

为了让 DoCmd.TransferSpreadsheet 函数获取特定工作表上的特定范围,“范围”参数必须采用以下格式:

"SheetName$A1:Z100"

如果 SheetName 中有空格,则必须是:

"Sheet Name$A1:Z100"
    工作表名称必须放在单引号中,否则方法将 失败。 工作表名称必须以感叹号结尾 在范围之前,否则方法将失败。 范围 (A1:Z100) 必须采用固定寻址表示法,或者 该方法将失败。

总结一下: 如果您有一个名为“WB”的工作簿,其中包含两个工作表:“S1”和“S 2”,并且您想从每个工作表中导入范围 A1:Z100:

DoCmd.TransferSpreadsheet ,,"TABLE NAME 1","WB",,"S1$A1:Z100"
DoCmd.TransferSpreadsheet ,,"TABLE NAME 2","WB",,"S 2$A1:Z100"

【讨论】:

以上是关于带有空格和范围的 MS Access VBA acImport 工作表名称的主要内容,如果未能解决你的问题,请参考以下文章

在使用 VBA 的 MS Access 链接的 Excel 电子表格中指定“开放式”范围

带有子查询的 SQL 查询上的 MS Access VBA 运行时错误 3075

MS Access - VBA 中报告的参数

使用 VBA 的 MS Access 打印报告

MS Access 日期范围函数减慢查询速度

MS Access 2016 VBA 导致“输入参数值”窗口