VBA字典技術整理

這段時間頗有點邯鄲學步的感覺,由于把大量的時間和精力投入到python中抛蚤,之前學的vba到想用的時候,居然忘了寻狂。

作為非程序員岁经,編程向來當成"核導彈"來用,一次編寫出來蛇券,能用缀壤,好,很難再有機會寫第二遍代碼了纠亚,因為問題解決了诉位,以至于一直在遺忘的狀態(tài),再想用的時候到處翻資料菜枷,筆記。

VBA字典技術

VBA字典在日常統(tǒng)計工作中是個十分有用的技術叁丧,但是在寫程序時啤誊,由于不熟練和個人記憶力有限,總要翻閱資料拥娄,于是產生將常用的字典技術匯集起來的想法蚊锹。

一、入門篇

字典: 是為字詞提供音韻稚瘾、意思解釋牡昆、例句、用法等等的工具書。

在VBA中字典與傳統(tǒng)理解的字典差不多:

1丢烘、都具有關鍵字(key)和值(item)一一對應的關系柱宦,

2、鍵具有唯一性播瞳。

VBA字典的作用掸刊,與數(shù)組的結合運用,簡化代碼(其實是犧牲內存赢乓,空間換取時間的用法忧侧,但在現(xiàn)時代通用的電腦普遍內存夠用的),提升速度等一些強大的功能牌芋。

字典不存在與VBA中蚓炬,需要調用,有兩種方法:

1躺屁、前期綁定肯夏,在EXCEL表格開發(fā)工具中,工具-引用-瀏覽-找到scrrun.dll-確定楼咳;

2熄捍、后期綁定,直接用代碼創(chuàng)建調用:Set d = CreateObject("scripting.dictionary")

本文主要采用后期綁定方式記錄字典用法母怜。

字典對象的方法有6個:

Add 添加一條關鍵字與條目

Keys 返回所有關鍵字(形成1維數(shù)組)

Items 返回所有條目(形成1維數(shù)組)

Exists 關鍵字是否存在(TRUE/FALSE)

Remove 移除關鍵字與對應的條目

RemoveAll 移除所有關鍵字與對應的條目

向 Dictionary 對象中添加一個關鍵字項目對余耽。

語法:object.Add (key, item)

Key,必選項苹熏。與被添加的 item 相關聯(lián)的 key碟贾。

Item,必選項轨域。與被添加的 key 相關聯(lián)的 item袱耽。

key 是唯一存在的,否則將導致一個錯誤干发。

實例1:

Sub kaishi()

'字典的鍵索引從零開始為第一個鍵

Dim d As New Dictionary, i, j, k, l

Set d = CreateObject("scripting.dictionary")

d.Add "張三", "15"

d.Add "李四", "18"

‘基礎取值方法

i = d.Keys(0)

j = Application.WorksheetFunction.Index(d.Keys, 2)

k = d.Keys ’keys會返回一個數(shù)組朱巨,所以可以用Index方法取值

l = k(1)
'Exists方法
'如果 Dictionary 對象中存在所指定的關鍵字則返回 true,否則返回 false枉长。
' a = d.Exists("李四")
'Remove方法
'Remove 方法從一個 Dictionary 對象中清除一個鍵——值對冀续。
d.Remove ("李四")
'RemoveAll方法
'RemoveAll 方法從一個 Dictionary 對象中清除所有鍵——值對。
d.RemoveAll
End Sub

字典對象的屬性有4個:

CompareMode屬性

Count屬性

Key屬性

Item屬性

實例2:

Sub test()

Set d = CreateObject("scripting.dictionary")

'1.CompareMode屬性

'設置或者返回在 Dictionary 對象中進行字符串關鍵字比較時所使用的比較模式必峰。

d.CompareMode = 0 '1則不區(qū)分大小寫洪唐,0則區(qū)分大小寫,默認為1

d.Add "a", ""

d.Add "A", ""

d.Add "張三", "13434544323"

d.Add "李四", "13589898999"

d.Add "王五", "13456565567"

'2.Count屬性

'返回一個Dictionary 對象中的項目數(shù).只讀屬性

k = d.Count

'3.Key屬性

'在 Dictionary 對象中修改一個 key吼蚁。

d.Key("王五") = "牛三斤"

'4.Item屬性

'在一個 Dictionary 對象中設置或者返回所指定 key 的 item凭需。對于集合則根據(jù)所指定的 key 返回一個 item。

i = d.Items

d.Item("張三") = "112233"

i = d.Items

d("張三") = 987 '簡寫方式

i = d.Items

'注意:容易混淆知識點。d.key("a")與d("a")

End Sub

二粒蜈、實戰(zhàn)篇

實例3:第一次與最后一次采購價格提取



在VBA中顺献,字典的鍵具有唯一性,采用add方法薪伏,如果有重復的鍵則會發(fā)生錯誤滚澜,根據(jù)這一特性,可以提取到第一次出現(xiàn)的鍵——值對嫁怀。

而采用d.item(key)=value替換方法设捐,新的鍵——值對會替換掉之前的鍵——值對,從而提取到最后一次鍵——值對塘淑。

由于d.keys與d.items都會形成標準的一維數(shù)組萝招,在寫入縱向的單元格時,需要通過transpose進行轉置存捺。


'求每種產品第一次采購價

Sub first()

Dim arr()

On Error Resume Next

Set d = CreateObject("scripting.dictionary")

arr = Range("b1:c" & Cells(Rows.Count, 3).End(xlUp).Row)

For i = 1 To UBound(arr)

d.Add arr(i, 1), arr(i, 2)

Next

[e1].Resize(d.Count) = Application.Transpose(d.keys)

[f1].Resize(d.Count) = Application.Transpose(d.items)

End Sub

'求每種產品最后一次采購價

Sub last()

Dim arr()

Set d = CreateObject("scripting.dictionary")

arr = Range("b1:c" & Cells(Rows.Count, 3).End(xlUp).Row)

For i = 1 To UBound(arr)

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

Next

[i1].Resize(d.Count) = Application.Transpose(d.keys)

[j1].Resize(d.Count) = Application.Transpose(d.items)

End Sub

實例4:多表求不重復值

值得一提的是d(key)=value方法槐沼,沒有就寫入,有就替換捌治,而且并不會隨著循環(huán)的改變清空其中的鍵——值對岗钩。



Sub test()

Set d = CreateObject("scripting.dictionary")

For Each sh In Sheets

c = sh.Name

If sh.Name <> "品名" Then

?arr = sh.Range("a1:a" & sh.Cells(Rows.Count, 1).End(xlUp).Row)

?For Each Rng In arr

? d(Rng) = ""

?Next

End If

Next

[a1].Resize(d.Count) = Application.Transpose(d.keys)

End Sub

實例5:字典與數(shù)組的結合運用



Sub test()

Set d = CreateObject("scripting.dictionary")

arr = Sheet1.Range("a1:b" & Sheet1.Cells(Rows.Count, "a").End(xlUp).Row)

For Each Rng In arr

arr1 = VBA.Split(Rng, "|")

For Each rngs In arr1

?d(rngs) = ""

Next

i = VBA.Join(d.keys, "|")

n = n + 1

Sheet2.Cells(n, "a") = i

d.RemoveAll’清除本次循環(huán)的鍵值對

Next

End Sub

實例6:分類計算

字典可以通過鍵對應空值d(key)=d(key)+1,形成迭代計算從而統(tǒng)計出重復鍵出現(xiàn)次數(shù)肖油。

而d(key)=d(key)+value兼吓,形成替換累加效果。



Sub 分類計數(shù)()

Dim arr1

Set d = CreateObject("scripting.dictionary")

arr = Range("b2:b" & Cells(Rows.Count, 2).End(xlUp).Row)

For Each Rng In arr

i = d(Rng)

d(Rng) = d(Rng) + 1

i = d(Rng)

Next

[e1].Resize(d.Count) = Application.Transpose(d.keys)

[f1].Resize(d.Count) = Application.Transpose(d.items)

End Sub

Sub 分類求和()

Dim arr1

Set d = CreateObject("scripting.dictionary")

arr = Range("b2:c" & Cells(Rows.Count, 2).End(xlUp).Row)

For i = 1 To UBound(arr)

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

Next

[e8].Resize(d.Count) = Application.Transpose(d.keys)

[f8].Resize(d.Count) = Application.Transpose(d.items)

End Sub

實例7:多列合并計算

此例在邏輯上挺繞的森枪,由于定義的動態(tài)數(shù)組arr(1 to 4, 1 to n),二維數(shù)組的第一維的下限不能為不確定值的變量视搏,所以通過多層轉置達到取值的目的。



Dim arr1()

Set d = CreateObject("scripting.dictionary")

arr = Range("a2:d" & Cells(Rows.Count, 2).End(xlUp).Row)

For i = 1 To UBound(arr)

?If Not d.exists(arr(i, 1)) Then

?n = n + 1

?d(arr(i, 1)) = n

?ReDim Preserve arr1(1 To 4, 1 To n)

?arr1(1, n) = arr(i, 1)

?arr1(2, n) = arr(i, 2)

?arr1(3, n) = arr(i, 3)

?arr1(4, n) = arr(i, 4)

Else

?m = d(arr(i, 1))

?arr1(2, m) = arr1(2, m) + arr(i, 2)

?arr1(3, m) = arr1(3, m) + arr(i, 3)

?arr1(4, m) = arr1(4, m) + arr(i, 4)

?End If

Next

[f2].Resize(n, 4) = Application.Transpose(arr1)

End Sub

實例8:條目數(shù)組用法

字典的鍵——值方式非常的靈活县袱,值甚至可以是數(shù)組浑娜。



Sub test() '條目數(shù)組用法

Set d = CreateObject("scripting.dictionary")

With Sheets("data")

arr = .Range("a2:e" & .Cells(Rows.Count, 1).End(xlUp).Row)

End With

For i = 1 To UBound(arr)

d(arr(i, 1)) = Array(arr(i, 2), arr(i, 3), arr(i, 4), arr(i, 5))

j = d(arr(i, 1))

Next

For Each Rng In Range("a3:a" & Cells(Rows.Count, 1).End(xlUp).Row)

Rng.Offset(0, 1).Resize(1, 4) = d(Rng.Value)

Next

End Sub

總結:

字典在VBA中是種非常實用的技術,在實際運用中式散,與事件筋遭,控件等功能結合運用會產生一些非常實用神奇的操作。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末暴拄,一起剝皮案震驚了整個濱河市漓滔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌揍移,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件反肋,死亡現(xiàn)場離奇詭異那伐,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門罕邀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畅形,“玉大人,你說我怎么就攤上這事诉探∪瞻荆” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵肾胯,是天一觀的道長竖席。 經常有香客問我,道長敬肚,這世上最難降的妖魔是什么毕荐? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮艳馒,結果婚禮上憎亚,老公的妹妹穿的比我還像新娘。我一直安慰自己弄慰,他們只是感情好第美,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著陆爽,像睡著了一般什往。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上墓陈,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天恶守,我揣著相機與錄音,去河邊找鬼贡必。 笑死兔港,一個胖子當著我的面吹牛,可吹牛的內容都是我干的仔拟。 我是一名探鬼主播衫樊,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼利花!你這毒婦竟也來了科侈?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤炒事,失蹤者是張志新(化名)和其女友劉穎臀栈,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挠乳,經...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡权薯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年姑躲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盟蚣。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡黍析,死狀恐怖,靈堂內的尸體忽然破棺而出屎开,到底是詐尸還是另有隱情阐枣,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布奄抽,位于F島的核電站蔼两,受9級特大地震影響,放射性物質發(fā)生泄漏如孝。R本人自食惡果不足惜宪哩,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望第晰。 院中可真熱鬧锁孟,春花似錦、人聲如沸茁瘦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甜熔。三九已至圆恤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腔稀,已是汗流浹背盆昙。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留焊虏,地道東北人蟀瞧。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓稽鞭,卻偏偏與公主長得像已亥,于是被迫代替她去往敵國和親咪惠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內容