一、默認屬性數組
VB6.0有默認屬性的特性。當沒有給對象指定具體的屬性時,"默認屬性"是VB6.0將使用的屬性。在某些情形下,省略經常使用屬性名,使代碼更爲精簡。瀏覽器
由於CommandButton的默認屬性是Value,因此下面兩句代碼是等價的:工具
1 Sub Test() 2 Debug.Print UserForm1.CommandButton1 '輸出Falue 3 Dim a 4 a = UserForm1.CommandButton1 5 Debug.Print a '輸出False 6 End Sub
而從F2對象瀏覽器中,能夠看到Value確實是CommandButton的缺省成員(默認屬性)——屬性圖標也和其它不一樣,左上角多了一個小圓圈。spa
另外一些狀況,假如咱們須要的是對象自己,而不是它的某個屬性,好比咱們想要把CommandButton1這個對象自己賦值給一個變量,就要使用Set 「顯式」 聲明:3d
1 Sub Test() 2 Dim cmd As MSForms.CommandButton 3 Set cmd = UserForm1.CommandButton1 4 End Sub
當一個對象不存在默認屬性,得到對象自己是否須要使用set?答案是確定的,將一個對象賦值給變量,必須使用Set關鍵字:Set a = Sheet1 code
二、動態數組Variantorm
定義動態數組:(沒有初始化長度)對象
Dim arr() As Integer '元素爲整型的動態數組 blog
Dim brr() As Variant '元素爲variant類型的動態數組
Dim crr() '元素爲variant類型的動態數組 索引
動態數組的特性之一:可被同一類型的靜態數組初始化(賦值)
1 Sub Test() 2 Dim arr() As Integer 3 Dim brr(1 To 3) As Integer '靜態數組 4 brr(1) = 1 5 brr(2) = 2 6 brr(3) = 3 7 arr = brr 8 Dim crr() As Variant 9 Dim drr(1 To 3) As Variant 10 drr(1) = 1 11 drr(2) = True 12 drr(3) = "張三" 13 crr = drr 14 End Sub
若是靜態數組和動態數組的元素類型不一致,則產生錯誤。下面的代碼報編譯錯誤「不能給數組賦值」。
1 Sub Test() 2 Dim arr() 3 Dim brr(1 To 3) As Integer 4 arr = brr '不能給數組賦值 5 End Sub
三、利用Range的Value屬性和Variant()接收單元格區域的值
Range是一個區域時,它的Value返回一個靜態Variant(),而動態Variant()是但是接收這個返回值的。
1 Sub Test() 2 Dim arr() 3 arr = Range("A1:A5").Value 4 arr = ThisWorkbook.Worksheets(1).Range("A1:A5").Value 5 End Sub
實際寫VBA代碼時,更可能是像下面這樣,使用variant變量達到相同效果:
1 Sub Test() 2 Dim arr 3 arr = Range("A1:A5") 4 arr = ThisWorkbook.Worksheets(1).Range("A1:A5") 5 End Sub
這樣的寫法沒有屬性的顯式調用,可能許多人會認爲利用了Range對象的默認屬性,這個默認屬性會讓人以爲是Value或Value2。
四、Range對象的默認屬性是什麼?
入門VBA的時候,絕多數人都說Value是Range對象的默認屬性,因此下面這樣寫,大多數人認爲是省略Value的寫法:
1 Sub Test() 2 Dim arr() 3 arr = Range("A1:A5") 4 End Sub
而這個說法有多是錯的。實際上,可能_Default 纔是Range的默認屬性
一、_Default屬性兩個參數都是可選的。意味着兩個參數均可以沒有。而這個屬性的返回值沒有定義,意味着它能夠是Variant()或Variant。
二、Range("A1")和Range("A1").Value,從截圖中可猜想上例的狀況並非省略了Value的寫法。
三、_Default是Range對象的默認屬性,並且是沒有名字的。(僅僅是推測,能夠有不取名字的屬性麼?)
推測證據1:
[題外話:worksheets也有一個_Default默認屬性,事實上,發現集合類對象幾乎都有_Default默認屬性(用做索引)。可自行求證]
下面這些寫法是成立的:
Debug.Print Range("A1:A5")(2, 1)
Debug.Print Range("A1:A5")(1)
推測證據2:
咱們經常使用Cells(index,index)的方式表示一個單元格。那這個表示法是從何而來呢?Cells屬性自己並無參數,見圖:
但Cells屬性返回的是Range對象,Range對象的默認屬性即_Default:
5、Object類型和一個保留問題
使用默認屬性經常會見到這樣的問題:
正常運行的代碼A
1 Sub Test1() 2 Dim arr() 3 arr = Range("A1:A5") 4 End Sub
正常運行的代碼B :
1 Sub Test2() 2 Dim arr 3 arr = ThisWorkbook.Worksheets(1).Range("A1:A5") 4 End Sub
運行會報錯的代碼C
1 Sub Test3() 2 Dim arr() 3 arr = ThisWorkbook.Worksheets(1).Range("A1:A5") 4 End Sub
上面的寫法均省略了默認屬性。(是Value? 仍是_Dafault?)
B和C等式右邊的表達式是徹底相同的。但在運行時,arr能夠正常賦值,arr()就會報錯。
須要留意的是,Worksheets(1)的類型是Object,不是一個強類型。arr()遇到Object.Range(),正是這種狀況會出現問題,而不能正常解析的問題緣由沒找出。
上面報錯的代碼,若是換一種方式,先聲明一個顯式類型Worksheet,問題就解決了。
1 Sub Test4() 2 Dim arr() 3 Dim sht As Worksheet 4 Set sht = ThisWorkbook.Worksheets(1) 5 arr = sht.Range("A1:A5") 6 End Sub
六、自定義類的默認屬性
如何在本身類中定義默認屬性呢?
VB6實現:(一個對象只能有一個默認屬性)
步驟1:在寫好屬性過程後,而後點擊工具—過程屬性
步驟2:在過程屬性中,選擇要設置爲默認屬性的名稱,點選高級,最近設置過程標識符爲「缺省」
VBA實現:
方法: 將類模塊代碼導出,使用文本編緝器(好比notepad)修改代碼,而後從新導入VBA類模塊。
案例:寫一個Person類,有一個屬性叫P_name,如今想要設置它爲Person類的默認屬性。
1 Private name As String 2 3 Public Property Get P_name() As String 4 P_name = name 5 End Property 6 7 Public Property Let P_name(ByVal vNewValue As String) 8 name = vNewValue 9 End Property 10 11 Private Sub Class_Initialize() 12 name = "張三" 13 End Sub
一、導出類文件到本地,默認文件名爲:Person.cls
二、使用文本編緝器打開。(文字塗灰的部分是自動生成的)
三、修改屬性過程代碼,在P_name屬性過程當中添加一句:Attribute P_name.VB_UserMemId = 0
四、將修改後的cls從新導入類模塊。
1 VERSION 1.0 CLASS 2 BEGIN 3 MultiUse = -1 'True 4 END 5 6 Attribute VB_Name = "Person" 7 Attribute VB_GlobalNameSpace = False 8 Attribute VB_Creatable = False 9 Attribute VB_PredeclaredId = False 10 Attribute VB_Exposed = False 11 12 13 Private name As String 14 15 Public Property Get P_name() As String 16 Attribute P_name.VB_UserMemId = 0 17 P_name = name 18 End Property 19 20 Public Property Let P_name(ByVal vNewValue As String) 21 Attribute P_name.VB_UserMemId = 0 22 name = vNewValue 23 End Property 24 25 Private Sub Class_Initialize() 26 name = "張三" 27 End Sub
使用:
1 Sub Test() 2 Dim p As New Person 3 4 Debug.Print p 5 'Debug.Print p.P_name 6 7 p = "李四" '直接給對象賦值(實際賦值給了默認屬性) 8 Debug.Print p 9 'Debug.Print p.P_name 10 11 End Sub