这是我自己测试,并学习了网络材料后整理的结论。
参见msdn:高级变量主题,理解变量的范围。
未测试类模块。未测试工程组。(请大家指正。)
首先,在“相同范围”内(比如同一个过程中,同一个模块的声明部分)不能两次定义同名变量或常量(模块和其中的过程不是严格的“相同范围”)。
其次,
1.窗体模块的声明部分,
对模块以外来说,
定义的变量,
如果是public定义的(不能用global),则可以被其他窗体和bas模块使用(读取和赋值),但必须加上该窗体模块的名字。
如果是private和dim定义的,则根本不能被其他窗体和bas模块使用。
定义的常量,
只能写const或private const,根本不能被其他窗体和bas模块使用。
对模块以内来说,
对于该窗体内部的各过程来说,窗体模块的声明部分定义的变量无论是public、private还是dim,以及定义的常量,都是相同的情况,即,如果各过程中先使用了这个变量、常量,那么就不能在过程中再定义,但如果过程中还没有使用这个变量、常量,就可以再定义同名变量、常量而使用,而互不干扰。
2.bas模块的声明部分,
对模块以外来说,
定义的变量和常量,
如果是global、public定义的,则可以被其他窗体和bas模块直接使用,但是“其他窗体和bas模块”必须没有在声明部分用任何语句定义过同名变量和常量,否则只能加上该bas模块的名字才能使用。如果有多个bas模块都定义了可直接使用的变量和常量,则直接使用时发生二义性错误。
如果是private和dim定义的(常数不能用dim定义,只有const则相当于private const),则根本不能被其他窗体和bas模块使用。
对模块以内来说,
对于该bas模块内部的各过程来说,模块的声明部分无论用何种语句定义的变量和常量,都是相同的情况,即,如果各过程中先使用了这个变量、常量,那么就不能在过程中再定义,但如果过程中还没有使用这个变量、常量,就可以再定义同名变量、常量而使用,而互不干扰。
3.在窗体模块、bas模块的各过程内部定义的,只能用dim、static定义变量,用const定义常量,只在该过程内部有效。过程内部(在用到这个变量常量时还)没有定义的,则先去找本模块声明部分定义的,如果还没有,则去找其他bas模块声明部分定义的而且可以对外直接使用的。找到以后就不能在过程中再定义同名变量。
4.事件过程的参数须依照事件本身的描述,不可改变。通用过程sub和函数function中的参数使用情况,第一、不能定义形参(虚参)。第二、对于形参的赋值不会改变传值的实参(反过来说,如果sub、function中能够对这个实参赋值,比如它是一个模块级变量、用其本身的名称对其赋值,也不会影响对形参的计算),但能改变传地址的实参(sub和function默认都是byref传地址。如果实参是控件的属性比如text1.text则不会变化,除非直接对其赋值)。第三、如果出现形参以外的参数名,则按上面一条中的顺序去找参数的定义。
5.综上所述,
①如果不希望各窗体、bas模块的变量和常量有任何互相影响的,则在各窗体、bas模块的声明部分都用private定义变量和常量。(窗体的控件属性只要加窗体名字就可以使用(读取和赋值,如果可以赋值的话),和怎么定义变量没关系。)
②如果允许窗体变量被其他窗体和bas模块加窗体名字使用的,则在该窗体声明部分用public定义变量。
③如果希望某个bas模块的变量常量直接被其他窗体和bas模块使用的(相当于“全局变量”),则在该bas模块声明部分应该用global、public来定义,而且其他窗体和bas模块的声明部分和具体使用的过程中都没有定义同名变量常量。
④如果希望模块内的某变量常量被模块内各过程使用的,则在该模块声明部分用private、dim定义,而且具体使用的过程中都没有定义同名变量常量。
⑤过程中类似于i、j、k、temp等循环变量、临时变量,最好要么只在模块的声明部分用private、dim定义,要么只在各过程开始的地方定义。
总的来说,应该尽量避免各处的变量常量、过程函数、控件同名。至少要意识到可能会有问题,这样出现问题的时候容易找到原因。