我有一个来自客户的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