返回列表 上一主題 發帖

[發問] 怎麼在USERFORM中加入可篩選複選之樹狀圖

回復 9# chaoyiho

你在模組1 (Module1) 加入了 Public vD
的宣告後,並於 Workbook_Open() 裡
設定了  vD 的屬性,基本上便 OK 了。
往後程式碼之執行均能自動辨認它了。

TOP

回復 9# chaoyiho
我使用 DEBUG MODE 觀察,會產生找不到物件的事實,
故修改成如下:

試試看!

TOP

本帖最後由 luhpro 於 2016-4-22 23:35 編輯

回復 9# chaoyiho
抱歉,現在才有時間回文.

我之所以會把 vD 的定義放在 Module 上,
原先的構想是資料檔案就那一個,
那麼開始時就讀取一次,
字典建好後面只要拿來用就好了,
不用每按一次按鈕就又要重新讀取檔案及建立對應資料.

習慣性的點兩下 "開啟舊檔" 按鈕開啟 CommandButton1_Click 實做自己的構想,
因為回文後才發現處理 "您沒有開啟母檔" 的 Sub 有好幾個,  O.O"
怕會與之前結果重疊才會加那一行消除前手.

至於你發生的問題,
我在這兩個檔案間操作並不會發生,
因為 RemoveAll 只清除 Key 與 資料 間的對應關係,
並不會刪除 vD 字典物件.
研判可能是操作中程式先後順序問題,
導致你沒有執行到  Set vD = CreateObject("Scripting.Dictionary").

而關於問題的處理:
在 10# 的是一種簡單明瞭的處理方法.
不過依個人之前的經驗,
也有可能是個人功力太差,
我發現 Excel 上並不能用一個 Is Nothing 就包辦所有這類物件錯誤的判斷,
因為這一行指令也可能會出現錯誤(因為連 vD 這個物件都不能出現在判斷式中)

另有一個很多人使用的處理方法,
就是一開始就加個 On Error Resume Next,
這樣遇到錯誤就當做沒問題發生繼續跑下去,
運氣好就沒事...
但要是運氣不好的話...

比較正統且不易出現非預期結果的做法是針對錯誤做專門的處理. (請搜尋 On Error 陳述式 的說明)

Sub ChkFile()
...
    On Error GoTo ErrorHandler    ' 開啟錯誤處理程式。
    vD.RemoveAll ' 發生錯誤需做處理的程式
    On Error Goto 0    ' 關閉錯誤處理程式。
...   
Exit Sub        ' 離開程式,以避免進入錯誤處理程式。

ErrorHandler:    ' 錯誤處理程式。
    Select Case Err.Number    ' 檢查錯誤代碼。
        Case 424    ' 發生「此處需要物件」之錯誤。
            Set vD = CreateObject("Scripting.Dictionary") ' 建立物件。(針對錯誤發生原因做補救或處理)

        Case Else ' 用 Err.number 取得錯誤代碼, 用 Err.Description 取得錯誤說明文字. Err.Clear 清除錯誤旗標
            MsgBox Prompt:=Err.Description, Buttons:=vbOK, Title:="發生錯誤"
            Err.Clear
            Exit Sub
    End Select
    Resume    ' 將程式執行步驟回到原發生錯誤的陳述式中。
End Sub


另外, 針對重複且可替代的程序建議另建立副程式以供呼叫, 如:
Image22_Click
Image3_Click
Image32_Click()
CommandButton1_Click()
CommandButton10_Click()
CommandButton14_Click()
CommandButton6_Click()
的內容全部都是 :

    If Application.FindFile = False Then
        MsgBox "您沒有開啟母檔"
    End If

那就可以把這段歸到 Module 內, 設為 Public, 再個別放入呼叫指令即可.
好處是程式碼容易修改與管理, 縮短程式碼, 辨識度也較好.
  1. Public Sub ChkFile()
  2.     If Application.FindFile = False Then
  3.         MsgBox "您沒有開啟母檔"
  4.     End If

  5.     Dim lRow&
  6.    
  7.     lRow = 3
  8.    
  9.     On Error GoTo ErrorHandler    ' 開啟錯誤處理程式。
  10.     vD.RemoveAll
  11.     EXCEL表單處理介面.ListBox1.Clear ' 清除 ListBox 的選單
  12.     On Error GoTo 0    ' 關閉錯誤處理程式。
  13.    
  14.     While Cells(lRow, 1) <> ""
  15.       If Not vD.Exists(CStr(Cells(lRow, 1))) Then
  16.         EXCEL表單處理介面.ListBox1.AddItem CStr(Cells(lRow, 1))
  17.         vD(CStr(Cells(lRow, 1))) = lRow
  18.       End If
  19.       lRow = lRow + 1
  20.     Wend
  21. Exit Sub        ' 離開程式,以避免進入錯誤處理程式。

  22. ErrorHandler:    ' 錯誤處理程式。
  23.     Select Case Err.Number    ' 檢查錯誤代碼。
  24.    
  25.         Case 424    ' 發生「此處需要物件」之錯誤。
  26.             Set vD = CreateObject("Scripting.Dictionary") ' 建立物件。
  27.             
  28.         Case Else   ' 可用 Err.number 取得錯誤代碼, 用 Err.Description 取得錯誤說明文字. Err.Clear 清除錯誤旗標
  29.             MsgBox prompt:="錯誤代碼 : " & Err.Number & Chr(10) & "錯誤原因:" & Err.Description, Buttons:=vbOK, Title:="發生錯誤"
  30.             Err.Clear
  31.             Exit Sub
  32.     End Select
  33.     Resume    ' 將程式執行步驟回到原發生錯誤的陳述式中。
  34.    
  35. End Sub
複製代碼
  1. Private Sub CommandButton1_Click()
  2.   ChkFile
  3. End Sub
複製代碼
餘類推.

表單處理系統3.2(PLS)-a2.zip (631.5 KB)

TOP

回復 13# luhpro

大大說的 "我發現 Excel 上並不能用一個 Is Nothing 就包辦所有這類物件錯誤的判斷"

如果把 Public vD  改成 Public vD  as object

還會出現  Is Nothing  發生問題嗎

蠻好奇的

如果是用 Public vD  
不用 On Err 可以寫成
if  isObject( vD )  then
    if   vD  is Nothing  then
    end if
end if

TOP

本帖最後由 GBKEE 於 2016-4-23 07:31 編輯

回復 14# jackyq
明確的宣告變數型態 ,可使程式碼不易出錯,且容易偵錯
  1. Option Explicit
  2. Dim vD 'As Object
  3. Sub Ex()
  4.     '如 Dim vD  需有執行 Ex1後再執行 Ex
  5.     '如是 Dim  vD  As Object 就不需先執行 Ex1
  6.     MsgBox vD Is Nothing  'Dim vD  程式執行錯誤了   
  7.     Set vD = Nothing
  8.     MsgBox vD Is Nothing
  9.     If vD Is Nothing Then
  10.         Set vD = CreateObject("Scripting.Dictionary")
  11.     End If
  12.     End   '結束所有的程序執行
  13. End Sub
  14. Sub Ex1()
  15.     MsgBox IsObject(vD)
  16.     If Not IsObject(vD) Then
  17.         Set vD = CreateObject("Scripting.Dictionary")
  18.     End If
  19.     MsgBox vD Is Nothing
  20.     'End
  21. End Sub
複製代碼
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

回復 15# GBKEE


    http://forum.twbts.com/redirect. ... 0&fromuid=21301

我有改正押   cc....

TOP

回復 14# jackyq
嗯...
因為我大都是看小幫手與本站自學,
有時忙沒看到的討論串就只能錯失學習了,

在小幫手裡的說明:
Dictionary 物件
  描述
物件,用於儲存資料關鍵字和項目對。
語法
Scripting.Dictionary
請注意
Dictionary 物件與 PERL 相關陣列全等。可以是任何型式的資料的項目被儲存在陣列中。每個項目都與一個唯一的關鍵字相關。該關鍵字用來取出單個項目,通常是整數或字串,可以是除陣列外的任何型態。
下面的程式碼舉例說明了如何建立一個 Dictionary 物件:

Dim d                   '建立一個變數
Set d = CreateObject(Scripting.Dictionary)
d.Add "a", "Athens"     '加入一些關鍵字和項目
d.Add "b", "Belgrade"d.Add "c", "Cairo"
...


所以,我一直學到的都是 Dictionary 物件要用 Variant 資料型態 來宣告,
早先為了解決類似的錯誤, Is Nothing, Is Null, = Null, .... 試了一堆方法耗時挫折,
後來乖乖的用 錯誤處理程式 處理才順利,
謝謝分享指正.

TOP

回復 13# luhpro

抱歉前輩,到現在才回
那是因為我一直想要將您的講解try出來之後再回報我的問題與發現
可是我發現我搞了幾天還是沒能try出來...
真的是能力非常不足
所以今天加班務必希望可以研究出來!!

加上我因為權限的關係無法下載附檔
請問前輩可以將檔案寄到我的信箱嗎?
讓我有個參考..
我的信箱是:
ch.yiho0105@gmail.com

研究您說的這些 結果一個都沒有試出來 一直出現錯誤
我想絕對是因為我的程式碼貼錯地方
因為是初學者的關係
所以資料特別混亂
今天卯起來把程式碼通通做一個整理
現在程式碼已經做好分類 雖然還是很隴長...

我的問題主要有兩個
1.嘗試前輩上面的程式碼 可能因為不知道該放哪邊而造成錯誤進而無法執行
2.關於重複動作的程式碼縮減

感謝前輩們的幫忙!!

TOP

回復 15# GBKEE

感謝版主!!
那再請問版主 請問您這個程式碼的意義試怎麼一個邏輯呢?
希望可以針對這樣的程式碼該放在哪裡做宣告與程式碼內容做個講解
我真的很希望可以學會
再次謝謝版主!!

TOP

回復 12# c_c_lai

感謝cc大的回覆
我有嘗試照著您的指示修改
但是卻會發現出現一個新問題
activeX 錯誤
Google了一下
我卻看不懂這到底是屬於一個什麼樣的東西
嘗試到工具列中尋找這個附件 但是我找不到
請問這是什麼問題所導致
我又該怎麼解決呢?

TOP

        靜思自在 : 口說一句好話,如口出蓮花;口說一句壞話如口吐毒蛇。
返回列表 上一主題