久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    看完這篇,如果你還不懂VBA字典,那我就沒辦法了

     5jia5 2020-04-13
    作者:看見星光
     微博:EXCELers / 知識星球:Excel

    HI,大家好,我是星光。在Excel基礎(chǔ)教程里,咱們講過函數(shù)+透視表是普通表格用戶處理數(shù)據(jù)的最佳組合,函數(shù)用于數(shù)據(jù)清洗整理,透視表用于數(shù)據(jù)匯總分析。如果你接觸過Power BI,會發(fā)現(xiàn)類似的情況,PowerQuery用于數(shù)據(jù)清洗整理,PowerPivot用于數(shù)據(jù)匯總分析。而VBA編程呢?也不例外,數(shù)組用于數(shù)據(jù)清洗整理,字典用于數(shù)據(jù)匯總分析……關(guān)于數(shù)組,可以看「零基礎(chǔ)學(xué)VBA編程系列教程」中的數(shù)組四篇,關(guān)于字典——打個響指,今天就來給大家講下什么是字典。

    前方高能預(yù)警,本文共分8節(jié),建議先收后看。

    目錄如下▼

    1 什么是字典

    2 如何創(chuàng)建字典

    3 如何將數(shù)據(jù)存入字典

    4 如何將數(shù)據(jù)從字典取出

    5 如何移除字典元素

    6 如何遍歷字典元素

    7 如何釋放字典

    8 思考和其它

    ……



    1 丨

    什么是字典


    談到字典,有些朋友可能會想到新華字典、康熙字典、英漢字典、有道字典等等。我今天說的字典,和這些家伙——都沒關(guān)系。字典(Dictionary)是VBA編程中的一個對象,具有操作簡單、運行高效的特點,常用于數(shù)據(jù)的條件查詢、聚合匯總等。如果說數(shù)組是VBA處理數(shù)據(jù)的基礎(chǔ)結(jié)構(gòu),那么字典就可以被稱為核心。攤手,騙你娶你,不論男女。

    我舉個例子。

    如上圖所示的數(shù)據(jù)表,如果我們需要查詢看見星光的特長,數(shù)組的解法步驟如下▼

    首先將數(shù)據(jù)源存入數(shù)組,然后遍歷姓名,第1個人名不是,第2個人名不是,第3個人名不是,第4個還不是……一直到第7個人名才是,于是取特長,退出數(shù)組循環(huán)……

    數(shù)組循環(huán)是線性查找的方式,只能一個個元素找過去,如果查找值過多,效率就很不理想。

    如果是用字典呢?

    首先將數(shù)據(jù)源裝入字典,然后用一句代碼就可以查詢相關(guān)人名的特長了。

    比如查詢看見星光的特長..▼


    字典('看見星光')

    不用懷疑,不用循環(huán),就是這么簡單。

    ……

    還記得嗎?在數(shù)組四篇之什么是數(shù)組里,咱們講過數(shù)組處理數(shù)據(jù)的過程可以分為5步。創(chuàng)建數(shù)組->將數(shù)據(jù)存入數(shù)組->數(shù)組運算->將數(shù)組數(shù)據(jù)寫入Excel->釋放數(shù)組。

    字典處理數(shù)據(jù)的過程與數(shù)組十分相似:創(chuàng)建字典->將數(shù)據(jù)裝入字典->將數(shù)據(jù)從字典取出->釋放字典。

    ——那么如何創(chuàng)建字典?

    2 丨

    如何創(chuàng)建字典



    如上文所講,字典(Dictionary)是VBA編程的一個對象,但它并非VBA自帶的妻妾,而是集成在動態(tài)鏈接庫文件Scrrun.dll中,需要綁定文件后才能夠使用。綁定文件有兩種方式,前期綁定和后期綁定。

    聽起來很麻煩的樣子,但操作起來其實——很簡單。

    先來說前期綁定

    操作步驟如下▼

    在VBE編輯器的[工具]選項卡下,單擊[引用],在打開的[引用]對話框中勾選'Microsoft Scripting Runtim'選項,單擊[確定]按鈕,關(guān)閉對話框即可。


    通過'前期綁定'的方式引用Scrrun.dll文件后,即可在VBA代碼中利用Dim語句聲明變量為字典對象,然后使用字典處理數(shù)據(jù)。

    示例代碼如下..▼




    Sub 前期綁定()    Dim d As New Dictionary '聲明一個字典對象    ……End Sub

    第2句代碼聲明一個字典對象,其名為d。語法格式如下▼


    Dim 變量名 As New Dictionary

    ……

    然后再說下后期綁定。

    所謂后期綁定是指通過CreateObject函數(shù)創(chuàng)建對字典對象的引用,示例代碼如下▼






    Sub 后期綁定()    Dim d As Object '聲明一個對象    Set d = CreateObject('scripting.dictionary') '創(chuàng)建對字典的引用    ……End Sub


    第2句代碼聲明一個對象類型的變量,其名為d。

    第3句代碼使用CreateObject函數(shù)創(chuàng)建對字典對象的引用……

    ……

    那么前期綁定和后期綁定有什么不同呢?

    有朋友說,星光你是不是個鐵憨憨?很明顯,前期綁定需要手動操作,后期綁定用代碼就行了!——拜托,我五行多金,你可以說我憨,但不能帶鐵。而且,攤手,事情可沒有這么簡單▼

    比如——在使用前期綁定后,編寫代碼時系統(tǒng)會自動顯示字典的成員列表,而后期綁定不會顯示;有些屬性,前期綁定是支持的,但后期綁定不能使用(詳情見文末說明);另外,通常前期綁定的代碼運算效率要比后期快一些。

    但是——前期綁定的代碼不適合發(fā)送給其它用戶使用,畢竟其它用戶未必會去手動綁定字典對象;因此后期綁定的方式兼容性更強些。

    總結(jié)——建議編寫代碼時采用前期綁定,編寫完成后,如需發(fā)送他人使用,再改為后期綁定,如此魚和熊掌必可兼得矣~


    3 丨

    如何將數(shù)據(jù)裝入字典



    創(chuàng)建完字典后,我們需要將數(shù)據(jù)裝入字典。但在講如何將數(shù)據(jù)裝入字典前,需要先給大家說一下字典的結(jié)構(gòu)。

    從表格角度,通俗而言,字典是有兩個一維數(shù)組或者說兩列數(shù)據(jù)構(gòu)成的特殊表。第1列是關(guān)鍵字,被稱為Key;第2列是每個關(guān)鍵字對應(yīng)的條目,被稱為Item。其中每個關(guān)鍵字在字典中都是唯一的,不會也不允許出現(xiàn)重復(fù)值。


    和數(shù)組所不同的是,字典的行數(shù)看起來并不固定,你往字典里裝了多少個關(guān)鍵字,它就會有幾行數(shù)據(jù),每一行數(shù)據(jù)都由兩列組成,第1列是關(guān)鍵字,第2列是關(guān)鍵字對應(yīng)的條目。

    那么如何將數(shù)據(jù)裝入字典呢?

    直接賦值就可以了。語法格式如下▼


    字典(關(guān)鍵字)=條目

    舉個例子。






    Sub 字典添加數(shù)據(jù)()    Dim d As New Dictionary '聲明一個字典對象    d('看見星光') = 99    d('Excel星球') = 98End Sub

    第2行代碼使用前期綁定的方式聲明一個字典對象,其名為d。

    第3行代碼將關(guān)鍵字'看見星光'裝入字典,對應(yīng)的條目是99。此時字典有一行數(shù)據(jù),如下圖所示。

    第4行代碼將關(guān)鍵字'Excel星球'裝入字典,對應(yīng)的條目是98。此時字典就會有兩行數(shù)據(jù),如下圖所示。

    ……

    但是我們前面講過,字典的關(guān)鍵字必須是唯一的,如果字典中已經(jīng)存在了某個關(guān)鍵字,我們又往里面添加了同樣的關(guān)鍵字,會怎么樣呢?

    舉個例子。






    Sub 字典添加重復(fù)數(shù)據(jù)() Dim d As New Dictionary '聲明一個字典對象 d('看見星光') = 99 d('看見星光') = 59End Sub
    第3行代碼將關(guān)鍵字'看見星光'裝入字典,對應(yīng)的條目是99。

    第4行代碼再次裝入一個相同的關(guān)鍵字'看見星光',條目是59。此時字典會將已經(jīng)存在的關(guān)鍵字'看見星光'的條目更新為59。

    如果我不想字典更新已經(jīng)存在的關(guān)鍵字記錄呢?憑什么把我從99分改為59分?對不對?我憑本事抄的答案你憑啥給我改成不及格?作為一個人,難道我連抄答案的自由都沒有了嗎?多么糟糕的組織會干出這樣無情的事?——摘自跨國出版物《星光日記》。

    解決方案代碼如下▼








    Sub 判斷字典是否存在相同關(guān)鍵字()    Dim d As New Dictionary '聲明一個字典對象    d('看見星光') = 99    If Not d.Exists('看見星光') Then        d('看見星光') = 59    End IfEnd Sub
    第4行代碼使用字典的Exists方法判斷是否存在關(guān)鍵字'看見星光';如果不存在,則添加該關(guān)鍵字并設(shè)置條目為59;如果存在,則忽略不處理。

    Exists是字典的方法,作用是判斷字典中是否存在指定關(guān)鍵字,結(jié)果返回一個布爾值,存在返回True,不存在返回False。語法格式如下▼

    字典.Exists(關(guān)鍵字)
    ……

    以上是講的如何將單個關(guān)鍵字裝入字典,那么如何將一組數(shù)據(jù)批量裝入字典呢?
    如上圖所示的數(shù)據(jù)表,需要將A列的姓名作為關(guān)鍵字,B列的特長作為條目,全部裝入字典——攤手,古老的VBA并沒有提供批量處理的方法,只能先將數(shù)據(jù)源存入數(shù)組,再遍歷數(shù)組將每個元素一一存入字典。

    示例代碼如下▼








    Sub 數(shù)據(jù)表數(shù)據(jù)存入字典()    Dim d As New Dictionary    Dim arr, i As Long    arr = Worksheets('數(shù)據(jù)表').Range('a1').CurrentRegion    For i = 2 To UBound(arr) '遍歷數(shù)組元素        d(arr(i, 1)) = arr(i, 2) '姓名是key,特長是item    NextEnd Sub

    第4行代碼將數(shù)據(jù)源數(shù)據(jù)存入數(shù)組arr

    第5至第7行代碼遍歷數(shù)組元素,將姓名作為key,特長作為item,分別存入字典。

    ……

    一個小問題,如何更新字典中指定關(guān)鍵字的條目呢?

    假設(shè)字典中已經(jīng)存在關(guān)鍵字'看見星光',對應(yīng)的條目是99分;但是由于他這成績是抄別人答案抄來的,所以需要更改為59分。這時應(yīng)該怎么編寫代碼呢?——請返回本節(jié)中段,查看跨國出版物《星光日記》

    ……

    4 丨

    如何將數(shù)據(jù)從字典取出



    了解了如何將數(shù)據(jù)裝入字典,接下來再看一下如何將數(shù)據(jù)從字典中取出,畢竟裝從來不是咱們的目的,咱們的目的是——要酷。字典的最大優(yōu)勢也并不在裝,而在于根據(jù)指定關(guān)鍵字取對應(yīng)條目的簡潔和高效。

    舉個例子。






    Sub 讀取數(shù)據(jù)() Dim d As New Dictionary '聲明一個字典對象 d('看見星光') = 99 d('Excel星球') = 98 MsgBox d('Excel星球')End Sub
    上述代碼中,第3行和第4行代碼將兩個關(guān)鍵字和對應(yīng)條目存入字典,第5行代碼獲取關(guān)鍵字'Excel星球'的對應(yīng)條目,并使用消息框顯示。

    獲取字典指定關(guān)鍵字對應(yīng)Item的語法格式如下▼


    字典(關(guān)鍵字)

    就是這么簡單~樸實無華且枯燥……

    打個響指,我再舉個實用的例子。

    如上圖所示的數(shù)據(jù)為例,需要根據(jù)A:B列的數(shù)據(jù)源,查詢D列人名對應(yīng)的特長,這就是所謂的條件查詢了。


    示例代碼如下▼


















    Sub 讀取數(shù)據(jù)2() Dim d As New Dictionary Dim arr, brr, i As Long arr = Range('a1').CurrentRegion '數(shù)據(jù)源 For i = 2 To UBound(arr) '遍歷數(shù)組,數(shù)據(jù)裝入字典 d(arr(i, 1)) = arr(i, 2) 'key是人名,item是特長 Next brr = Range('d1:e' & Cells(Rows.Count, 'd').End(xlUp).Row) '查詢區(qū)域 For i = 2 To UBound(brr) '遍歷查詢值 If d.Exists(brr(i, 1)) Then '如果字典存在查詢值            brr(i, 2) = d(brr(i, 1)) '獲取人名對應(yīng)的條目 Else            brr(i, 2) = '查無此人' End If Next Range('d1:e' & Cells(Rows.Count, 'd').End(xlUp).Row) = brr Set d = NothingEnd Sub

    代碼解析:

    第5至第7行代碼將數(shù)據(jù)源數(shù)據(jù)存入字典,其中人名為關(guān)鍵字,特長為條目。

    第8行代碼將查詢區(qū)域的數(shù)據(jù)存入數(shù)組brr。

    第9行至第15行代碼遍歷獲取相關(guān)人名在字典中對應(yīng)的特長。第10行代碼判斷字典中是否存在相關(guān)人名,如果存在,則取對應(yīng)的條目存入數(shù)組brr;如果不存在,則將結(jié)果設(shè)置為字符串'查無此人'。

    第16行代碼將查詢結(jié)果寫入單元格區(qū)域。

    代碼運行后結(jié)果如下▼
    ……

    字典除了支持通過指定關(guān)鍵字查詢對應(yīng)Item外,也支持一次性將所有的關(guān)鍵字或條目轉(zhuǎn)換為一維數(shù)組,這需要用到字典的Keys和Items屬性。

    獲取字典所有的Key,語法格式如下▼


    字典.Keys

    獲取字典所有的Item,語法格式如下▼


    字典.Items

    ……

    我用麒麟雙臂給大家舉個典型的例子:數(shù)據(jù)去重。

    如下圖所示的數(shù)據(jù)表,A列人名存在重復(fù)值,需要去重復(fù),獲取不重復(fù)的人員名單,結(jié)果如D列。


    示例代碼如下▼














    Sub 去重復(fù)()    Dim d As New Dictionary    Dim arr, i As Long    arr = Range('a1').CurrentRegion    For i = 1 To UBound(arr)        If Not d.Exists(arr(i, 1)) Then            d(arr(i, 1)) = ''        End If    Next    Range('d:d').ClearContents    Range('d1').Resize(d.Count, 1) = Application.Transpose(d.Keys)    Set d = NothingEnd Sub
    代碼解析▼

    第4行至第9行代碼將數(shù)據(jù)源的姓名作為關(guān)鍵字存入字典。很多新手朋友可能困惑于下面這句代碼。


    d(arr(i, 1)) = ''


    代碼的意思是姓名為關(guān)鍵字,條目為空文本。為什么要將條目設(shè)置為空文本?對于字典來說,Key和Item都是必須的,兩者必須成對出現(xiàn),缺一不可,但這里我們對Item并沒有特別的要求,所以就隨便賞個空文本打發(fā)一下算了。有朋友說,那我將代碼改成下面這樣行不行?——當(dāng)然可以!我真誠的祝愿你夢想成真!


    d(arr(i, 1)) = '我想有個真人女朋友'

    需要重點說一下第11行代碼,它的作用是將字典所有關(guān)鍵字存入當(dāng)前工作表的D列。語句如下。


    Range('d1').Resize(d.Count, 1) = Application.Transpose(d.Keys)

    Count是字典的屬性之一,作用是統(tǒng)計字典關(guān)鍵字的數(shù)量,d.Count也就是名稱為d的字典有多少個關(guān)鍵字。

    Range('d1').Resize(d.Count, 1),以d1單元格為起點,向下擴展指定行數(shù),作為存放字典所有關(guān)鍵字的單元格區(qū)域。

    d.Keys是以一維數(shù)組的形式返回字典所有的關(guān)鍵字。在數(shù)組四篇里咱們講過,一維數(shù)組就是一行數(shù)據(jù),需要通過Transpose函數(shù)進行一次轉(zhuǎn)置才能轉(zhuǎn)換為二維,然后才能直接寫入垂直單元格區(qū)域。

    綜上所述——這四個字老霸氣了,但更霸氣的是隨后的四個字——您就懂了!

    ……

    擴展一下,我再舉個與之相似的例子。

    如下圖所示,需要在D:E列,獲取A:B列不重復(fù)的人名及其特長數(shù)據(jù)。


    示例代碼如下▼














    Sub 去重復(fù)2()    Dim d As New Dictionary    Dim arr, i As Long    arr = Range('a1').CurrentRegion    For i = 1 To UBound(arr)        If Not d.Exists(arr(i, 1)) Then            d(arr(i, 1)) = arr(i, 2)        End If    Next    Range('d:e').ClearContents    Range('d1').Resize(d.Count, 2) = Application.Transpose(Array(d.Keys, d.Items))    Set d = NothingEnd Sub

    和上一段代碼相比,所不同的有兩句。

    第7行代碼,d(arr(i, 1)) = arr(i, 2),指定了關(guān)鍵字對應(yīng)的條目為arr(i,2),也就是人員的特長。為什么不再是d(arr(i, 1)) = ''了?因為你需要Item為指定值,不能再隨便打發(fā)了。人吶,就是這么現(xiàn)實。

    第11行代碼放置數(shù)據(jù)的列數(shù)由1列改為了2列。

    Range('d1').Resize(d.Count, 2)

    代碼使用以下語句一次性獲取字典的Keys和Items,存入一個一維數(shù)組(在數(shù)組四篇里咱們講過,Array函數(shù)結(jié)果為一維數(shù)組),最后再通過一次轉(zhuǎn)置將一維數(shù)組修改為2維,直接寫入指定單元格區(qū)域。


    Application.Transpose(Array(d.Keys, d.Items))

    ……

    5 丨

    如何移除字典中的元素



    前面講了如何對字典的數(shù)據(jù)進行存和取,這是使用字典最常見的兩種情況;但還有一種情況:移除,也就是將數(shù)據(jù)從字典中移除。

    如果移除指定關(guān)鍵字,可以使用方法Remove,語法格式如下▼


    字典.Remove 關(guān)鍵字

    示例代碼如下:







    Sub 移除指定關(guān)鍵字()    Dim d As New Dictionary '聲明一個字典對象    d('看見星光') = 99    d('Excel星球') = 98    d.Remove '看見星光'End Sub

    第3行和第4行代碼分別添加兩個關(guān)鍵字到字典中。此時字典有兩行數(shù)據(jù),如下圖所示▼

    第5行代碼將關(guān)鍵字'看見星光'移除,關(guān)鍵字和條目總是成對出現(xiàn)的,關(guān)鍵字移除了,對應(yīng)的條目也就移除了,于是此時字典就還剩下一個關(guān)鍵字▼


    除了根據(jù)指定關(guān)鍵字移除數(shù)據(jù)外,還可以使用方法RemoveAll將字典數(shù)據(jù)一次性清空。語法格式如下▼


    字典.RemoveAll


    當(dāng)一個字典需要重復(fù)使用的時候,就需要用上RemoveAll方法了。

    舉個例子,如下圖所示,需要在H列獲取每期開獎號碼不重復(fù)的號碼,并用逗號作為分隔符,合并成一個字符串。


    示例代碼如下▼

















    Sub 全部移除字典中的元素()    Dim d As New Dictionary    Dim arr, i As Long, j As Long    arr = Range('a1').CurrentRegion    For i = 2 To UBound(arr) '遍歷行        d.RemoveAll '移除字典中所有的元素        For j = 2 To UBound(arr, 2) - 1 '遍歷列            If Not d.Exists(arr(i, j)) Then                d(arr(i, j)) = '' '將不重復(fù)的號碼存入字典            End If        Next        arr(i, UBound(arr, 2)) = VBA.Join(d.Keys, ',') '合并為一個字符串    Next    Range('a1').CurrentRegion = arr    Set d = NothingEnd Sub
    第5行代碼遍歷處理每行數(shù)據(jù)。

    第6行代碼在實際處理每行數(shù)據(jù)之前,先清空字典中的所有元素。

    第7至第11行代碼遍歷當(dāng)前行每列的元素,只將唯一值存入字典。

    第12行代碼使用Join函數(shù),以逗號為分隔符,將當(dāng)前字典所有的關(guān)鍵字合并成為一個字符串,并存入結(jié)果數(shù)組。


    arr(i, UBound(arr, 2)) = VBA.Join(d.Keys, ',')

    然后再遍歷處理下一行數(shù)據(jù)……

    ……


    6 丨

    如何遍歷字典中的元素



    有時候,為了篩選出符合條件的數(shù)據(jù),我們需要像遍歷數(shù)組一樣,遍歷字典中的每個元素。這通常需要先獲取字典的Keys集合,再遍歷每個Key去篩選字典中符合條件的數(shù)據(jù)。

    什么意思呢?舉個例子還是我。

    如下圖所示的數(shù)據(jù)表,需要篩選出人名重復(fù)出現(xiàn)次數(shù)大于2次的人員名單,以及相關(guān)出現(xiàn)次數(shù),結(jié)果參考C:D列。

    示例代碼如下▼





















    Sub 遍歷字典元素_索引法()    Dim d As New Dictionary    Dim arr, aKey, aRes, i As Long, k As Long    arr = Range('a1').CurrentRegion    For i = 2 To UBound(arr)        d(arr(i, 1)) = d(arr(i, 1)) + 1    Next    aKey = d.Keys    ReDim aRes(1 To d.Count, 1 To 2) '結(jié)果數(shù)組    For i = 0 To UBound(aKey)        If d(aKey(i)) > 2 Then '次數(shù)大于2次            k = k + 1            aRes(k, 1) = aKey(i)            aRes(k, 2) = d(aKey(i))        End If    Next    Range('c:c').ClearContents    Range('c1') = '重復(fù)2次以上的人名'    Range('c2').Resize(k, 2) = aRes    Set d = NothingEnd Sub

    代碼解析:

    第4行代碼將數(shù)據(jù)源數(shù)據(jù)存入數(shù)組arr。

    第5行至第7行代碼將數(shù)組arr中的人名存入字典,重點是下面這句代碼。


    d(arr(i, 1)) = d(arr(i, 1)) + 1

    這句代碼類似于咱們在什么是變量里講過的計數(shù)器k=k+1。

    作為賦值語句,它首先運算的是等號右側(cè)的表達式:d(arr(i,1))+1。有趣的是,在代碼運行這里的d(arr(i,1))的時候,我們還沒有將arr(i,1)的關(guān)鍵字存入字典,所以正常理解,這句代碼應(yīng)該返回程序錯誤,但事實并沒有。字典(關(guān)鍵字)語句的運算規(guī)則是,如果字典中存在指定關(guān)鍵字,則返回對應(yīng)的Item,否則會將該關(guān)鍵字存入字典,同時將其對應(yīng)的Item設(shè)置為Nothing。
    因此,在第一次運行這句代碼時……


    d(arr(i, 1)) = d(arr(i, 1)) + 1

    等于▼


    d(arr(i, 1)) = Nothing + 1

    等于▼


    d(arr(i, 1)) =1

    也就是在字典中存入一個關(guān)鍵字arr(i,1),對應(yīng)的條目為1。

    當(dāng)出現(xiàn)第2次出現(xiàn)同名的關(guān)鍵字時…


    d(arr(i, 1)) = d(arr(i, 1)) + 1

    等于▼


    d(arr(i, 1)) = 1 + 1

    等于▼


    d(arr(i, 1)) = 2

    也就是在字典將關(guān)鍵字arr(i,1)對應(yīng)的條目更新為2.

    ……以此實現(xiàn)了相同值出現(xiàn)次數(shù)在字典中不斷累加的效果。

    你品品,是不是這個道理?品不出來?沒事,不怕你墮落,我送你一瓶82年的雪碧,你慢慢品。



    ……

    第8行代碼返回字典中所有的Key,結(jié)果是一個下標(biāo)為0的一維數(shù)組,命名為aKey。

    第9行代碼聲明一個結(jié)果數(shù)組,行數(shù)為字典的個數(shù),列數(shù)是2列,一列放人名,一列放次數(shù)。

    第10行至第16行代碼采用索引的方式遍歷數(shù)組aKey,查看每一個Key在字典中的Item是否大于2次,如果大于2次則將Key和Item分別存入結(jié)果數(shù)組。相似的套路咱們在數(shù)組4篇的數(shù)組運算里詳細講過了,這里就不再敲擊鍵盤,免得浪費它所剩無幾的生命力。

    ……

    7 丨

    如何釋放字典內(nèi)存



    如果你是細心的人兒,會發(fā)現(xiàn)前面每小節(jié)的代碼末尾都會出現(xiàn)下面這條語句。

    Set d = Nothing

    在章節(jié)什么是變量里咱們講過了,它的作用是釋放對象變量所占用的內(nèi)存,提高代碼運行效率,雖然它未必是必須的,但聰明的您最好像優(yōu)秀的我一樣,養(yǎng)成使用它的好習(xí)慣。

    有朋友可能會問,我用字典.RemoveAll語句清空字典,是不是可以代替Set 字典=Nothing?答案是否定的,你失戀了,傷感的把合租的房子清空,和你一怒之下把房子給燒沒了,是兩個概念好吧?前者房子雖然空了,但還在,還能住新歡和舊愛,后者是連房子都沒了,再愛也都煙消云散了……。


    8 丨

    思考題和其它



    最后說一下幾個零散的知識點。

    ……

    1丨前期綁定和后期綁定的不同

    在本章第2節(jié)如何創(chuàng)建字典,咱們講過,有些屬性前期綁定是支持的,但后期綁定并不能使用。這個有些屬性,其實指的就是Items和Keys。

    在前期綁定的情況下,我們可以使用以下語句讀取Keys集合的指定索引元素。

    讀取字典Keys的第2個元素,并賦值為變量strKey..▼

    strKey = d.Keys(1)

    但后期綁定并不支持運行該語句,必須先將Key或Item轉(zhuǎn)換為數(shù)組才能夠索引遍歷。

    讀取字典Keys的第2個元素,并賦值為變量strKey..▼


    r = d.Keys'關(guān)鍵字集合賦值數(shù)組rstrKey = r(1)

    ……

    2丨如何讓字典不區(qū)分字母大小寫

    字典是默認(rèn)是區(qū)分字母大小寫的。如果不需要區(qū)分字母大小寫,有兩種解決方法……

    一種是設(shè)置字典的CompareMode屬性為TextCompar,示例代碼如下▼







    Sub 不區(qū)分字母大小寫() Dim d As New Dictionary d.CompareMode = TextCompare d('a') = 1 MsgBox d('A')End Sub

    一種是將所有的字母統(tǒng)一轉(zhuǎn)換為大寫(UCase)或小寫(LCase),這種方式明顯修改了原值,因此通常不建議使用。示例代碼如下▼






    Sub 不區(qū)分字母大小寫2()    Dim d As New Dictionary    d(LCase('a')) = 1'LCase將字母統(tǒng)一轉(zhuǎn)換為小寫    MsgBox d(LCase('A')) End Sub

    ……

    3丨字典對數(shù)據(jù)類型的態(tài)度是嚴(yán)格的

    字典對數(shù)據(jù)類型的態(tài)度是嚴(yán)格的——這句話是什么意思呢?我們知道Excel是一款對數(shù)據(jù)類型要求很寬松的軟件,數(shù)值可以分為文本型數(shù)值和純數(shù)值兩種,在VBA的邏輯判斷中,文本型數(shù)值和純數(shù)值是相等的,比如以下代碼返回True。




    Sub t() MsgBox '1' = 1End Sub

    但在字典中,純數(shù)值和文本型數(shù)值并不相等。

    舉個例子,示例代碼如下▼






    Sub 數(shù)據(jù)類型1()    Dim d As New Dictionary    d(1) = '愛就一個字'    MsgBox d.Exists('1')End Sub

    第3行代碼將純數(shù)值1作為Key存入字典。

    第4行代碼判斷文本型數(shù)值1在字典中是否存在,結(jié)果返回False。

    知道這個知識點有什么用?

    當(dāng)你需要處理的Key有數(shù)值類型時,最好將源數(shù)據(jù)和查詢值都統(tǒng)一轉(zhuǎn)換為文本的形式,避免踩坑。如何統(tǒng)一轉(zhuǎn)換為文本的形式?可以通過聲明一個字符串類型的變量,強制進行轉(zhuǎn)換。

    示例代碼如下▼











    Sub 數(shù)據(jù)類型2() Dim d As New Dictionary Dim strKey As String '定義一個字符串類型的變量 strKey = '1' d(strKey) = '愛就一個字' strKey = '2' d(strKey) = '我要說兩次' strKey = 1 '強制轉(zhuǎn)換為字符串 MsgBox d.Exists(strKey) '結(jié)果返回TrueEnd Sub

    ……

    4丨字典常用方法和屬性的另外表達方式

    如果你看的VBA代碼多了,可能會看到有人使用以下方式往字典中添加關(guān)鍵字和對應(yīng)條目:


    d.Add '夏天','吃冰棍'

    其中夏天是Key,吃冰棍是Item。

    但這種方式在常規(guī)VBA代碼中我并不推薦使用,原因很簡單,它不夠靈活。如果字典中已存在相同關(guān)鍵字,該語句會返回錯誤值,而且它并不支持更新相關(guān)條目。當(dāng)然,最重要的是,它打字太多了,你數(shù)數(shù),相比下句代碼它多打了幾個字?別不把手指當(dāng)親骨肉啊同志們吶!!


    d('夏天')='吃冰棍'

    與之相似的還有下面幾種語句,同樣因為不夠靈活,打字偏多等不推薦使用。







    Sub test1()    Dim d As New Dictionary    d.Add '看見星光', '曾經(jīng)20歲' '添加一個關(guān)鍵字看見星光    MsgBox d.Item('看見星光') '獲取關(guān)鍵字看見星光對應(yīng)的條目    d.Item('看見星光') = '年年18歲' '將看見星光對應(yīng)的條目修改為'年年18歲'End Sub

    5丨如何學(xué)習(xí)更多VBA編程知識和技巧?

    字典是VBA編程中的核心數(shù)據(jù)結(jié)構(gòu),本文只是講解了最基礎(chǔ)的概念和用法,字典存在的意義到底是什么?僅僅只是去重復(fù)嗎?簡單的數(shù)據(jù)查詢嗎?當(dāng)然不是!更多實用的字典用法我會繼續(xù)分享在知識星球……

      本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
      轉(zhuǎn)藏 分享 獻花(0

      0條評論

      發(fā)表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 国产在线欧美日韩精品一区| 久久97人人超人人超碰超国产| 免费观看欧美猛交视频黑人| 精品一区二区三区在线成人| 超碰成人人人做人人爽| 天天躁日日躁狠狠躁2018| 国产白嫩护士被弄高潮| 亚洲高清WWW色好看美女| 亚洲AV永久无码一区| 午夜福利高清在线观看| 一二三四免费中文字幕| 久久精品国产99国产精品澳门| 亚洲精品人成网线在播放VA| 色偷偷AV男人的天堂京东热| 狠狠做五月深爱婷婷伊人| 亚韩精品中文字幕无码视频| 人妻系列无码专区69影院| 国产农村妇女毛片精品久久| 18禁成人免费无码网站| 男女性高爱潮是免费国产| 久久先锋男人AV资源网站| 天天爽夜夜爱| 久久综合色天天久久综合图片| 亚洲精品一区二区区别| 人妻少妇久久久久久97人妻| 日韩在线视频线观看一区| 国产欧美久久久精品影院| 久久精品国产亚洲AV麻| 99中文字幕国产精品| 18精品久久久无码午夜福利| 亚洲欧美卡通另类丝袜美腿| 久久国产成人av蜜臀| 国产成人无码区免费内射一片色欲| 中文字幕亚洲日韩无线码| 亚洲精品香蕉一区二区| 国产精品IGAO视频网网址| A级日本乱理伦片免费入口| 免费现黄频在线观看国产| 丰满人妻一区二区三区视频53 | 亚洲精品熟女一区二区| 亚洲欧洲中文日韩久久AV乱码|