将文件从OLE对象(Access)保存到光盘

时间:2018-01-19 14:18:46

标签: vb.net vba ms-access oledb

我有来自具有Access Application的客户的MS SQL数据库。

此应用程序将文件存储在此MS SQL数据库中。

我试图从数据库中获取字节,然后将它们保存到磁盘中。 有些文件可以使用,而有些则没有。 (图片不工作,拉链工作,wordfiles打开但字必须恢复它们)

我发现Access将文件保存在OLE对象中。

所以我需要从OLE对象中取出原始文件!

这似乎很难。

我试图找到一个可以从OLE对象中分离文件的.NET库..什么也没找到......

现在我正试图通过Access获取文件......

似乎我需要一个getChunk函数来做到这一点...... 发现这个页面有一个WriteBlob代码...据说它会满足我的需要..

https://support.microsoft.com/en-us/help/210486/acc2000-reading--storing--and-writing-binary-large-objects-blobs

现在我可以将文件写入Harddisc ......但文件仍然无法打开!

这里出了点问题......

我的完整VBA代码是:

 Option Compare Database


 Const BlockSize = 32768


 Sub xxx()


 Dim id As Integer
   Debug.Print "****************************************************"
   Debug.Print "****************************************************"
   Debug.Print "****************************************************"
   Debug.Print "****************************************************"

   Dim unnoetig As Variant

   Dim dok() As Byte
   Dim sql As String
   sql = "select top 1 idCaseDetail, idCase, Dokument from dbo_law_tbl_CaseHistory where idCaseDetail = ""1"""

   Dim rst As DAO.Recordset

   Set rst = CurrentDb.OpenRecordset(sql)

   If Not rst.EOF Then
     Do While Not rst.EOF
       Debug.Print "idcasehistory: " & rst.Fields(0)
       Debug.Print "idcase: " & rst.Fields(1)

       If Not IsNull(rst.Fields(2).Value) Then
         dok = rst.Fields(2)
         unnoetig = WriteBLOB(rst, "Dokument", "c:\temp\ole.doc")
       End If
       rst.MoveNext


     Loop
   End If

 End Sub



 '**************************************************************
 ' FUNCTION: WriteBLOB()
 '
 ' PURPOSE:
 '   Writes BLOB information stored in the specified table and field
 '   to the specified disk file.
 '
 ' PREREQUISITES:
 '   The specified table with the OLE object field containing the
 '   binary data must be opened in Visual Basic code and the correct
 '   record navigated to prior to calling the WriteBLOB() function.
 '
 ' ARGUMENTS:
 '   T           - The table object containing the binary information.
 '   sField      - The OLE object field in table T containing the
 '                 binary information to write.
 '   Destination - The path and filename to write the binary
 '                 information to.
 '
 ' RETURN:
 '   The number of bytes written to the destination file.
 '**************************************************************
 Function WriteBLOB(T As DAO.Recordset, sField As String, _
 Destination As String)
     Dim NumBlocks As Integer, DestFile As Integer, i As Integer
     Dim FileLength As Long, LeftOver As Long
     Dim FileData As String
     Dim RetVal As Variant

     On Error GoTo Err_WriteBLOB

     ' Get the size of the field.
     FileLength = T(sField).FieldSize()
     If FileLength = 0 Then
         WriteBLOB = 0
         Exit Function
     End If

     ' Calculate number of blocks to write and leftover bytes.
     NumBlocks = FileLength \ BlockSize
     LeftOver = FileLength Mod BlockSize

     ' Remove any existing destination file.
     DestFile = FreeFile
     Open Destination For Output As DestFile
     Close DestFile

     ' Open the destination file.
     Open Destination For Binary As DestFile

     ' SysCmd is used to manipulate the status bar meter.
     RetVal = SysCmd(acSysCmdInitMeter, _
     "Writing BLOB", FileLength / 1000)

     ' Write the leftover data to the output file.
     FileData = T(sField).GetChunk(0, LeftOver)
     Put DestFile, , FileData

     ' Update the status bar meter.
     RetVal = SysCmd(acSysCmdUpdateMeter, LeftOver / 1000)

     ' Write the remaining blocks of data to the output file.
     For i = 1 To NumBlocks
         ' Reads a chunk and writes it to output file.
         FileData = T(sField).GetChunk((i - 1) * BlockSize _
            + LeftOver, BlockSize)
         Put DestFile, , FileData

         RetVal = SysCmd(acSysCmdUpdateMeter, _
         ((i - 1) * BlockSize + LeftOver) / 1000)
     Next i

     ' Terminates function
     RetVal = SysCmd(acSysCmdRemoveMeter)
     Close DestFile
     WriteBLOB = FileLength
     Exit Function

 Err_WriteBLOB:
     WriteBLOB = -Err
     Exit Function

 End Function

你有什么建议吗? 重要的是: 它是一个MS SQL数据库......而不是一个Access数据库..有些工具可能会用access-Databases来表达..但不是mit ms sql

是否有.NET方式或VBA方式将文件保存到光盘?

2 个答案:

答案 0 :(得分:1)

使用DAO保存OLE对象的一种简单替代方法是使用ADODB.Stream对象:

Public Sub SaveOLEObject(OleObjectField As Field, Filelocation As String)
    Dim adoStream As Object 'ADODB.Stream
    Set adoStream = CreateObject("ADODB.Stream")
    adoStream.Type = 1 'adTypeBinary
    adoStream.Open
    adoStream.Write OleObjectField.Value
    adoStream.SaveToFile Filelocation, adSaveCreateOverWrite
    adoStream.Close
End Sub

称之为:

SaveOLEObject(rst.Fields("Dokument"), "c:\temp\ole.doc")

请注意,当然,您的文档可能已损坏,这可能解释了问题。

如果您的对象存储在SQL Server中,我宁愿直接打开包含SQL Server二进制数据的ADO记录集,而不是创建链接表并从链接表中打开DAO记录集。

答案 1 :(得分:0)

在Access中,使用所有相关字段创建一个相应的Access Form。使用链接中提供的VBA代码,您应该能够以自动方式导出一些最常见的文件类型。祝好运。 https://medium.com/@haggenso/export-ole-fields-in-microsoft-access-c67d535c958d