使用 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 数据库的最大大小,因此您可能 运行 在此之前遇到麻烦。此代码也不使用分块,因此它可能会使用比所需更多的内存。
我有一个 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 数据库的最大大小,因此您可能 运行 在此之前遇到麻烦。此代码也不使用分块,因此它可能会使用比所需更多的内存。