使用 VBA 在 Access 字段中保存 OLE 对象
Saving OLE Objects in Access field with VBA
我知道这个主题已被广泛涉及,但我无法找到解决我的特定问题的方法。
我有一个 table,其列 Attachments 的 OLE 对象数据类型。 table 的后端是 SQL Server table,Attachments 列的数据类型为 VARBINARY(MAX)。
如果我右键单击 Access 中的 附件 字段,会弹出一个菜单,其中包含 插入对象... 按照这个路径,我可以在字段中插入一个文件。
以这种方式插入的文件只需双击该字段即可打开进行查看和编辑。
现在。我需要使用 VBA 做同样的事情。我需要获取文件列表并将它们插入适当行的 Attachments 字段中。这应该不是一项艰巨的任务,因为众所周知如何使用 ADODB.Stream 在字段中插入文件。以下是尝试概念的简单代码:
Private Sub POC()
Dim db As DAO.Database
Dim rsa As DAO.Recordset
Dim stream As ADODB.stream
Set db = CurrentDb()
Set rsa = db.OpenRecordset("ZipCodeAttachments", dbOpenDynaset, dbSeeChanges)
rsa.MoveFirst
rsa.MoveNext
rsa.Edit
Set stream = New ADODB.stream
stream.Type = adTypeBinary
stream.Open
stream.LoadFromFile Application.CurrentProject.Path & "\Attachments7.zip"
rsa.Fields("Attachments").value = stream.Read
rsa.Update
rsa.Close
Set rsa = Nothing
Set dba = Nothing
End Sub
代码在第二行的 Attachments 字段中插入一个文件。我可以验证该值已通过 SSMS 添加。但是,当我像之前对第一行所做的那样尝试打开字段进行查看和编辑时,这次我收到错误消息:
很明显,VBA保存文件的方式有问题。
我做错了什么?如何使用 VBA 获得与使用 Access 用户界面相同的结果?
如果您想将文件存储为 OLE 包 shell 对象,进行一些 GUI 编码(打开带有 OLE 对象的表单,然后使用它来存储文件)是目前唯一的方法据我所知。
创建一个名为 frmLoadOLEObj 的未绑定表单,其中包含一个名为 MyBoundOLEFrame 的绑定 OLE 对象。
在表单中,添加以下代码:
Public Sub SaveOLEObj(rs As DAO.Recordset, fldName As String, FileName As Variant)
'Save the position of the recordset
Dim bkmrk As Variant
bkmrk = rs.Bookmark
'Bind the form to the recordset
Set Me.Recordset = rs
'Move the form to the saved position
Me.Bookmark = bkmrk
'Bind the OLE frame to the field
MyBoundOLEFrame.ControlSource = fldName
MyBoundOLEFrame.Class = "Package"
'Load the attachment into the OLE frame
MyBoundOLEFrame.SourceDoc = FileName
MyBoundOLEFrame.Action = acOLECreateEmbed
End Sub
然后,将文件添加到记录中:
Dim rsa As DAO.Recordset
Set rsa = CurrentDb.OpenRecordset("ZipCodeAttachments", dbOpenDynaset, dbSeeChanges)
Dim frmOLE As New Form_frmLoadOLEObj
frmOLE.SaveOLEObj rs, "Attachments", Application.CurrentProject.Path & "\Attachments7.zip"
如您所见,这是非常"hacky"的代码,因为它运行的是 GUI 操作,并且您在窗体上的代码不是窗体,而是真正的模块,但您需要一个窗体来放上控件,因为没有表单就无法获得控件。我宁愿每天都有一个 BLOB。
我知道这个主题已被广泛涉及,但我无法找到解决我的特定问题的方法。
我有一个 table,其列 Attachments 的 OLE 对象数据类型。 table 的后端是 SQL Server table,Attachments 列的数据类型为 VARBINARY(MAX)。
如果我右键单击 Access 中的 附件 字段,会弹出一个菜单,其中包含 插入对象... 按照这个路径,我可以在字段中插入一个文件。
以这种方式插入的文件只需双击该字段即可打开进行查看和编辑。
现在。我需要使用 VBA 做同样的事情。我需要获取文件列表并将它们插入适当行的 Attachments 字段中。这应该不是一项艰巨的任务,因为众所周知如何使用 ADODB.Stream 在字段中插入文件。以下是尝试概念的简单代码:
Private Sub POC()
Dim db As DAO.Database
Dim rsa As DAO.Recordset
Dim stream As ADODB.stream
Set db = CurrentDb()
Set rsa = db.OpenRecordset("ZipCodeAttachments", dbOpenDynaset, dbSeeChanges)
rsa.MoveFirst
rsa.MoveNext
rsa.Edit
Set stream = New ADODB.stream
stream.Type = adTypeBinary
stream.Open
stream.LoadFromFile Application.CurrentProject.Path & "\Attachments7.zip"
rsa.Fields("Attachments").value = stream.Read
rsa.Update
rsa.Close
Set rsa = Nothing
Set dba = Nothing
End Sub
代码在第二行的 Attachments 字段中插入一个文件。我可以验证该值已通过 SSMS 添加。但是,当我像之前对第一行所做的那样尝试打开字段进行查看和编辑时,这次我收到错误消息:
很明显,VBA保存文件的方式有问题。
我做错了什么?如何使用 VBA 获得与使用 Access 用户界面相同的结果?
如果您想将文件存储为 OLE 包 shell 对象,进行一些 GUI 编码(打开带有 OLE 对象的表单,然后使用它来存储文件)是目前唯一的方法据我所知。
创建一个名为 frmLoadOLEObj 的未绑定表单,其中包含一个名为 MyBoundOLEFrame 的绑定 OLE 对象。
在表单中,添加以下代码:
Public Sub SaveOLEObj(rs As DAO.Recordset, fldName As String, FileName As Variant)
'Save the position of the recordset
Dim bkmrk As Variant
bkmrk = rs.Bookmark
'Bind the form to the recordset
Set Me.Recordset = rs
'Move the form to the saved position
Me.Bookmark = bkmrk
'Bind the OLE frame to the field
MyBoundOLEFrame.ControlSource = fldName
MyBoundOLEFrame.Class = "Package"
'Load the attachment into the OLE frame
MyBoundOLEFrame.SourceDoc = FileName
MyBoundOLEFrame.Action = acOLECreateEmbed
End Sub
然后,将文件添加到记录中:
Dim rsa As DAO.Recordset
Set rsa = CurrentDb.OpenRecordset("ZipCodeAttachments", dbOpenDynaset, dbSeeChanges)
Dim frmOLE As New Form_frmLoadOLEObj
frmOLE.SaveOLEObj rs, "Attachments", Application.CurrentProject.Path & "\Attachments7.zip"
如您所见,这是非常"hacky"的代码,因为它运行的是 GUI 操作,并且您在窗体上的代码不是窗体,而是真正的模块,但您需要一个窗体来放上控件,因为没有表单就无法获得控件。我宁愿每天都有一个 BLOB。