Access导入卡在“正在复制记录”是Jet/ACE引擎对大表单事务写入的瓶颈,需分批插入、剥离OLE字段、暂删索引并优先选用MDB格式。
Access导入卡在“正在复制记录”不动了怎么办
本质是 jet/ace 引擎对大表(尤其 >10 万行或含 ole/附件字段)的单事务写入瓶颈,不是网络或磁盘问题。它会锁整个目标表、缓存全量数据再刷盘,内存吃满就假死。
- 立刻停止操作,别反复重试——重复失败会加剧临时文件碎片
- 检查
Temp目录空间(通常是C:\Users\{user}\AppData\Local\Temp),不足 2 倍源文件大小就必然卡住 - 关闭所有 Office 进程,特别是后台运行的
MSACCESS.EXE或EXCEL.EXE,它们会争抢 Jet 共享内存
用 DAO.Recordset 分批插入比“导入向导”快 5 倍以上
导入向导强制走完整事务 + 索引重建;DAO 手动控制批次可绕过大部分开销。关键不是“换工具”,而是放弃“一次性塞完”的执念。
- 每批控制在
500–2000行之间:太少则事务开销占比高,太多易触发内存溢出(尤其有长文本字段时) - 插入前执行
DoCmd.SetWarnings False,结束后再设为True,否则每条INSERT都弹确认框 - 目标表提前删掉非必要索引和关系约束,导入完成后再重建——
CREATE INDEX比边插边建快一个数量级
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("SELECT * FROM [SourceTable]", dbOpenSnapshot)
Do While Not rs.EOF
CurrentDb.Execute "INSERT INTO TargetTable (a,b,c) VALUES (" & rs!a & ",'" & rs!b & "','" & rs!c & "')", dbFailOnError
rs.MoveNext
If rs.AbsolutePosition Mod 1000 = 0 Then DoEvents '防界面冻结
Loop
OLE 对象(图片/文件)字段是性能黑洞,必须剥离
Access 存 OLE 不是存路径,而是把二进制流嵌进数据库页,导入时会逐字节解包+校验+重组,1MB 文件可能拖慢整张表 10 分钟。
- 用 VBA 提前遍历源表,把
OleObject字段内容用rs.Fields(i).Value取出,保存为文件,字段只留路径字符串 - 目标表对应字段类型必须改为
Text(255 字符够存相对路径),绝不能保留OLE Object类型 - 如果必须保留原始 OLE,改用
ADODB.Stream手动写入,但成功率低、兼容性差,仅限 Access 2010+ 且不推荐
ACCDB 和 MDB 格式对大导入的实际影响
ACCDB 并不比 MDB “更快”,反而因启用加密、用户级安全等默认特性,在无必要时更慢。很多人以为升级格式能解决问题,其实只是错觉。
- 纯数据导入场景下,MDB(Jet 4.0)引擎更轻量,
dbSeeChanges参数兼容性更好,建议优先用 MDB - ACCDB 的
Attachment字段类型看似合理,但批量插入时会触发额外元数据写入,比普通文本字段慢 3–4 倍 - 若必须用 ACCDB,请在导入前关闭数据库选项里的“启用数据库加密”和“使用用户级安全”,这两项会显著拖慢写入吞吐
Access 大表导入真正的复杂点不在语法或步骤,而在于你得亲手拆解“一张表”这个概念——把它切成可管理的块,把字段按行为重新分类,甚至要主动放弃某些看起来“本该有”的功能(比如实时索引、OLE 存储)。没人替你做这个判断,工具也不会提醒。










