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



我有一个来自客户的MS SQL数据库,带有访问应用程序。

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

我试图从数据库中获取字节并将它们保存到磁盘。 对于某些文件,这有效,而对于某些文件则无效。 (图像不起作用,zips工作,word文件要打开,但word必须恢复它们)

我发现 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

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

这里出事了...

我的完整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:tempole.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数据库...不是访问数据库。有一些工具也许可以用访问数据库来表达。但不是麻省理工学院 MS SQL

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

使用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:tempole.doc")

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

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

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

最新更新