Board logo

標題: [發問] 如何利用VBA對另個檔案的資料庫進行篩選,然後將選出的值存入表格中 [打印本頁]

作者: colinyang    時間: 2016-4-27 13:37     標題: 如何利用VBA對另個檔案的資料庫進行篩選,然後將選出的值存入表格中

個人對VBA較為生疏,但是目前功能函數已無法滿足,故發問前來求助個位VBA專家..
也希望藉此來提升自身VBA的程度,後續也會努力回饋各位的!!!

檔案有兩個
data.xlsx : 資料列表
[attach]24035[/attach]
list.xlsm : VBA的Form與紀錄區域
[attach]24037[/attach]

如果希望list.xlsm的ComboBox針對data.xlsx資料列表進行篩選
(類似自動篩選,彼此關係是連動的,根據範圍的選定後,後面可選的選項會縮小,例如北部/國立/A學校,南部/私立/H學校)
然後最後list.xlsm的三個ComboBox選定後再按輸入資料後,會輸入在list.xlsm的輸入資料欄位內,若上一列有資料則會繼續向下遞補

希望各位可以幫忙一下,感謝各位的協助,謝謝大家..[attach]24038[/attach]
作者: colinyang    時間: 2016-4-27 20:48

回復 1# colinyang

應該是說ComboBox比較像是連動選單,因為沒有要針對原始資料進行篩選,只有下拉式選單要資料連動而已..
不好意思..
作者: lpk187    時間: 2016-4-28 08:19

回復 2# colinyang

把程式碼貼到UserForm1中試試
  1. Option Explicit
  2. Dim myCon As Object, myRs As Object, SQL$
  3. Private Sub ComboBox1_Click()
  4.     ComboBox2.Clear
  5.     ComboBox3.Clear
  6.     SQL = "SELECT 公私立" & _
  7.           " FROM [學校名單$]" & _
  8.           " Where 區域 Like '" & ComboBox1.Value & "'" & _
  9.           " GROUP BY 公私立;"
  10.     Set myRs = myCon.Execute(SQL)
  11.     ComboBox2.List = Application.Transpose(myRs.GetRows)
  12. End Sub

  13. Private Sub ComboBox2_Click()
  14.     ComboBox3.Clear
  15.     SQL = "SELECT 學校" & _
  16.           " FROM [學校名單$]" & _
  17.           " GROUP BY 學校, [區域] & [公私立]" & _
  18.           " HAVING [區域] & [公私立] Like '" & ComboBox1.Value & ComboBox2.Value & "';"
  19.     Set myRs = myCon.Execute(SQL)
  20.     ComboBox3.List = Application.Transpose(myRs.GetRows)
  21. End Sub

  22. Private Sub CommandButton1_Click() '輸人資料
  23.     Dim ro
  24.     With Sheets("工作表1")
  25.         ro = .Cells(Rows.Count, 2).End(xlUp).Row + 1
  26.         .Cells(ro, 2) = ComboBox1.Value
  27.         .Cells(ro, 3) = ComboBox2.Value
  28.         .Cells(ro, 4) = ComboBox3.Value
  29.     End With
  30.     ComboBox3.Clear
  31.     ComboBox2.Clear
  32.     ComboBox1.Value = ""
  33. End Sub

  34. Private Sub CommandButton2_Click() '離開
  35.     Unload Me
  36. End Sub

  37. Private Sub UserForm_Initialize()
  38.     Set myCon = CreateObject("ADODB.Connection")
  39.     Set myRs = CreateObject("ADODB.Recordset")
  40.     myCon.Open "provider=Microsoft.ACE.OLEDB.12.0;" & _
  41.                "Data Source=" & ThisWorkbook.Path & "\data.xlsx;" & _
  42.                "Extended Properties=""Excel 12.0;HDR=Yes;"";"
  43.     SQL = "SELECT 區域" & _
  44.           " FROM [學校名單$]" & _
  45.           " GROUP BY 區域;"
  46.     Set myRs = myCon.Execute(SQL)
  47.     ComboBox1.List = Application.Transpose(myRs.GetRows)
  48.     Set myRs = Nothing
  49. '    myCon.Close
  50. '    Set myCon = Nothing
  51. End Sub
複製代碼

作者: colinyang    時間: 2016-4-28 10:54

回復 3# lpk187

實際測試,下拉選單與輸入皆無異常,這對我而言真的是一個經典的範例,真的十分的感謝
後續將會再進行分頁的增加再進行測試,好好解析一下程式碼了,若有任何問題會再與您請教
真的是太感謝了!!!
作者: colinyang    時間: 2016-4-29 20:08

回復 3# lpk187

Dear lpk187,

如果我的Data工作表再加入一個"學校名單2"
[attach]24099[/attach]
我在List在新增1個ComboBox4來進行切換作業
已在Form Initial的時候addItem進ComboBox4了
[attach]24100[/attach]
結果在SQL語法中利用"&"進行SQL字串與變數連接時,執行時卻造成以下異常,我該如何修正我的語法來達到變更的目的呢...
[attach]24101[/attach]

以下為程式碼,並附上檔案,還請您指教..謝謝
[attach]24102[/attach]
  1. Option Explicit
  2. Dim myCon As Object, myRs As Object, SQL$
  3. Private Sub ComboBox1_Click()
  4.     ComboBox2.Clear
  5.     ComboBox3.Clear
  6.     '增加了ComboBox4.Value至 FROM的後面來切換工作表
  7.     SQL = "SELECT 公私立" & _
  8.           " FROM [& ComboBox4.Value &$]" & _
  9.           " Where 區域 Like '" & ComboBox1.Value & "'" & _
  10.           " GROUP BY 公私立;"
  11.     Set myRs = myCon.Execute(SQL)
  12.     ComboBox2.List = Application.Transpose(myRs.GetRows)
  13. End Sub

  14. Private Sub ComboBox2_Click()
  15.     ComboBox3.Clear
  16.     '增加了ComboBox4.Value至 FROM的後面來切換工作表
  17.     SQL = "SELECT 學校" & _
  18.           " FROM [& ComboBox4.Value &$]" & _
  19.           " GROUP BY 學校, [區域] & [公私立]" & _
  20.           " HAVING [區域] & [公私立] Like '" & ComboBox1.Value & ComboBox2.Value & "';"
  21.     Set myRs = myCon.Execute(SQL)
  22.     ComboBox3.List = Application.Transpose(myRs.GetRows)
  23. End Sub

  24. Private Sub CommandButton1_Click() '輸人資料
  25.     Dim ro
  26.     With Sheets("工作表1")
  27.         ro = .Cells(Rows.Count, 2).End(xlUp).Row + 1
  28.         .Cells(ro, 2) = ComboBox1.Value
  29.         .Cells(ro, 3) = ComboBox2.Value
  30.         .Cells(ro, 4) = ComboBox3.Value
  31.     End With
  32.     ComboBox3.Clear
  33.     ComboBox2.Clear
  34.     ComboBox1.Value = ""
  35. End Sub

  36. Private Sub CommandButton2_Click() '離開
  37.     Unload Me
  38. End Sub

  39. Private Sub UserForm_Initialize()
  40.     Set myCon = CreateObject("ADODB.Connection")
  41.     Set myRs = CreateObject("ADODB.Recordset")
  42.     myCon.Open "provider=Microsoft.ACE.OLEDB.12.0;" & _
  43.                "Data Source=" & ThisWorkbook.Path & "\data.xlsx;" & _
  44.                "Extended Properties=""Excel 12.0;HDR=Yes;"";"
  45.     '增加了ComboBox4.Value至 FROM的後面來切換工作表
  46.     SQL = "SELECT 區域" & _
  47.           " FROM [& ComboBox4.Value &$]" & _
  48.           " GROUP BY 區域;"
  49.     Set myRs = myCon.Execute(SQL)
  50.     ComboBox1.List = Application.Transpose(myRs.GetRows)
  51.     Set myRs = Nothing
  52.    
  53. '   加入ComboBox4的Vlaue
  54.     ComboBox4.AddItem "學校名單"
  55.     ComboBox4.AddItem "學校名單2"
  56. '    myCon.Close
  57. '    Set myCon = Nothing
  58. End Sub
複製代碼
Best Regards,
Colin
作者: lpk187    時間: 2016-4-29 21:33

回復 5# colinyang

下面代碼摻雜著ADODB及SQL語言,若需求更多說明,請自行Google
  1. Option Explicit
  2. Dim myCon As Object, myRs As Object, SQL$
  3. Private Sub ComboBox1_Click()
  4.     ComboBox2.Clear
  5.     ComboBox3.Clear
  6.     '增加了ComboBox4.Value至 FROM的後面來切換工作表
  7.     SQL = "SELECT 公私立" & _
  8.           " FROM [" & ComboBox4.Value & "$]" & _
  9.           " Where 區域 Like '" & ComboBox1.Value & "'" & _
  10.           " GROUP BY 公私立;"
  11.     Set myRs = myCon.Execute(SQL)
  12.     ComboBox2.List = Application.Transpose(myRs.GetRows)
  13. End Sub

  14. Private Sub ComboBox2_Click()
  15.     ComboBox3.Clear
  16.     '增加了ComboBox4.Value至 FROM的後面來切換工作表
  17.     SQL = "SELECT 學校" & _
  18.           " FROM [" & ComboBox4.Value & "$]" & _
  19.           " GROUP BY 學校, [區域] & [公私立]" & _
  20.           " HAVING [區域] & [公私立] Like '" & ComboBox1.Value & ComboBox2.Value & "';"
  21.     Set myRs = myCon.Execute(SQL)
  22.     ComboBox3.List = Application.Transpose(myRs.GetRows)
  23. End Sub

  24. Private Sub ComboBox4_Change()
  25.     ComboBox3.Clear
  26.     ComboBox2.Clear
  27.     ComboBox1.Clear
  28.     SQL = "SELECT 區域" & _
  29.           " FROM [" & ComboBox4.Value & "$]" & _
  30.           " GROUP BY 區域;"
  31.     Set myRs = myCon.Execute(SQL)
  32.     ComboBox1.List = Application.Transpose(myRs.GetRows)
  33.     Set myRs = Nothing
  34. End Sub

  35. Private Sub CommandButton1_Click() '輸人資料
  36.     Dim ro
  37.     With Sheets("工作表1")
  38.         ro = .Cells(Rows.Count, 2).End(xlUp).Row + 1
  39.         .Cells(ro, 2) = ComboBox1.Value
  40.         .Cells(ro, 3) = ComboBox2.Value
  41.         .Cells(ro, 4) = ComboBox3.Value
  42.     End With
  43.     ComboBox3.Clear
  44.     ComboBox2.Clear
  45.     ComboBox1.Clear
  46.     ComboBox4.Value = ""
  47. End Sub

  48. Private Sub CommandButton2_Click() '離開
  49.    
  50.     Set myRs = Nothing
  51.     myCon.Close
  52.     Set myCon = Nothing
  53.     Unload Me
  54. End Sub

  55. Private Sub UserForm_Initialize()
  56.     Set myCon = CreateObject("ADODB.Connection")
  57.     Set myRs = CreateObject("ADODB.Recordset")
  58.     myCon.Open "provider=Microsoft.ACE.OLEDB.12.0;" & _
  59.                "Data Source=" & ThisWorkbook.Path & "\data.xlsx;" & _
  60.                "Extended Properties=""Excel 12.0;HDR=Yes;"";"
  61. '   加入ComboBox4的Vlaue
  62.     ComboBox4.AddItem "學校名單"
  63.     ComboBox4.AddItem "學校名單2"
  64. End Sub
複製代碼

作者: colinyang    時間: 2016-4-29 21:59

回復 6# lpk187
謝謝你,造成您的困擾了...抱歉
作者: Hsieh    時間: 2016-4-29 23:43

本帖最後由 Hsieh 於 2016-4-29 23:56 編輯

回復 2# colinyang

直覺是Combobox3清單會依據Combobox1,Combobox2內容變動
選定後按下按鈕依序輸入
  1. Public d2

  2. Private Sub ComboBox1_Change()
  3. ex
  4. End Sub

  5. Private Sub ComboBox2_Change()
  6. ex
  7. End Sub

  8. Private Sub ComboBox4_Change()
  9. Set d = CreateObject("Scripting.Dictionary")
  10. Set d1 = CreateObject("Scripting.Dictionary")
  11. Set d2 = CreateObject("Scripting.Dictionary")
  12. fs = ThisWorkbook.Path & "\data.xlsx" '請將2檔案放在同一目錄
  13. Set databook = Workbooks.Open(fs)
  14. With databook.Sheets(ComboBox4.Text)
  15. For Each a In .Range(.[A2], .[A2].End(xlDown))
  16.    d(a.Value) = "" 'A欄不重複清單
  17.    d1(a.Offset(, 1).Value) = "" 'B欄不重複清單
  18.    d2(a & a.Offset(, 1)) = IIf(d2(a & a.Offset(, 1)) = "", a.Offset(, 2), d2(a & a.Offset(, 1)) & "," & a.Offset(, 2)) 'A&B欄清單內容
  19. Next
  20. ComboBox1.List = d.keys
  21. ComboBox2.List = d1.keys
  22. End With
  23. databook.Close 0

  24. End Sub

  25. Private Sub CommandButton1_Click()
  26. Cells(Rows.Count, 2).End(xlUp).Offset(1).Resize(, 3) = Array(ComboBox1, ComboBox2, ComboBox3) '輸入資料
  27. End Sub

  28. Private Sub UserForm_Initialize()
  29. fs = ThisWorkbook.Path & "\data.xlsx" '請將2檔案放在同一目錄
  30. Set databook = Workbooks.Open(fs)
  31. For Each sh In databook.Sheets
  32.    ComboBox4.AddItem sh.Name
  33. Next
  34. databook.Close 0
  35. End Sub
  36. Sub ex()
  37. mystr = ComboBox1 & ComboBox2
  38. If d2(mystr) <> "" Then ComboBox3.List = Split(d2(mystr), ",") 'Combobox3的清單
  39. End Sub
複製代碼

作者: colinyang    時間: 2016-4-30 00:47

回復 8# Hsieh

謝謝版主,看起來又是另外一種方式來進行選取呢!會好好吸收的!不過在Combobox4選取時會有畫面更新的動作
加入Application.ScreenUpdating = False,可以抑止更新狀況,但是同樣輸入的時候資料不會浮現..必須重新打開檔案才看的到
但是程式碼還是很值得學習,謝謝呢!!!
作者: colinyang    時間: 2016-5-2 12:54

各位好..有發現個問題想問了..是關於資料有Null的部分
[attach]24132[/attach]
在轉換時因為會有字串與NULL的問題,所以轉換資料會出現異常
[attach]24133[/attach]
有查詢到SQL可使用CASE進行IS NOT NULL判讀..可是接著在CASE IS NOT NULL "WHEN"的時候
ADODB認不出WHEN的方法..請問該如何將NULL移除呢..謝謝




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)