Access编程交流网
  • 设为首页|收藏本站|繁体中文|手机版
  •     
  • Access培训-Access开发平台-Access行业开发

  • 首页
  • 资讯
  • 技巧
  • 源码
  • 行业
  • 资源
  • 活动
  • 关于

技巧

ACCESS数据库

启动/设置/选项/背景

修复/压缩

安全/加密/解密

快捷键

版本升级/其它等

数据表

命名方式/设计规范

表设计

查询

Sql语言基础

选择查询

更新查询

删除查询

追加查询

生成表查询

交叉表查询

SQL特定查询

查询参数

查询综合应用

界面/窗体/控件

标签

文本框

命令按钮

组合框/列表框

选项组/复选框/选项按钮

选项卡

子窗体

窗体本身/综合应用

其它

报表打印

报表设计

高级报表

模块/函数/VBA/API/系统

VBA基础

内置函数

调试/跟踪/Debug

模块/类模块

API/COM/系统相关

字符数字日期

网络通信游戏

加密解密安全

文件处理

经典算法

宏/菜单/工具栏/功能区

宏/脚本

菜单/工具栏

功能区/Ribbon

图表/图形/图像/多媒体

图表

图形/图像

音频

视频/动画

DAO/链接表/ADO/ADP

DAO/链接表/ODBC

ADO/RDO

ADP

ActiveX/第三方控件/插件

Treeview树控件

ListView列表控件

Toolbar工具栏控件

微软其它控件

Dbi-Tech

CodeJock

Grid++Report

FastReport

ComponentOne

加载项/插件/Addin

OFFICE集成/导入导出/交互

Excel导入导出/交互

Word导入导出/交互

PPT交互

Outlook控制/邮件

Text文本文件/INI/CSV

PDF/SWF/XML格式

CAD格式

Sharepoint/其它Office

SqlServer/其它数据库

表

视图

存储过程/触发器

函数

用户/权限/安全

调试/维护

SqlServer其它/综合

发布/打包/文档/帮助

开发版/运行时

打包/发布/部署

开发文档/帮助制作

Access完整行业系统

采购管理系统

销售管理系统

仓库管理系统

人力资源管理HRM

CRM管理系统

MRP/ERP管理系统

BRP/流程优化

其它管理系统

心得/经验/绝招
其它/杂项
Excel技巧

Excel应用与操作

Excel开发编程

Word技巧

Word应用与操作

Word开发编程

Outlook技巧

Outlook应用与操作

Outlook开发编程

热门文章

  • Access如何为不够位数..
  • 判断窗体是否打开的两种方法
  • access求出某个数值靠..
  • 求某月的最后一天的函数
  • Access限制文本框的输..
  • 一个简单的小写金额转中文的..

最新文章

  • Access或VB VBA..
  • 关于VBA的0、""(空字..
  • Access导出函数Out..
  • Access日期与日期区间..
  • RecordSource ..
  • Access子窗体事件控制..

联系方式

Access交流网(免费Access交流)

QQ:18449932 

网  址:www.access-cn.com

当前位置:首页 > 技巧 > 模块/函数/VBA/API/系统 > VBA基础
VBA基础

从表的OLE字段中读写文件

'---------------------------------【问题症状】----------------------------------------

如何读写OLE字段, 即保存文件到表中OLE字段中,并可读出来,释放到文件


'---------------------------------【专家解答】----------------------------------------


方法一:

tmtony:

保存文件到字段:

Public Function SaveFileToField(ByRef fld As ADODB.Field, DiskFile As String) As Boolean

On Error GoTo ErrorHandle

    Const BLOCKSIZE = 4096
    Dim byteData() As Byte '定义数据块数组
    Dim NumBlocks As Long '定义数据块个数
    Dim FileLength As Long '标识文件长度
    Dim LeftOver As Long '定义剩余字节长度
    Dim SourceFile As Long '定义自由文件号
    Dim I As Long '定义循环变量
    SourceFile = FreeFile '提供一个尚未使用的文件号
    Open DiskFile For Binary Access Read As SourceFile '打开文件
    FileLength = LOF(SourceFile) '得到文件长度
    If FileLength = 0 Then '判断文件是否存在
    Close SourceFile
    MsgBox DiskFile & "无 内 容 或 不 存 在 !"
    Else
    NumBlocks = FileLength \ BLOCKSIZE '得到数据块的个数
    LeftOver = FileLength Mod BLOCKSIZE '得到剩余字节数
    fld.Value = Null
    ReDim byteData(BLOCKSIZE) '重新定义数据块的大小
    For I = 1 To NumBlocks
    Get SourceFile, , byteData() ' 读到内存块中
    fld.AppendChunk byteData() '写入FLD
    Next I
    ReDim byteData(LeftOver) '重新定义数据块的大小
    Get SourceFile, , byteData() '读到内存块中
    fld.AppendChunk byteData() '写入FLD
   
    Close SourceFile '关闭源文件
    End If
        SaveFileToField = True
        Exit Function
   
ErrorHandle:
        SaveFileToField = False
        MsgBox Err.Description, vbCritical, "写入数据出错!"
   
End Function

保存字段内容到文件:

Public Function GetFileFromField(blobColumn As ADODB.Field, ByVal FILENAME) As Boolean
Dim FileNumber      As Integer      '文件号
Dim DataLen             As Long         '文件长度
Dim Chunks              As Long         '数据块数
Dim ChunkAry()      As Byte         '数据块数组
Dim ChunkSize       As Long         '数据块大小
Dim Fragment        As Long         '零碎数据大小
Dim lngI                As Long '计数器
   
        On Error GoTo ErrorHandle
        GetFileFromField = False
        ChunkSize = 2048                    '定义块大小为 2K
        If IsNull(blobColumn) Then Exit Function
   
        DataLen = blobColumn.ActualSize         '获得图像大小
        If DataLen < 8 Then Exit Function   '图像大小小于8字节时认为不是图像信息
            FileNumber = FreeFile               '产生随机的文件号
        Open FILENAME For Binary Access Write As FileNumber     '打开存放图像数据文件
        Chunks = DataLen \ ChunkSize        '数据块数
        Fragment = DataLen Mod ChunkSize    '零碎数据
        If Fragment > 0 Then            '有零碎数据,则先读该数据
                ReDim ChunkAry(Fragment - 1)
                ChunkAry = blobColumn.GetChunk(Fragment)
                Put FileNumber, , ChunkAry      '写入文件
        End If
   
        ReDim ChunkAry(ChunkSize - 1)             '为数据块重新开辟空间
        For lngI = 1 To Chunks                              '循环读出所有块
                ChunkAry = blobColumn.GetChunk(ChunkSize)   '在数据库中连续读数据块
                Put FileNumber, , ChunkAry()    '将数据块写入文件中
        Next lngI
        Close FileNumber            '关闭文件
        GetFileFromField = True
        Exit Function
ErrorHandle:
        GetFileFromField = False
        MsgBox Err.Description, vbCritical, "读取数据出错!"
End Function

 

 


方法二:

笨小漆:
 


如何将文件保存在OLE字段里(OLE写入/读出)?
OLE文件读入和读出

支持的类型使所有文件,当然,你在读入数据的时候,最好做一个字段保存文件的类型,在保存文件的时候,就可以根据类型选择要保存的类型了。


Option Compare Database
Option Explicit

Public Function GetFromFile(strTable As String, strField As String, strFilter As String, objFileName As String) As Boolean

'============================================================
' 过程函数名: CommModule.GetFromFile 类型:Function
' 参数:
'     strTable (String)  :准备保存图形数据的表名称
'     strField (String)  :准备保存图形数据的字段名称
'     strFilter (String)  :打开表的过滤字符串,用于定位并确保被打开的表的数据的唯一性
'     objFileName (String) :准备输入到表里边的图象文件名称
' 返回:如果保存成功,返回True,如果失败,返回False
'-------------------------------------------------------------
' 说明:把图象文件的数据保存到表里边
'-------------------------------------------------------------
' 修订历史:
'=============================================================
Dim recset   As ADODB.Recordset, FileData() As Byte, FileNo As Long, FileSize As Long, strSQL As String

  strSQL = "Select " & strField & " From " & strTable & " Where " & strFilter & ";"
  Set recset = New ADODB.Recordset
  recset.Open strSQL, CurrentProject.Connection, adOpenDynamic, adLockOptimistic
  GetFromFile = True
  If recset(strField).Type <> DB_OLE Or Not IsFileName(objFileName) Then
    GetFromFile = False     '如果字段不是OLE字段,或者文件不存在,返回错误
    GoTo EndGetFromFile
  End If
  If recset.EOF Then       '如果记录不存在,返回错误
    GetFromFile = False
    GoTo EndGetFromFile
  End If
  FileSize = GetFileSize(objFileName) '如果被打开的文件大小为零,返回错误
  If FileSize <= 0 Then
    GetFromFile = False
    GoTo EndGetFromFile
  End If
  ReDim FileData(FileSize)      '重新初始化数组
  FileNo = FreeFile          '获取一个空闲的文件号
  Open objFileName For Binary As #FileNo '打开文件
  Get #FileNo, , FileData()      '读取文件内容到数组
  Close #FileNo            '关闭文件
  recset(strField).value = FileData() '保存数据
  recset.Update            '更新数据
  Erase FileData           '释放内存
EndGetFromfile:
  recset.Close            '关闭RecordSet
  Set recset = Nothing        '释放内存
End Function

Public Function SaveToFile(strTable As String, strField As String, strFilter As String, strFileName As String) As Boolean
'============================================================
' 过程函数名: CommModule.SaveToFile 类型:Function
' 参数:
'     strTable (String)  :保存图形数据的表名称
'     strField (String)  :保存图形数据的字段名称
'     strFilter (String)  :打开表的过滤字符串,用于定位并确保被打开的表的纪录的唯一性
'     strFileName (String) :准备保存的图象的文件名称
' 返回:如果保存成功,返回True,如果失败,返回False
'-------------------------------------------------------------
' 说明:把由GetFromFile函数保存到表中OLE字段的数据还原到文件
'-------------------------------------------------------------
' 修订历史:
'=============================================================
Dim recset   As ADODB.Recordset, FileData() As Byte, FileNo As Long, FileSize As Long, strSQL As String

  strSQL = "Select " & strField & " From " & strTable & " Where " & strFilter & ";"
  Set recset = New ADODB.Recordset
  recset.Open strSQL, CurrentProject.Connection, adOpenDynamic, adLockOptimistic
  SaveToFile = True
  If recset(strField).Type <> DB_OLE Then
    SaveToFile = False     '如果字段不是OLE字段,返回错误
    GoTo EndSaveToFile
  End If
  If recset.EOF Then       '如果记录不存在,返回错误
    SaveToFile = False
    GoTo EndSaveToFile
  End If
  FileNo = FreeFile
  Open strFileName For Binary As #FileNo
  ReDim FileData(recset(strField).ActualSize) '重新初始化数组
  FileData() = recset(strField).GetChunk(recset(strField).ActualSize) '把OLE字段的内容保存到数组
  Put #FileNo, , FileData()  '把数组内容保存到文件
  Close #FileNo
  Erase FileData
EndSaveTofile:
  recset.Close
  Set recset = Nothing
End Function


MsAccess补充:非常感谢,另两点建议,不知妥否: 

1.recset(strField).Type <> DB_OLE Or Not IsFileName(objFileName) 可改为
recset(strField).Type <> 205 Or Dir(objFileName) = ""

2.GetFileSize(objFileName) 可改为
FileLen(objFileName)

zhuyiwen补充:

在ADP中,对应 image 字段。

recset(strField).Type <> DB_OLE Or Not IsFileName(objFileName) 要改为

recset(strField).Type <> adLongVarBinary Or Dir(objFileName) = ""

 

方法三:

cg1提供:一个mdb文件,可以自动把所有的需要调用的文件解包到指定目录。不用ole字段完全可以做到。

ole控件的名字.Action = acOLEActivate

记得把rar自解压缩包存到窗体的ole控件里面哈


方法四:


将ADO数据库中的图象拷贝到文件中
Private Function GetRandomFileName(sDirTarget As String, _
sPrefix As String, _
sExtention As String) As String

'Generates a unique temp file name for the specified directory
'with the specified extention
On Error Resume Next
Dim fs As FileSystemObject ' **** requires filesystem object
Dim sFName As String
Dim iRnd As Long
Dim iUpperBound As Long, iLowerbound As Long

TRYAGAIN:

Randomize
iUpperBound = 99
iLowerbound = 0
iRnd = Int((iUpperBound - iLowerbound + 1) * Rnd + iLowerbound)

sFName = CStr(iRnd) + CStr(DatePart("d", Now())) _
+ CStr(DatePart("h", Now())) _
+ CStr(DatePart("n", Now()))

sFName = sPrefix + sFName + "." + sExtention

Set fs = New FileSystemObject

If Not fs.FileExists(sDirTarget + "\" + sFName) Then
GetRandomFileName = sDirTarget + sFName
Exit Function
Else
GoTo TRYAGAIN
End If

End Function

Public Function CopyImageField(fld As ADODB.Field, _
fldTO As ADODB.Field)

'This function takes the source field image and copies it
'into the destination field.
'The function first saves the image in the source field to a
'temp file on disc. Then reads this temp file into
'the destination field.
'The temp file is then deleted
On Error Resume Next

Dim iFieldSize As Long
Dim varChunk As Variant
Dim baData() As Byte
Dim iOffset As Long
Dim sFName As String
Dim iFileNum As Long
Dim cnt As Long
Dim z() As Byte

Const CONCHUNKSIZE As Long = 16384

Dim iChunks As Long
Dim iFragmentSize As Long

'Get a unique random filename
sFName = GetRandomFileName(App.Path, "pic", "tmp")

'Open a file to output the data to
iFileNum = FreeFile
Open sFName For Binary Access Write Lock Write As iFileNum

'Copy the logo to a variable in chunks.
iFieldSize = fld.ActualSize
iChunks = iFieldSize / CONCHUNKSIZE
iFragmentSize = iFieldSize Mod CONCHUNKSIZE
If iFragmentSize > 0 Then
' if there is a frag then write it first, else just use chunk
ReDim baData(iFragmentSize)
baData() = fld.GetChunk(iFragmentSize)
Put iFileNum, , baData()
End If

'Fragment added; Now write rest of chunks
ReDim baData(CONCHUNKSIZE)
For cnt = 1 To iChunks
baData() = fld.GetChunk(CONCHUNKSIZE)
Put iFileNum, , baData
Next cnt

'Close file
Close iFileNum

'Now we have the file on disk Load the pic from
'the temp file into the other field

Open sFName For Binary Access Read As #1
ReDim z(FileLen(sFName))
Get #1, , z()
fldTO.AppendChunk z
Close #1

'Delete the file
Kill (sFName)

End Function
返回

 

'---------------------------------【专家点评】----------------------------------------  

cg1:以下代码是将文件以二进制存储在OLE字段中,与手动(右键单击OLE字段,选"插入对象")将文件嵌入到OLE字段中是不同的。以二进制方法存储文件无法直接在字段中编辑,必须读出存为文件才能编辑,编辑完成后再写入到OLE字段中。

tmtony:如果要读取手动插入的文件,请参考tmtony《Access专家门诊》一书中有关OLE字段内容剖析的文章

 

 

 


 

发布人:tmtony-Access中国  
分享到:
点击次数:  更新时间:2005-02-04 13:33:34  【打印此页】  【关闭】
上一条:获取程序所在的目录及全名【AKB00001】  下一条:如何隐藏/显示某个表或者其他数据库对象



相关文章

  • • Access或VB VBA判断数组的值是否为空的几种方法
  • • 关于VBA的0、""(空字符串)、Null、Empty、与 Nothing 的区别
  • • Access导出函数OutPutto解释
  • • Access日期与日期区间的筛选
  • • RecordSource SourceObject ControlSource属性的区别
  • • Access子窗体事件控制父窗体
  • • 事件​change和AfterUpdate的区别
  • • 代码修改完善方法示例(初学者必读)

热门文章

  • [2004-11-23] 获取唯一的文件名access数据库
  • [2017-01-05] VBA 的 Format 函数用法大全access数据库
  • [2005-01-31] 求教 急急急access数据库
  • [2006-11-17] Access权限 判断函数access数据库
  • [2004-11-23] 如何取得WINDOWS和ACCESS的安装目录access数据库
  • [2003-12-20] 获取文件后缀access数据库

热门产品

公司动态|在线留言|在线反馈|友情链接|会员中心|站内搜索|网站地图

中山市天鸣科技发展有限公司 版权所有 1999-2023 粤ICP备10043721号

QQ:18449932

Access应用 Access培训 Access开发 Access平台

access|数据库|access下载|access教程|access视频|access软件

Powered by MetInfo 5.3.12 ©2008-2025  www.metinfo.cn