使用 DAO 代码将文件从 Access 上传到 SQL 服务器 - 需要对象错误

Uploading file from Access to SQL Server with DAO code - Object Required error

我有一个 Access 2016 数据库用作 SQL Server 2008 Express 实例的前端。 WATER_FILES table 存在于 SQL 服务器数据库中,并且包含类型为 varbinary(MAX) 的列 Binary_File

我正在尝试编写一个 VBA 子例程来将文件上传到该列。以下代码导致错误

Object Required

在运行时。此代码基于此不完整页面:https://msdn.microsoft.com/en-us/vba/access-vba/articles/work-with-attachments-in-dao#

我错过了什么?

Dim dbsGMEC As DAO.Database
Dim rstWater_Files As DAO.Recordset

Set dbsGMEC = CurrentDb
Set rstWater_Files = dbsGMEC.OpenRecordset("dbo_WATER_FILES", dbOpenDynaset, dbSeeChanges)

'   Unclear if a single record should be opened
'    Dim strSQL As String
'    strSQL = "SELECT * FROM dbo_WATER_FILES WHERE OBJECTID = '2'"
'    Set rstWater_Files = dbsGMEC.OpenRecordset(strSQL, dbOpenDynaset, dbSeeChanges)

' Activate edit mode.
rstWater_Files.Edit

' Instantiate the child recordset.
Dim rstFiles As DAO.Recordset

' THIS LINE GIVES THE ERROR "Runtime Error '424': Object Required"
Set rstFiles = rstWater_Files.Fields("Binary_File").Value

' Add a new attachment.
rstFiles.AddNew
rstFiles.Fields("FileData").LoadFromFile "C:\test.jpg"
rstFiles.Update

' Update the parent record
rstWater_Files.Update

Set 关键字用于将变量设置为对象引用。您的 .Value 不是对象,它是 Null。因此 Object Required 错误。

您找到的代码用于访问附件字段。然而,Varbinary(Max) 不是附件字段,而是映射到 Access/DAO 中的 OLE 对象。这意味着您需要将值设置为包含文件数据的字节数组,而不是使用嵌套记录集来管理附件。

有很多方法可以将文件加载到字节数组中。我更喜欢以下使用 ADODB.Stream 对象的代码。

Dim dbsGMEC As DAO.Database
Dim rstWater_Files As DAO.Recordset

Set dbsGMEC = CurrentDb
Set rstWater_Files = dbsGMEC.OpenRecordset("dbo_WATER_FILES", dbOpenDynaset, dbSeeChanges)
rstWater_Files.Edit
Dim strm As Object
Set strm = CreateObject("ADODB.Stream")
strm.Type = 1 'adTypeBinary
strm.Open
strm.LoadFromFile "C:\test.jpg"
rstWater_Files.Fields("Binary_File").Value = strm.Read
strm.Close
rstWater_Files.Update

要将其存储回文件:

With CreateObject("ADODB.Stream")
    .Type = 1 'adTypeBinary
    .Open
    .Write rstWater_Files.Fields("Binary_File").Value
    .SaveToFile "C:\testcopy.jpg", 2 'adSaveCreateOverWrite
    .Close
End With

如果你真的不喜欢 ADODB,甚至 ADODB.Stream 的想法都让你感到厌恶,你也可以使用 VBA 本身来将文件读入字节数组:

Dim dbsGMEC As DAO.Database
Dim rstWater_Files As DAO.Recordset

Set dbsGMEC = CurrentDb
Set rstWater_Files = dbsGMEC.OpenRecordset("dbo_WATER_FILES", dbOpenDynaset, dbSeeChanges)
rstWater_Files.Edit
Dim byteArr() As Byte
Dim fileInt As Integer: fileInt = FreeFile
Open "C:\test.jpg" For Binary Access Read As #fileInt
ReDim arr(0 To LOF(fileInt) - 1)
Get #fileInt, , byteArr
Close #fileInt
rstWater_Files.Fields("Binary_File").Value = byteArr
rstWater_Files.Update

最后一段代码会将最大文件大小限制为 2,147,483,647 字节(Long 的最大大小)。但是,这也是 Access 数据库的最大大小,因此您可能 运行 在此之前遇到麻烦。此代码也不使用分块,因此它可能会使用比所需更多的内存。