再次声明,这不是俺的原创,是站在别人的肩膀上,稍加改进!
一直以来,EXCEL文件封装成EXE文件是大家(特别是初学者)关心的话题.坛子里也有许多相关的帖子。但容易出现封装成功,却无法保存EXCEL文件封装之后更新的内容。
本人经过试验通过,代码正常。
[除非你的EXCEL不支持API,否则一定行。若EXCEL暂时不支持API,偶暂时想到的方法是重新安装EXCEL。重新安装EXCEL后就可能支持API了]
原因是封装后的EXE文件在驻留内存时是无法对它进行更新的。所以要对它进行更新只有将它请出内存。方法是调用windows的Taskkill命令。
在进程中增加:shell "TaskKill /im " & &" /f ",注意中间的几个空格不能少。
总结,对要封装的EXCEL文件,首先得在原有的代码基础上增加以下代码到对应的过程中。
一、公共部分(就是ThisWorkBook的代码区最顶端)加入以下代码,用于声明和引用:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const EXE_SIZE = 163840 '此处数字为EXE文件字节数,一定要和EXE文件头的字节数对应。切记
Private Type FileSection
Bytes() As Byte
End Type
二、在Workbook_BeforeClose过程中必须有如下代码。自己原有的代码请参照加入。
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.ScreenUpdating = True
Application.DisplayAlerts = False
ThisWorkbook.Save '文件存盘
Dim myfile As FileSection '定义变量
Dim exec, xlsc, exen As String '定义变量 增加了一个进程名定义exen
Application.Visible = False '隐藏EXCEL主窗口
exec = Worksheets("Temp").Cells(1, 1).Value
xlsc = Worksheets("Temp").Cells(2, 1).Value
exen = Split(exec, "\")(UBound(Split(exec, "\")))
Open exec For Binary As #1 '打开EXE文件
ReDim myfile.Bytes(1 To EXE_SIZE)
Get #1, 1, myfile.Bytes '取得固有文件头
Close #1 '关闭打开的EXE文件
Shell "taskkill /im " & exen & " /f" '强制结束EXE文件
Open exec For Binary As #1 '重新生成新的EXE文件
Put #1, 1, myfile.Bytes ''把原EXE文件文件头写进新的文件头
Open xlsc For Binary As #2 '打开xls临时文件
ReDim myfile.Bytes(1 To FileLen(xlsc))
Get #2, 1, myfile.Bytes
Put #1, EXE_SIZE + 1, myfile.Bytes '将xls部分追加进EXE
Close #1
Close #2
ActiveWorkbook.ChangeFileAccess xlReadOnly ' 将活动工作簿设为只读,便于执行下面的语句,如不进行此操作,将没法完成
Kill ActiveWorkbook.FullName '删除当前文件,其实是一个临时文件
Application.Quit
End Sub
提示:在对EXCEL文件进行完编辑之后,先保存,然后一定要非正常退出,避免因为触发Workbook_BeforeClose事件,而执行Kill ActiveWorkbook.FullName这一句而删除EXCEL文件。这就是为什么出现EXCEL文件“蒸发”在原因。
非正常退出的方法:(两种办法均可,前提是先确保已经存盘)
1、 一种方法是调用WINDOWS的任务管理器,强制结束EXCEL进程。
2、 另一种方法是,在VBE的立即窗口下,执行以下语句:
Application.EnableEvents =False ,然后再关闭EXCEL文件即可!