Sql server 使用VBA在Access字段中保存OLE对象

Sql server 使用VBA在Access字段中保存OLE对象,sql-server,object,ms-access,vba,ole,Sql Server,Object,Ms Access,Vba,Ole,我知道这个问题已经被广泛地讨论过了,但我还没有找到解决我这个问题的办法 我有一个表,其列附件为OLE对象数据类型。该表的后端是SQL Server表,附件列的数据类型为VARBINARY(MAX) 如果我右键单击Access中的附件字段,将弹出一个菜单,其中包含插入对象的选项。。。沿着这个路径,我可以在字段中插入一个文件 以这种方式插入的文件可以通过双击该字段打开进行查看和编辑 现在。我需要用VBA做同样的事情。我需要获取文件列表,并将它们插入相应行的附件字段中。这应该不是一项困难的任务,

我知道这个问题已经被广泛地讨论过了,但我还没有找到解决我这个问题的办法

我有一个表,其列附件为OLE对象数据类型。该表的后端是SQL Server表,附件列的数据类型为VARBINARY(MAX)

如果我右键单击Access中的附件字段,将弹出一个菜单,其中包含插入对象的选项。。。沿着这个路径,我可以在字段中插入一个文件

以这种方式插入的文件可以通过双击该字段打开进行查看和编辑

现在。我需要用VBA做同样的事情。我需要获取文件列表,并将它们插入相应行的附件字段中。这应该不是一项困难的任务,因为众所周知,如何使用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 & "\Attachments\537.zip"

    rsa.Fields("Attachments").value = stream.Read

    rsa.Update
    rsa.Close

    Set rsa = Nothing
    Set dba = Nothing
End Sub
代码将在第二行的附件字段中插入一个文件。我可以验证通过SSMS增加的价值。但是,当我尝试打开字段进行查看和编辑时,正如我之前对第一行所做的那样,这次我遇到了一个错误:

显然,使用VBA保存文件的方式有问题


我做错了什么?如何使用VBA获得与使用Access用户界面相同的结果?

据我所知,如果您想将文件存储为OLE包外壳对象,执行一些GUI编码(使用OLE对象打开表单,然后使用该对象存储文件)是唯一的方法

创建一个名为frmLoadOLEObj的未绑定表单,其上有一个名为MyBoundOLEFrame的绑定OLE对象

在表单上,添加以下代码:

Public子SaveOLEObj(rs作为DAO.Recordset,fldName作为String,FileName作为Variant)
'保存记录集的位置
Dim bkmrk作为变体
bkmrk=rs.书签
'将表单绑定到记录集
设置我。记录集=rs
'将表单移动到保存的位置
Me.Bookmark=bkmrk
'将OLE框架绑定到字段
MyBoundOLEFrame.ControlSource=fldName
MyBoundOLEFrame.Class=“包”
'将附件加载到OLE框架中
MyBoundOLEFrame.SourceDoc=文件名
MyBoundOLEFrame.Action=acOLECreateEmbed
端接头
然后,要将文件添加到记录中,请执行以下操作:

Dim rsa作为DAO.Recordset
Set rsa=CurrentDb.OpenRecordset(“ZipCodeAttachments”、dbOpenDynaset、dbSeeChanges)
将frmOLE变为新形式\u frmLoadOLEObj
frmOLE.SaveOLEObj rs,“附件”,Application.CurrentProject.Path&“\Attachments\537.zip”

正如您所看到的,这是一个非常“黑”的代码,因为它运行GUI操作,并且您在表单上的代码不是表单,而是真正的模块,但是您需要一个表单来放置控件,因为没有表单就无法拥有控件。我宁愿有一个BLOB任何一天。

你真的在使用sql server吗?屏幕截图中的所有内容都来自Access。一个重要的区别是:是否要像文件BLOB(BLOB通过VBA、其他编程语言等很容易使用,但通过Access GUI很难使用)或OLE包对象那样存储文件(通过GUI很容易使用,但除了VBA之外几乎不可能使用,通过VBA很难使用)?我可以向您展示如何将OLE包对象从文件加载到记录集中,但我强烈建议使用普通的文件BLOB。OLE对象类似于嵌入式Word或Excel文档,而不是BLOB。它们应该具有非常特定的文件格式,并且只能由注册的应用程序打开兰格先生:是的。我用SQL Server作为后端。所有数据都保存在SQL Server中。我使用Access作为前端。如果这完全回答了你的问题,考虑接受itErik von Asmuth,我想它确实回答了我的问题,我肯定会ACC。接受它作为答案。我想澄清几件事,因为我面临一个重大问题,希望您能帮助我解决。提供的解决方案适用于大多数文件,但在大于20 MB的文件上失败。语句BoundOLEFrame.Action=acOLECreateEmbed需要大约2.5分钟才能完成。它不会引发任何异常,但是,当执行以下MoveNext或任何重新定位语句时,它们会失败,并出现运行时错误“3426”:“该操作已被关联对象取消”。因此,该对象似乎未存储在数据库中,因为尝试使用Access UI打开它会导致错误:“Microsoft Access与OLE服务器或ActiveX控件通信时出现问题。请关闭OLE服务器并在Microsoft Access外部重新启动。然后在Microsoft Access中重试原始操作。"我怀疑这个问题可能与ODBC超时有关,默认情况下,ODBC超时设置为60秒。我尝试将当前数据库QueryTimeout设置为600秒。但这没有帮助…请提供任何建议。这听起来像是一个单独的问题。我建议您发布一个单独的问题。尝试提供所有必要的信息我的数据库设置相当快,因此很难重现加载时间长的问题,我与SQL Server的连接也非常快,但服务器是远程的,即使在本地数据库中加载20+MB的文件也需要相当长的时间。