作者:绿色风
分类:
时间:2022-08-18
浏览:171
楼主 amulee |
Q:为什么用代码改变代码却没有执行? A:请先下载附件。
代码改代码.rar
附件的VBA中共有两个模块和一个工作表。当我们点击工作表按钮的时候运行模块2中的如下程序。- Sub Call3次()
- ThisWorkbook.VBProject.VBComponents("模块1").CodeModule.ReplaceLine 6, "Range(""C2:C"" & R) = ""=A2*100"""
- MsgBox 1
- Call 试验
- ThisWorkbook.VBProject.VBComponents("模块1").CodeModule.ReplaceLine 6, "Range(""D2:D"" & R) = ""=A2*10000"""
- MsgBox 2
- Call 试验
- End Sub
很显然,上述程序是更改模块1的代码后并运行的,一共运行两次。模块1代码如下:- Sub 试验()
- Dim R&
- R = [A65536].End(3).Row
- [B:F].ClearContents
- For i = 1 To R
- Range("D2:D" & R) = "=A2*10000"
- Range("b2:b" & R) = "=A2*10"
- Next
- End Sub
我们点击按钮后可以发现,C列的公式都是A列乘以100,而D列为空。我们看第一段代码,他的作用是将模块1中以下语句替换:- Range("D2:D" & R) = "=A2*10000"
第一次替换成- Range("C2:C" & R) = "=A2*100"
第二次又恢复原样。
但是程序根本没有执行第二次替换后的试验程序,仅执行的是第一次替换后的程序,这是为什么呢?
原来,在VBA运行的之前,系统做一些事情,就是将我们编写的代码转换成机器语言,装入内存,然后执行。这个转换的过程就称为编译。编译的时候,程序进行查错、语法分析等等一系列工作,最终转换成了可以让机器执行的二进制代码。
在VBA中,编译有一些特性: 1、在直接运行程序时(即直接点击按钮),系统会先编译主程序,只要主程序不出错就会运行程序。如上例,我们第一段代码并没有错误,所以系统就运行了。当语句运行到子程序(即主程序中调用其它程序)的时候,再编译子程序。然后在运行。当第二次运行相同名称的子程序的时候不再进行编译,因为这个时候该程序已经在内存中,为了提高效率系统不再编译,就直接运行了该程序。 这样就解释了我们直接执行Call3次程序的时候,系统只进行了第一次代码的替换工作。其实不然,系统确实进行了两次代码替换工作,只是第二次替换后的代码并没有进行编译,而是运行了第一次替换后的代码。
这个过程如下: 编译主程序→运行代码→(执行到子程序时候)编译子程序(这个时候子程序的代码已经替换)→运行子程序→跳出子程序继续运行代码→第二次运行子程序(不再进行编译,而是直接运行。所以运行的代码并非第二次替换后的代码,而是第一次替换后的代码)
2、当先编译,再运行的时候。系统会编译主程序和子程序,将上述编译后的机器码直接装载到内存。然后再运行的时候,机器执行的是什么呢?就是一次都没有替换过的代码。
我们可以试验一下,在VBE中点击调试→编译,然后再运行看看结果呢?是不是这样呢?
我们了解了VBA程序的运作原理之后,就可以明白为什么上述第二次的替换为什么没有执行。其实替换代码是执行了,只是运行的时候没有运行那个已经替换了的代码。 |
2楼 eliane_lei |
进来学习!楼主真的很
|
免责声明
有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素,
经与ExcelTip.Net站长Apolloh商议并征得其同意,
现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示,
供有需要的人士查询使用,也慰缅曾经的论坛时代。
所示各个帖子的原作者如对版权有异议,
可与本人沟通提出,或于本站点留言,我们会尽快处理。
在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一