在数据库管理系统中,尤其是对于一些基础资料,可能并不仅仅是文字信息,还可能带有相应的附件(尤其是图片)。对于这种情况,我们的通常做法是将文件放在共享服务器上,然后在数据库中仅记录相应的文件路径,需要的时候通过程序自动调用并进行管理维护。基于该实现思路,快速开发平台提供了一个通用的附件管理模块,让你不必再为附件的添加、修改、删除、查看等功能的实现费脑筋,而只需要简单的调用即可。
该附件管理模块可以和任意数据表进行结合,对一个数据表甚至还可以进行多重展示(如产品是机器,需要将部件分别管理)。
效果预览

附件服务器类型
可以系统设置中进行设置,使用共享文件夹或FTP服务器来存储附件。
使用方法
该模块使用方法相当简单,只需要编辑窗体中添加一个子窗体控件,控件名修改为“sfrAttachments”,其“源对象”属性设为“SysFrmAttachments”,然后在加载和保存数据时,添加一行调用代码即可。

调用函数说明
01 | '函数用途:加载指定附件数据。注意!LoadAttachmentData 不但用于加载已有附件,还用于对附件子窗体进行初始化处理,所以新增模式下也要调用!不能和 LoadRecord 放在一起! |
02 | '参数说明:DataCategory 必需的,和数据表相关的标识,比如“产品表”该参数可以设为“产品照片”,“员工表”该参数可以设为“员工照片”等 。可以任意指定,但一旦确定了就不能改,否则可能会导致数据和文件不能正常关联! |
03 | ' DataID 必需的,设为数据表中的唯一标识 ID 字段的值,如“产品表”该参数对应“产品编号”字段,“员工表”该参数对应“工号”字段。新增模式下可以为Null,该值同样一旦确定就不能改,否则可能会导致数据和文件不能正常关联! |
04 | ' ActiveConnection 可选的,从数据库取数据时用到的 ADO 连接对象,如果未使用事务处理,可以省略该参数。 |
05 | Public Function LoadAttachmentData _ |
06 | ( _ |
07 | DataCategory As String _ |
08 | , DataID As Variant _ |
09 | , Optional ActiveConnection As Variant _ |
10 | ) |
11 |
12 | '函数用途:保存指定附件数据 |
13 | '参数说明:参数和 LoadAttachmentData 函数中的参数意义一样。 |
14 | Public Function SaveAttachmentData _ |
15 | ( _ |
16 | DataCategory As String _ |
17 | , DataID As Variant _ |
18 | , Optional ActiveConnection As Variant _ |
19 | ) |
代码调用示例
在版本v2.6.2.505中,InitData函数需要加入一行代码:
1 | Public Function InitData() |
2 | ClearControlValues Me |
3 | '由于新增模式下保存后Edit窗体不会关闭,所以这里需要再次调用进行重新初始化 |
4 | Call Me .sfrAttachments.Form.LoadAttachmentData( "商品照片" , Me !商品ID) '“商品照片”不能为变量 |
5 | End Function |
01 | Private Sub Form_Load() |
02 | On Error GoTo ErrorHandler |
03 | |
04 | Dim cnn: Set cnn = CurrentProject.Connection |
05 | |
06 | '编辑窗体的其它加载事件代码,此处省略 |
07 | |
08 | If Nz( Me .OpenArgs) <> "" Then |
09 | LoadRecord Me , "SELECT * FROM 商品信息表 WHERE 商品代码='" & Me .OpenArgs & "'" |
10 | '再次强调,LoadAttachmentData 不能在这里调用! |
11 | End If |
12 | ' |
13 | '--------------------------------------------------------------------------------------------- |
14 | '通过这一行代码的调用实现附件的加载 |
15 | '不论是新增还是修改,都要调用 LoadAttachmentData 函数,因为它不光是用来加载已有附件,还用来对附件窗体进行初始化处理。 |
16 | '第1个参数 Category (即下方的"商品照片")必须是一个固定不变的字符串,一般可以用功能模块的名称,不能是变量,否则一旦变化就会导致数据和附件关联不上! |
17 | '第2个参数 DataID 应该取数据的主键,即能确定数据唯一性的值。最好是一生成就不会被修改的值,否则也可能导致数据和附件关联不上! |
18 | '第3个参数 ActiveConnection 如果没有可以省略,默认使用CurrentProject.Connection |
19 |
20 | Call Me .sfrAttachments.Form.LoadAttachmentData( "商品照片" , Me !商品ID, cnn) '“商品照片”不能为变量 |
21 |
22 | '使用不同的子窗体,并且这里第一个参数设成不一样,可以实现多重展示,即同时可以显示多个图片 |
23 | Call Me .sfrAttachments2.Form.LoadAttachmentData( "商品照片_旧款" , Me !商品ID, cnn) '“商品照片_旧款”不能为变量 |
24 | '--------------------------------------------------------------------------------------------- |
25 | |
26 | ExitHere: |
27 | Exit Sub |
28 |
29 | ErrorHandler: |
30 | MsgBoxEx Err.Description, vbCritical |
31 | Resume ExitHere |
32 | End Sub |
33 |
34 | Private Sub btnSave_Click() |
35 | On Error GoTo ErrorHandler |
36 | |
37 | Dim cnn: Set cnn = CurrentProject.Connection |
38 |
39 | '编辑窗体的其它保存按钮单击事件代码,此处省略 |
40 | |
41 | '--------------------------------------------------------------------------------------------- |
42 | '通过这一行代码的调用实现附件的保存 |
43 | Call Me .sfrAttachments.Form.SaveAttachmentData( "商品照片" , Me !商品ID, cnn) '“商品照片”不能为变量 |
44 |
45 | '多重展示时,将第二个子窗体的数据也进行保存 |
46 | Call Me .sfrAttachments2.Form.SaveAttachmentData( "商品照片_旧款" , Me !商品ID, cnn) '“商品照片_旧款”不能为变量 |
47 | '--------------------------------------------------------------------------------------------- |
48 | |
49 | Form_frm商品信息.RefreshDataList |
50 | MsgBoxEx "保存成功!" & vbCrLf & strMsg, vbInformation |
51 | |
52 | If Me .DataEntry Then |
53 | ClearControlValues Me |
54 | Else |
55 | DoCmd.Close acForm, Me .Name, acSaveNo |
56 | End If |
57 | |
58 | ExitHere: |
59 | Set rst = Nothing |
60 | Set cnn = Nothing |
61 | Exit Sub |
62 | |
63 | ErrorHandler: |
64 | MsgBoxEx Err.Description, vbCritical |
65 | Resume ExitHere |
66 | End Sub |
加入版本:v2.0.1
修订记录
2021-06-03 v2.6.0 增加 FTP 支持,可将附件保存到 FTP 服务器上。
2021-08-14 v2.6.2.505 完善示例代码。