VBA的form相关实验2,form里的变量传递和模块里有什么不同?(---未完成-----)

草稿

'1.1 参数的传递,应该还是要以

'Public index1  '传不过去,擦, 这是之前,想把一个form里的变量,传递给其他form 不管用
'怀疑,可能只能public private 只再模块间是这样的
'测试下

'但好方法?,确实先把东西存再excel表,也就是数据库,之后在读,这样安全?
 

感觉存在数据库表里,是个好思路

0 名词解释:

0.1 作用域

  • 常量/变量的作用域
  • 作用域是指这个变量允许在什么地方 使用/ 调用变量。
  • ( 反过来说就是那些程序可以访问到这些变量)
  • 作用域有各种说法
  1. 公有变量/全局变量/跨模块变量     public
  2. 模块级变量                                    private 或 dim
  3. 私有变量/ 过程级变量                   dim 或 static

  • 声明变量的作用域,一定要在模块最开始声明
  • 如果只在模块中间声明,比如某些过程后面,会有问题。因为代码是顺序执行的,没执行到那,那个变量在之前还不是全局变量等,所以要在模块最开始声明

0.2 生存周期:(声明作用域会影响生命周期)

  • 常量/变量的生存周期
  • 变量保留其值的时间,称为生存周期。
  • 生存周期的 start :  赋值的过程,开始生效(也就是即使声明为public,赋值所在的过程,不允许,变量的值还是没被改变,可能还是"")
  • 比如public a1 在模块开始声明时其实已经创建了,但没赋值,还是为空
  • 生存周期的 end  :   赋值的过程,已经结束,回收变量,消灭了。(但是声明public private的变量,在过程结束后,并不回收,而是整个模块(其实是整个workbook关闭了)关闭才会回收)
  • if 常量在模块开头定义和赋值,生存周期就是整个模块加载期间。
  • if 常量定义在过程/函数里,就是过程/函数 生命期内。

  • VBA里一般变量(非静态static变量)都在过程内,赋值,生命期也是,离开这个过程,除非已经调用到内存,否则过程外是不生效的,因为已经回收消灭了。
  • 静态变量与动态变量 动态变量是指被过程调用时均重新初始化的变量,而静态变量在初始化后,下一次调用时仍保留上次的值的变量。

声明变量作用域会影响变量的生命周期的关系

  • 模块级的变量,只要不关表(模块一直在加载)就一直在生效,不会被消灭!。比如public  private dim 定义在模块最开始的地方的( dim定义在过程内的不算模块级变量)
  • 过程级变量,过程运行结束马上消灭,变量每次重置计算,特殊的static记住之前的

下面是网上查的资料

这个  https://blog.csdn.net/qq_25582033/article/details/117427865

比方说你在一个xls文件中有两个工程(应该1个EXCEL表都只有1个工程吧),那么在某个工程中的模块如果不写这个语句,那么两个工程都可以用这个模块的内容。如果写上Option Private Module,那么另外那个工程就不能使用这个模块的内容。

     下面表格里有几个地方是错的,private声明的变量,因为必须在模块顶部(只要是声明在模块顶部的,即使是 dim 或 public private都一样,因为都是模块级变量了),所以一旦过程内运行赋值后,其声明周期不是过程有效期内,而是模块/整个EXCEL的 workbook 文件有效期内都在生效,而并没有被释放消灭。

      下面的代码可以证明

Private Sub tf2()

Debug.Print "x= " & X
Debug.Print "y= " & y
Debug.Print "z= " & z
Debug.Print "z1= " & z1

End Sub

'模块级的,只要不关表就一直在
'过程级马上没,一般变量每次重置计算, static记住之前的
Private Sub tf3()

    X = 1
    y = 111
    z = 222
    z1 = 333
    
End Sub

0.3 即使写了参数调用  和 声明作用域,也得先运行那个程序

因为即使是一个public变量,作用域是全局,但是没有被其他程序赋值改变前,值为空

  • VBA 并不会,自动运行这个变量的相关的其他 block,
  • VBA 和其他代码一样,都是顺序执行的
  • 即使声明了某模块级变量,但是如果还未运行赋值过程给这个 模块级变量,那么这个 模块级变量仍然还是 "" none null nothing 等等,运行了赋值过程后,虽然赋值过程本身消灭了,但是这个模块级变量的值会一直保留,且可以被修改到,这个模块结束(被关闭)之前。

0.4 特殊的静态变量 Static (很适合用来计数--因为模块内不清除)

  • static 变量 特殊性:生命周期效果类模块级变量,但是作用域还是过程级的变量。这么特殊,可能时比public等更安全点
  • VB允许你通过改变声明方式延长当地变量的存活期,这种就是 static 静态变量
  • 很特殊,首先是变量,不是常量  (可改变)
  • 而且仍然是过程级,外部程序无法访问
  • 但是可以在模块结束之前,一直都存在, 生命周期效果类 模块级变量,但是作用域还是过程及的变量。
Const aaa1 = 2
Public Const aaa2 As Integer = 111
Public y
Private z
Dim z1

Sub tf1()

Const aaa5 = 555
'Public Const aaa6 = 666


Debug.Print "aaa1= " & aaa1
Debug.Print "aaa2= " & aaa2
Debug.Print "aaa5= " & aaa5
'Debug.Print "aaa6= " & aaa6

End Sub


Private Sub tf2()

'没法调用过程了里得变量的!只能调用过程。
' 函数特殊,有返回值的函数可以当变量调用,但本质还是 调用函数,只是函数返回值是这样


Debug.Print "x= " & X
Debug.Print "y= " & y
Debug.Print "z= " & z
Debug.Print "z1= " & z1
Debug.Print "z2= " & z2
End Sub


Private Sub tf3()

    X = 1
    y = 111
    z = 222
    z1 = 333
    Static z2
    z2 = z2 + 1
    
    Debug.Print "内部X= " & X
    Debug.Print "内部z2= " & z2
    
    
End Sub

1第1部分,模块内和模块之间的 直接使用和调用

1.1 常量的 直接使用和调用

  • 常量的直接使用,非传递的话,想直接使用只能靠声明
  • 常量一般都是声明了直接使用吧,本身不变,没有什么调用的必要了吧?得查查后以后看

1.2  常量的定义,赋值和生命周期

  • 常量的声明和定义 (声明和定义一般是一块儿,但赋值一般是在计算时才赋值)
  • 常量可以声明,声明在模块开始

  • 常量的赋值
  • 赋值在哪儿,决定了常量的生命周期
  • 如果常量赋值在模块开始,整个模块内都生效,在本模块内常量不会被释放(变量是不允许在 过程外赋值的!)
  • 赋值在过程内,只能在过程内生命周期内有效,过程结束就释放了

Const aaa1 = 2
Public Const aaa2 As Integer = 111



Sub tf1()

Const aaa5 = 555
'Public Const aaa6 = 666


Debug.Print "aaa1= " & aaa1
Debug.Print "aaa2= " & aaa2
Debug.Print "aaa5= " & aaa5
'Debug.Print "aaa6= " & aaa6


End Sub

1.2.1  直接使用常量

  • 直接使用常量,靠常量本身的声明的使用域的范围
  • private 不能跨模块,这个级别声明,只能在本模块内的,不同过程/函数之间用
  • public可跨模块,本模块内所有,其他模块的都能直接使用
  • 本例中,因为取不到其他模块的private内容,a1会被识别为本模块的 过程级变量名,而且因为没定义没赋值,就为空

'----------------此处是模块5,下面是模块6的内容------------------


'1常量
Private Const a1 = 5
Public Const a2 = 5
Public b5

'----------------此处是模块6,下面是模块6的内容------------------


Private Const a3 = 777
Private Const a4 = 778

Private b7
Public b8



Sub test0001()

Debug.Print "调用常量" & "private 不能跨模块,public可跨模块,取不到其他模块的private内容,a1只能识别为本模块的 过程级变量名"
Debug.Print "其他模块的 a1=" & a1
Debug.Print "其他模块的 a2=" & a2
Debug.Print "a3=" & a3
Debug.Print "a4=" & a4
Debug.Print

End Sub

1.3 常量的调用

常量一般都是声明了直接使用吧,本身不变,没有什么调用的必要了吧?

2 变量的使用 和调用

2.1 代码的封装,无法访问 封装内部的变量,只能整体调用

  • 也就是外部代码无法访问封装部分内部的内容,但是可以访问其外部整体调用
  • 那些东西是封装的:过程/函数等完整的block,而不是那种顺序流的
  • 过程/函数封装的内部到底有啥:变量,一些处理逻辑表达式
  • 不能直接调用其他过程内的变量,而只能根据作用域,调用这些过程,并且只能执行这些过程这个动作,并不能引用 那些过程的结果"

2.2 整体调用方式

  • 怎么叫 整体调用,就是调用,过程名,call  t1() 这种 整体调用。
  • 特殊的
  • 但是函数特殊,有返回值的函数可以当变量调用,把   特殊变量 = 函数名(代表函数)
  • 但本质还是 调用函数,只是函数返回值是这样

function t2

t2=XXXX

end function

  • t2= XXXX   相当于return ,只有函数function 可以这样返回,sub 过程不能这样return

2.3 调用过程,也需要看 过程本身的作用域,比如private sub  无法被跨过程调用

  • sub / function 因为本身就存在于模块级,不存在在过程中的可能,所以默认是全局的 public
  • (默认 public ) sub 
  • 可以主动声明为 private sub
  • Option Private Module ,写在模块开头,会设置下面的所有的 过程/函数都是private的

2.4  过程/函数的 作用域和 变量本身作用域 完全无关! 独立的

3  函数和变量的调用

  • 函数包括带返回值,和不带返回值的情况
  • 函数如果不带返回值时,类 sub,基本和sub一样的处理
  • 但是function 带返回值,的情况是不同的

3.1 不带返回值的function 被调用参数时

  • 直接无法访问,其他代码内部的变量,无论时本模块,还是其他模块的
  • 因为访问其他变量的代码,本身是在 过程/函数内,所以,在本过程内,没有这些变量。就会认为是未定义的空变量
  • 如果内存里已经有 其他过程内的变量,声明为 非过程级,比如  整个模块开始处定义的 public private  dim,而且已经运行过其对应赋值过程,内存里变量已经生成,且因为 声明的作用域一直还处于生效期,则可以访问到其值。
  • 特殊情况,如果不是在整个模块开始处定义的 public private  dim,比如下面例子的 public d3 只是在过程前声明,而不是在整个模块开始处声明,则声明无意义。

  • 如果 访问作为整体的 过程,则要i看过程/ 函数本身是否声明为 public private. 一般来说,默认过程/函数 默认都是 public ,也就是可以各个模块都访问。
  • 但是可以强制声明为 private 只让本模块内的其他程序,call 调用他
  • 但是至少最小的调用范围就是private了

'----------------此处是模块5,下面是模块6的内容------------------

'4函数,和变量     函数(函数名)可以作为变量用,有无返回值时
'函数,无返回值
Private Function e1()
     d1 = 6
    Debug.Print "内部 d1= " & d1
End Function


Public Function e2()
     d2 = 6
     Debug.Print "内部d2= " & d2
     
End Function

'----------------此处是模块6,下面是模块6的内容------------------
Public d3

Sub test03()

d3 = 5
d4 = 6
d5 = 7

Debug.Print "内部d3= " & d3
Debug.Print "内部d4= " & d4
Debug.Print "内部d5= " & d5

End Sub



Sub test0004()

Debug.Print "d1= " & d1
Debug.Print "d2= " & d2
Debug.Print "d3= " & d3
Debug.Print "d4= " & d4
Debug.Print "d5= " & d5

End Sub



Sub test0005()

'Call e1     '会报错,子过程 sub 或函数 function 未定义!
Call e2

End Sub

 

3.2 如果函数带返回值了,是一种特殊处理, 变量名= 函数名= 函数返回值return

  • 核心就是特殊处理 :变量名= 函数名= 函数返回值return

sub内的代码,声明周期也是过程级,应该不影响其他吧

  • Application.DisplayAlerts = False  
  • 这个声明的生命周期也应该在sub内,有啥必要非在sub结尾前关闭掉?多此一举把


 

2.2 

'----------------此处是模块5,下面是模块6的内容------------------


'1常量
Private Const a1 = 5
Public Const a2 = 5
Public b5




'2变量
'VBA 变量的声明可以在 过程/函数的内/外,但是赋值只能在过程/函数的 内
'bbb = 555    '报错,无效的外部过程




'3过程和变量,调用过程只能用call
Private Sub t1()
     b1 = 61
'     t1 = 61     '报错,缺少函数/或变量,相当于return ,只有函数可以这样返回,sub 过程不能这样return
     Debug.Print "内部b1= " & b1
End Sub


Public Sub t2()
     b2 = 62
'     t2 = 62      '相当于return ,只有函数可以这样返回,sub 过程不能这样return
      Debug.Print "内部b2= " & b2
End Sub



Sub t3()
     b9 = 69
'     t3 = 63      '相当于return ,只有函数可以这样返回,sub 过程不能这样return
      Debug.Print "内部b9= " & b9
End Sub


'----------------此处是模块6,下面是模块6的内容------------------


Private Const a3 = 777
Private Const a4 = 778

Private b7
Public b8



Sub test0001()

Debug.Print "调用常量" & "private 不能跨模块,public可跨模块,取不到其他模块的private内容,a1只能识别为本模块的 过程级变量名"
Debug.Print "其他模块的 a1=" & a1
Debug.Print "其他模块的 a2=" & a2
Debug.Print "a3=" & a3
Debug.Print "a4=" & a4
Debug.Print

End Sub




Public Sub test01()
    b7 = 111
     Debug.Print "内部b7= " & b7
End Sub

Private Sub test02()

    b8 = 222
     Debug.Print "内部b8= " & b8
End Sub


Sub test0002()


Debug.Print "直接调用其他函数过程里的变量是不行的!封闭性,程/函数 内部的内容都是封装的,外部不能访问,只能整体调用"
Debug.Print "b1=" & b1
Debug.Print "b2=" & b2
Debug.Print "b7=" & b7
Debug.Print "b8=" & b8
Debug.Print "b9=" & b9
End Sub


Sub test0003()
Debug.Print "调用过程/函数,也要看 过程/函数本身的 作用域声明,这个和变量的作用域完全独立"
Debug.Print "一般默认过程/函数,都是模块级的,public 公有的"
Debug.Print "不能直接调用其他过程内的变量,而只能根据作用域,调用这些过程,并且只能执行这些过程这个动作,并不能引用 那些过程的结果"

'Call t1   '非public 过程,无法被这么调用
Call t2
Call t3

Call test01
Call test02

End Sub


'没法调用过程了里得变量的!只能调用过程。
' 函数特殊,有返回值的函数可以当变量调用,但本质还是 调用函数,只是函数返回值是这样

Private Sub tf2()

'没法调用过程了里得变量的!只能调用过程。
' 函数特殊,有返回值的函数可以当变量调用,但本质还是 调用函数,只是函数返回值是这样


Debug.Print "x= " & X
    

End Sub


Private Sub tf3()

    X = 1
    

End Sub

1.2.1 变量的直接使用

1.2.2 变量的调用

  第2是调用

而传递,可以绕开声明,也可以跨过程

形式和实际


 

传递方法

位置参数

名称参数

混合的,名称的在后,好像是


---------

'在模块里试下,在form里试下,在workbook和sheet里试下
'然后再试下,能不能跨这几个

'VBA的一个BUG,修改函数,变量的声明范围后,比如去掉加上public 有时候,需要关掉重开,运行代码才会正常,还按老的,
'VBA,甚至跨模块调用时,赋值也有这种滞后的问题


'调用,常量,变量/函数
'call 过程/函数

-------

然后 form内呢

然后三者互相呢


'在模块里试下,在form里试下,在workbook和sheet里试下
'然后再试下,能不能跨这几个

'VBA的一个BUG,修改函数,变量的声明范围后,比如去掉加上public 有时候,需要关掉重开,运行代码才会正常,还按老的,
'VBA,甚至跨模块调用时,赋值也有这种滞后的问题


'调用,常量,变量/函数
'call 过程/函数

1 先在模块里做了实验


'常量
Private Const a1 = 5
Public Const a2 = 5
Public b5


'过程和变量

Private Sub t1()

     b1 = 6
     t1 = 6
     
End Sub


Public Sub t2()

     b2 = 6
'     t2 = 6 '相当于return ,只有函数可以这样返回,sub 过程不能这样return
     
End Sub


'函数和变量
Private Function f1()
     b3 = 55
     c1 = 6
     f1 = 6
     
End Function


Public Function f2()   '过程/函数 不是默认public吗?
     b4 = 66
     c2 = 6
     f2 = 6 '相当于return
     
     b5 = 777
'Public b6         'vba,声明跨过程/函数级的参数,必须在 过程/函数 外部声明,一般是最开始(理论上使用前声明就行,但放最前面最安全)
'     b6 = 777
     
     
End Function


'函数,无返回值
Private Function e1()

     d1 = 6

     
End Function


Public Function e2()

     d2 = 6

     
End Function






'在模块里试下,在form里试下,在workbook和sheet里试下
'然后再试下,能不能跨这几个



'VBA的一个BUG,修改函数,变量的声明范围后,比如去掉加上public 有时候,需要关掉重开,运行代码才会正常,还按老的,
'VBA,甚至跨模块调用时,赋值也有这种滞后的问题






'调用,常量,变量/函数
'call 过程/函数


Private Const a3 = 777
Private Const a4 = 778

Private b7
Public b8



Public Sub test01()
    b7 = 111
End Sub

Public Function test02()

    b8 = 222

End Function


Sub test001()

Debug.Print "调用常量" & "private 不跨模块,public可跨模块,取不到其他模块的private内容,a1只能识别为本模块的 过程级变量名"
Debug.Print "a1=" & a1
Debug.Print "a2=" & a2
Debug.Print "a3=" & a3
Debug.Print "a4=" & a4
Debug.Print


Debug.Print "调用其他函数过程里的变量" & "都不行,过程/函数 内部的内容()都是封装的,除非return拿到,否则只能靠声明变量拿到"
Debug.Print "b1=" & b1
Debug.Print "b2=" & b2
Debug.Print "b3=" & b3
Debug.Print "b4=" & b4
Debug.Print "b5=" & b5   '参数声明public还不够,还需要函数/过程也 public ?
Debug.Print "b6=" & b6
Debug.Print "b7=" & b7
Debug.Print "b8=" & b8
Debug.Print





Debug.Print "t1=" & t1

'Debug.Print "t2=" & t2    '过程名不能当 变量/函数 这样直接使用,只能call 调用?
                          '这样是变量,不是函数,但是无参数的不是默认自动去掉括号吗?
'Debug.Print "t2=" & t2()

'Call t1
Call t2


Debug.Print "f1=" & f1
Debug.Print "f2=" & f2


'Call f1
Call f2



Debug.Print "e1=" & e1
Debug.Print "e2=" & e2


'Call e1
Call e2





End Sub




'传递参数的几个思路


'存下来传递,存储,文件中,中转


'方法,按位置,按名称







'中转







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值