【问题标题】:Uploading file from Access to SQL Server with DAO code - Object Required error使用 DAO 代码将文件从 Access 上传到 SQL Server - 需要对象错误
【发布时间】:2018-03-27 19:40:45
【问题描述】:

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

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

需要对象

在运行时。此代码基于此不完整页面: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

【问题讨论】:

    标签: sql-server-2008 dao ms-access-2016


    【解决方案1】:

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

    您找到的代码用于 Access 附件字段。但是,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 数据库的最大大小,因此在此之前您可能会遇到麻烦。此代码也没有使用分块,因此它可能会使用比所需更多的内存。

    【讨论】:

    • 谢谢埃里克! ADODB 流方法运行良好。我非常感谢您的指导。我现在正在尝试使用 SaveToFile 写出文件的内容...关于如何正确打开记录集、记录、流(和字段)的任何建议?我还没有找到用于 ADODB 对象和写入文件系统的这些方法的示例。还是您更喜欢不同的方法?最后,是或否的问题 - 文件内容可以在 Access 报告中输出吗?例如。用文件填充模板?
    • 我提供了一个示例,说明如何使用 ADODB.Stream 回写内容。与.LoadFromFile 一样,.SaveToFile 仅用于访问附件字段。根据确切的文件类型,它可以显示在报告中,但通常将其保存到临时文件并使用它更容易。
    • 效果很好!非常感谢埃里克!你是老板。
    • 我的支持。如何将同名的文件保存到数据库中。 .SaveToFile "C:\testcopy.jpg", 2 我将如何用存储的文件名替换 testcopy
    • 嗯,这取决于您如何存储该文件名。如果您将它放在字符串变量中,只需使用该变量而不是 "C:\testcopy.jpg"。与 Access 附件类型相比,blob 不一定包含文件名,因此需要单独存储在某处。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多