看板 Office 關於我們 聯絡資訊
(若是和其他不同軟體互動之問題 請記得一併填寫) 軟體: Excel 版本: Microsoft 365 各位先進好,請教VBA的多層字典用法。 想透過字典Key值唯一特性來整理採買水果(知道其他方式也可達成同樣效果,但想請教多層字典用法),請教如圖二問號的程式碼。 如有表達不清楚之處,請見諒並告知。 http://i.imgur.com/Q6QUCWG.jpg
http://i.imgur.com/HKlaLRF.jpg
----- Sent from JPTT on my Samsung SM-G9980. -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 175.181.157.93 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Office/M.1642860184.A.EC3.html
waiter337: 我教你去破 01/23 00:19
waiter337: 你找空白處 輸入'dic.keys() 跟 'dic.items() 01/23 00:20
waiter337: 新增監看視 01/23 00:20
waiter337: 前面的'不要選到 然後各新增一個監看式 你就看懂了 01/23 00:21
waiter337: 另外 我不知道你的問題 brr並不是字典 是陣列 01/23 00:22
waiter337: 上面的dic.keys() 跟dic.items()是第一層 01/23 00:27
waiter337: 忘了說 要查看都得在程式運行時設中斷點才有資料 01/23 00:27
waiter337: 而第二層就得要看你第一層的資料代入才有辦法看的到 01/23 00:28
waiter337: dic是物件 不像陣列會有第二層自動顯示 01/23 00:29
waiter337: 我做個圖好了 01/23 00:30
kumasan123: http://i.imgur.com/2Rt3exY.jpg 01/23 00:54
kumasan123: w大您好,我試您的方法,有辦法知道第三層嗎? 01/23 00:55
kumasan123: http://i.imgur.com/dPif8GQ.jpg 01/23 00:55
waiter337: https://i.imgur.com/wcp5r2W.png 01/23 00:59
waiter337: 會第一第二層 就會第三層 01/23 01:00
waiter337: 看你是要用"文字" 還是dic.keys()(0)(0) 01/23 01:00
waiter337: dic("文字")("文字")("文字") 01/23 01:01
waiter337: 當然你也可以直接用變數 'dic(SerDate) 01/23 01:03
waiter337: 或者'dic(SerDate)(Names) 但上述這兩種 都只會出現 01/23 01:03
waiter337: 一下就消失 會跟著變數變化 01/23 01:04
waiter337: 這裡偏難 要花幾個小時玩玩看 01/23 01:07
waiter337: 我更正一下 你的兩張圖 都只有在第一層 01/23 01:08
waiter337: 我大概打一些 你試看看 01/23 01:09
waiter337: 'dic.keys()(0)(0) 01/23 01:09
waiter337: dic(#2021/10/7#) 01/23 01:09
waiter337: 'dic.keys()(0)(0)(0) 01/23 01:11
waiter337: 怕你觀念有問題 我補充一下 01/23 01:11
kumasan123: 沒錯,的確是一開始新增監看,會直接就地建立該字典。 01/23 01:12
waiter337: 每一層 都有key 跟 item 01/23 01:12
waiter337: 而keys() 跟items() 是"總集合" 01/23 01:13
kumasan123: 好的,我早上會試試,非常不好意思晚上還讓您解說。再 01/23 01:14
kumasan123: 次感謝。 01/23 01:14
waiter337: 該層的總集合 01/23 01:15
waiter337: 我的講解內也有一些小錯誤 用自己的直覺去玩學比較快 01/23 01:21
waiter337: 'dic.items()(0)(0) 01/23 04:22
kumasan123: http://i.imgur.com/yBXMTl2.jpg 01/23 12:50
kumasan123: 我試著用Dic()(0)(0)也是看不到第三層水果,要怎麼監 01/23 12:53
kumasan123: 看到水果或輸出到Excel儲存格(如Names) 表達方式? 01/23 12:53
waiter337: 都要試試看阿 01/23 17:34
waiter337: dic.keys()(0) 01/23 17:34
waiter337: dic.keys()(0)(0) 01/23 17:35
waiter337: dic.keys()(0)(0)(0) 01/23 17:35
waiter337: dic.items()(0) 01/23 17:35
waiter337: dic.items()(0)(0) 01/23 17:35
waiter337: dic.items()(0)(0)(0) 01/23 17:35
waiter337: dic(#2021/10/7#)("james") 01/23 17:37
waiter337: 就是玩 要玩出規律 01/23 17:38
kumasan123: 謝謝w大的引導,有抓住一些線索了。 01/23 22:57
waiter337: 你想要監看的話... 01/24 09:12
waiter337: names 是在第二層 01/24 09:13
waiter337: 通常作法如你一開始提供的範例 01/24 09:29
waiter337: 會先將字典篩好去重的資料 依照順序轉放入brr陣列裡面 01/24 09:30
waiter337: 然後再去找brr 的第二欄 跑迴圈 01/24 09:30
waiter337: 不過 此種方式有多種操作 可以選擇自己需要的方向 01/24 09:31
waiter337: 比如依照原本範例 他是導出dic.keys() 01/24 09:32
waiter337: 也可以用迴圈導出其他東西 如dic.items() 01/24 09:33
waiter337: 就要看你的需求 01/24 09:33
waiter337: 他的brr(jloop,3) ="" 這行確實沒任何用途 01/24 09:33
waiter337: 可能是原先準備要拿來預備用的 01/24 09:33
waiter337: 當然你也可以利用迴圈 for i = 1 to dic.count 01/24 09:39
waiter337: 上述更正 01/24 09:41
waiter337: for i = 0 to dic.count 01/24 09:42
waiter337: 然後搭配 dic.items()(i).count 去跑 多層迴圈 01/24 09:46
waiter337: 不過還有一種方法也可以 比較常見 01/24 09:46
waiter337: 這種方法通常運用在爬蟲或者網頁上 01/24 09:46
waiter337: 用for each d0 in dic 先遍例第一層 01/24 09:48
waiter337: 遍歷 01/24 09:49
waiter337: 然後 第二層 再用 for each d1 in d0 再跑一圈 01/24 09:49
waiter337: 接著判斷d1 是否有東西 01/24 09:50
kumasan123: w大真熱心。我原本用意兩份資料(A與B資料)先比對, 01/24 20:00
kumasan123: 先將B資料寫入字典內,再以A資料檢驗,若存在則進行後 01/24 20:00
kumasan123: 續資料處理。 01/24 20:00
kumasan123: 試過幾個方式,如您上述提到的For Each也試過。後來遇 01/24 20:07
kumasan123: 到問題想排除,想使用監看方式觀察,發現第三層第四層 01/24 20:07
kumasan123: 的監看設定不出來,例如Dic() (0)(0).keys還是不行( 01/24 20:07
kumasan123: 慚愧)。所以改用字典寫入Brr,再轉寫至儲存格,第三 01/24 20:07
kumasan123: 層也就卡住了。 01/24 20:07
kumasan123: 後來A資料比對就用Exists比對,遇到另一個問題此處需 01/24 20:09
kumasan123: 要物件(階段錯誤424),現在也在排除中。 01/24 20:09
waiter337: 要查key 要用items()(0)(0)(0) 01/24 20:10
waiter337: 要查item 要用dic.keys()(0)(0)(0) 數字可以自己調整 01/24 20:10
waiter337: 因為不一定每個都有三層 01/24 20:10
waiter337: 更正 要查key 要用dic.items()(0)(0)(0) 01/24 20:12
waiter337: dic.items()(0)(0)(0).......看幾層 用幾層 01/24 20:13
waiter337: 另外提供一個情報 dic雖然在vba使用上能用自動去重 01/24 20:13
kumasan123: 是的,經由提示,才知道是在item內 XD。 01/24 20:14
waiter337: 但實際上的字典 無法自動去重 若你未來有用到其他語言 01/24 20:14
waiter337: 就需要靠exist確認是否存在才能放入 以免會bug 01/24 20:14
waiter337: 但vba不影響 01/24 20:14
kumasan123: 咦,是透過exist來去重嗎?我之前想重複給予同一個key 01/24 20:18
kumasan123: ,可能會蓋掉原本的item值但是不會新增key值。 01/24 20:18
waiter337: 補充 並不是在item內 01/24 20:18
waiter337: vba 本身有自動去重的功能 但其他語言沒有例如vb.net 01/24 20:19
waiter337: 而是key 跟 item 本身就是相互存在的 01/24 20:20
waiter337: 比如 你 跟 身分證字號 01/24 20:21
waiter337: 假如 我指"你" 那麼代表 我要的是身分證字號 01/24 20:21
waiter337: 反之 我給了身分證字號 那麼 我要的是"你" 01/24 20:22
waiter337: 比如 張三 a123456789 01/24 20:22
waiter337: 那麼 我查張三 我要的答案就是a123456789 01/24 20:22
waiter337: 而我查a123456789 而該給我的答案就是 張三 01/24 20:23
waiter337: 若複雜一點 a123456789 可以不只是文字 還可以是物件 01/24 20:24
waiter337: 才會出現這種層層疊加的狀態 01/24 20:24
waiter337: 也就是說 如範例 你可能創了幾百個字典 只不過字典包 01/24 20:25
waiter337: 著其他的字典 01/24 20:25
waiter337: 雖然看起來只有dic 一本字典 但裡面還有上百個字典 01/24 20:25
waiter337: 比如dic(#2021/1/7#) <--這裡面可能又藏了一本字典 01/24 20:26
kumasan123: 謝謝熱心回答及舉例說明。 01/24 20:26
kumasan123: 嗯嗯,多層字典,我看左岸論壇另一個說法字典嵌套。都 01/24 20:30
kumasan123: 是表達同樣意思。 01/24 20:30
waiter337: 是的 01/24 20:33
waiter337: 如果不要去重 就用陣列會更方便點= = 因為我觀察這題 01/26 10:41
waiter337: 其實用陣列應該會更適合 01/26 10:41
waiter337: 比如你的第一個是2021/1/7 01/26 10:42
waiter337: 更正2021/10/7號 01/26 10:42
waiter337: 你可能會懷疑 陣列該怎麼做會適合 01/26 10:42
waiter337: 其實 日期非常適合用陣列 01/26 10:43
waiter337: 因為2021/10/7 的通用格式數字 就是44476 01/26 10:43
waiter337: 那接著下一個問題就是 我要怎麼創陣列 01/26 10:43
waiter337: 陣列的創造有個特性 不一定要從0開始創 01/26 10:43
waiter337: 甚至vba 還可以從負的開始創 這目前不在討論範圍 01/26 10:44
waiter337: 也就是我們 可以這樣創 01/26 10:44
waiter337: redim ar(44476 to 50000,20,20) 01/26 10:45
waiter337: 至少每個日期能放20人 每個人 還能放20種水果 01/26 10:45
waiter337: 而且還不會卡住 01/26 10:46
waiter337: 這題目剛好是多維陣列 目前是3維 01/26 10:46
waiter337: 接著下個問題就是 每個日期內的資料 數量都不同怎麼辦 01/26 10:46
waiter337: 由於我們創的陣列第3維是從0~20 01/26 10:47
waiter337: 也就是資料從1~20放入就好 01/26 10:47
waiter337: ar(44476,1,0)~ar(45000,1,0) 可以拿來記錄資料數量 01/26 10:48
waiter337: 每個ar(x,1,0) 都能拿來放數量紀錄 01/26 10:49
waiter337: 不過要有檔案比較好做 01/26 10:49
waiter337: 通常會用到字典嵌套 也代表這是一個需要多次比對資料的 01/26 10:50
waiter337: 問題類型 以一般的二維陣列 就會綁手綁腳 因為感覺要 01/26 10:50
waiter337: 創很多個陣列 但是用上多維陣列 跟0位記錄數量的方法 01/26 10:51
waiter337: 就能達到相同效果 01/26 10:51
waiter337: 倘若問題更為複雜 比如第一維非日期 該如何處理 01/26 10:51
waiter337: 當然用字典嵌套是個好方法 01/26 10:52
waiter337: 但如果資料量高過10000以上 會連字典都變慢卡住 01/26 10:52
waiter337: 這時候用陣列速度會更快 01/26 10:52
waiter337: 但難度又會多一道手續 必須將文字 用asc轉成數字 01/26 10:53
waiter337: 利用隨機兩個字轉asc的尾數 來當作一維陣列號數0~99 01/26 10:53
waiter337: 那就可以處理更大範圍的資料比對 01/26 10:53
waiter337: 但如果再上去達到30萬筆時 就建議改學SQL 01/26 10:54
waiter337: 其實5萬筆資料以上 就建議改用SQL處理了 01/26 10:54
kumasan123: 驚!沒想到w大持續光臨XD。 01/27 09:53
kumasan123: 當時有想到移除重複項後再寫入陣列,一樣可達到去重效 01/27 09:56
kumasan123: 果,但考量到在陣列取出多重條件比對後的結果有點難( 01/27 09:56
kumasan123: 可能有其他我不知道的解法),所以就採用多層字典。 01/27 09:56