Page 1 of 1

ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Sat Aug 03, 2019 3:49 pm
by warotthan
สวัสดีครับ

รบกวน สอบถาม Logic หรือ เขียน code vba ในไฟล์ที่ Attached ครับ

ต้องการทำให้ dropdown ใน ComboBox โชว์ข้อมูลที่ Filter
เช่น เลือก ComboBox Sex เป็น Male => ComboBox Country ก็จะ Filter เหลือแค่ (TH,MA,VN)
และสามารถเลือกกลับข้างกันได้
Concept คล้ายกับการ Filter แต่ให้มาโชว์ใน Userform ครับ

รบกวนด้วยครับ

Re: ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Sat Aug 03, 2019 3:55 pm
by snasui
:D การใช้งาน VBA ต้องเขียน Code มาเองก่อนตามกฎการใช้บอร์ดข้อ 5 ด้านบน ติดตรงไหนค่อยถามกันต่อครับ

ลองศึกษาเกี่ยวกับการ Add item ให้กับ ComboBox ตาม Link นี้ครับ Add Item

Re: ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Sun Aug 04, 2019 5:10 pm
by warotthan
ผมลองเขียนให้มัน filter ได้แล้ว แต่มันได้แค่ criteria เดียว จะต้องทำอย่างไรเพื่อให้มันสามารถ filter ได้หลายๆ criteria ครับ

Code: Select all

Private Sub ComboBox1_Change()

ComboBox2.Clear
ComboBox3.Clear

Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row

For i = 2 To LastRow
    y = Application.WorksheetFunction.CountIfs(Range(Cells(2, 3), Cells(i, 3)), Cells(i, 3), Range(Cells(2, 2), Cells(i, 2)), ComboBox1)
    z = Application.WorksheetFunction.CountIfs(Range(Cells(2, 4), Cells(i, 4)), Cells(i, 4), Range(Cells(2, 2), Cells(i, 2)), ComboBox1)

If Cells(i, 2) = ComboBox1 Then
    If y = 1 Then ComboBox2.AddItem Cells(i, 3)
    If z = 1 Then ComboBox3.AddItem Cells(i, 4)
End If

Next i

End Sub

Private Sub ComboBox2_Change()

ComboBox1.Clear
ComboBox3.Clear

Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row

For i = 2 To LastRow
    x = Application.WorksheetFunction.CountIfs(Range(Cells(2, 2), Cells(i, 2)), Cells(i, 2), Range(Cells(2, 3), Cells(i, 3)), ComboBox2)
    z = Application.WorksheetFunction.CountIfs(Range(Cells(2, 4), Cells(i, 4)), Cells(i, 4), Range(Cells(2, 3), Cells(i, 3)), ComboBox2)

If Cells(i, 3) = ComboBox2 Then
    If x = 1 Then ComboBox1.AddItem Cells(i, 2)
    If z = 1 Then ComboBox3.AddItem Cells(i, 4)
End If

Next i

End Sub

Private Sub ComboBox3_Change()

ComboBox1.Clear
ComboBox2.Clear

Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row

For i = 2 To LastRow
    x = Application.WorksheetFunction.CountIfs(Range(Cells(2, 2), Cells(i, 2)), Cells(i, 2), Range(Cells(2, 4), Cells(i, 4)), ComboBox3)
    y = Application.WorksheetFunction.CountIfs(Range(Cells(2, 3), Cells(i, 3)), Cells(i, 3), Range(Cells(2, 4), Cells(i, 4)), ComboBox3)

If Cells(i, 4) = ComboBox3 Then
    If x = 1 Then ComboBox1.AddItem Cells(i, 2)
    If y = 1 Then ComboBox2.AddItem Cells(i, 3)
End If

Next i
End Sub

Private Sub UserForm_Initialize()

Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row

Dim x As Integer, y As Integer, z As Integer

For i = 2 To LastRow
    x = Application.WorksheetFunction.CountIf(Range(Cells(2, 2), Cells(i, 2)), Cells(i, 2))
    y = Application.WorksheetFunction.CountIf(Range(Cells(2, 3), Cells(i, 3)), Cells(i, 3))
    z = Application.WorksheetFunction.CountIf(Range(Cells(2, 4), Cells(i, 4)), Cells(i, 4))
    
    If x = 1 Then ComboBox1.AddItem Cells(i, 2)
    If y = 1 Then ComboBox2.AddItem Cells(i, 3)
    If z = 1 Then ComboBox3.AddItem Cells(i, 4)
Next i
    
End Sub
ไฟล์ที่มี Code ตามที่ Attached ครับ

รบกวนด้วยครับ ขอบคุณมากๆครับ

Re: ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Sun Aug 04, 2019 6:22 pm
by snasui
:D ตัวอย่าง Code ครับ

Code: Select all

Dim sList As Object
Dim cLsList As Object
Dim cnList As Object
Dim r As Range, rall As Range

Private Sub ComboBox1_Change()
    Set cLsList = CreateObject("Scripting.Dictionary")
    ComboBox2.Clear
    With Sheets("Sheet1")
        For Each r In rall.Offset(0, 1)
            If r.Offset(0, -1).Value = Me.ComboBox1.Value _
                And Not cLsList.Exists(r.Value) Then
                cLsList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox2.AddItem r.Value
            End If
        Next r
    End With
End Sub

Private Sub ComboBox2_Change()
    Set cnList = CreateObject("Scripting.Dictionary")
    ComboBox3.Clear
    With Sheets("Sheet1")
        For Each r In rall.Offset(0, 2)
            If r.Offset(0, -2).Value = Me.ComboBox1.Value _
                And r.Offset(0, -1).Value = Me.ComboBox2.Value _
                And Not cnList.Exists(r.Value) Then
                cnList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox3.AddItem r.Value
            End If
        Next r
    End With
End Sub

Private Sub UserForm_Initialize()
    Set sList = CreateObject("Scripting.Dictionary")
    With Sheets("Sheet1")
        Set rall = .Range("b2", .Range("b" & .Rows.Count).End(xlUp))
        For Each r In rall
            If Not sList.Exists(r.Value) Then
                sList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox1.AddItem r.Value
            End If
        Next r
    End With
End Sub

Re: ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Sun Aug 04, 2019 6:51 pm
by warotthan
ขอบคุณมากครับ จากตัวอย่าง Code มันทำการ Filter เรียงจาก ComboBox1 ไป 2 และ ไป3
ถ้าต้องการให้สามารถ Filter ข้ามกัน และสามารถสลับกันได้ เช่น ComboBox2 ไป3 และ ไป1 ต้องทำอย่างไรครับ

Re: ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Sun Aug 04, 2019 7:17 pm
by snasui
:D ต้องปรับปรุงมาเอง ติดตรงไนค่อยถามกันต่อ

ทุกคำถามจะต้องผ่านกระบวนการปรับปรุงมาเองก่อนแล้ว ไม่สามารถนำคำตอบมาถามต่อเนื่องได้โดยที่ยังไม่มีการปรับปรุงมาด้วยตนเองก่อนครับ

Re: ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Sun Aug 04, 2019 9:57 pm
by warotthan
รบกวนถาม logic ในการเขียนได้มั้ยครับ เพราะผมนึกไม่ออกจริงๆ แล้วเดี๋ยวนำไปปรับปรุงเองครับ :D

Re: ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Sun Aug 04, 2019 9:58 pm
by snasui
:D หลักการคือหาค่าไม่ซ้ำแล้วนำไป Add ไว้ใน ComboBox ที่เกี่ยวข้องครับ

การหาค่าไม่ซ้ำใช้ Scripting.Dictionay มาช่วยครับ

Re: ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Mon Aug 05, 2019 10:02 am
by warotthan
พยายามให้สามารเลือก filter จาก ComboBox ไหนก่อนก็ได้ โดย ComboBox ที่เลือกแล้วจะ Lock ไว้ แต่ยัง Run ไม่ผ่านครับ
รบกวนอาจารย์ช่วยด้วยครับ

Code: Select all


Dim sList As Object
Dim cLsList As Object
Dim cnList As Object
Dim r As Range, rall As Range

Private Sub ComboBox1_Change()
    Set cLsList = CreateObject("Scripting.Dictionary")

    With Sheets("Sheet1")
    
    If ComboBox2 = "" Then
        ComboBox2.Clear
        For Each r In rall.Offset(0, 1)
            If r.Offset(0, -1).Value = Me.ComboBox1.Value _
                And Not cLsList.Exists(r.Value) Then
                cLsList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox2.AddItem r.Value
            End If
    ComboBox1.Enabled = False
        Next r
    End If
    
      If ComboBox3 = "" Then
        ComboBox3.Clear
        For Each r In rall.Offset(0, 2)
            If r.Offset(0, -2).Value = Me.ComboBox1.Value _
                And Not cLsList.Exists(r.Value) Then
                cLsList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox3.AddItem r.Value
            End If
                ComboBox1.Enabled = False
        Next r
          End If
          
    End With
    
End Sub

Private Sub ComboBox2_Change()
    Set cnList = CreateObject("Scripting.Dictionary")

    With Sheets("Sheet1")

        If ComboBox1 = "" Then
        ComboBox1.Clear
        For Each r In rall.Offset(0, 0)
            If r.Offset(0, 1).Value = Me.ComboBox2.Value _
                And Not cLsList.Exists(r.Value) Then
                cLsList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox1.AddItem r.Value
            End If
    ComboBox2.Enabled = False
        Next r
    End If
    
      If ComboBox3 = "" Then
        ComboBox3.Clear
        For Each r In rall.Offset(0, 2)
            If r.Offset(0, -1).Value = Me.ComboBox2.Value _
                And Not cLsList.Exists(r.Value) Then
                cLsList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox3.AddItem r.Value
            End If
                ComboBox2.Enabled = False
        Next r
          End If
          
    End With
End Sub

Private Sub ComboBox3_Change()
    Set cnList = CreateObject("Scripting.Dictionary")

    With Sheets("Sheet1")

        If ComboBox1 = "" Then
        ComboBox1.Clear
        For Each r In rall.Offset(0, 0)
            If r.Offset(0, 2).Value = Me.ComboBox3.Value _
                And Not cLsList.Exists(r.Value) Then
                cLsList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox1.AddItem r.Value
            End If
    ComboBox3.Enabled = False
        Next r
    End If
    
      If ComboBox2 = "" Then
        ComboBox2.Clear
        For Each r In rall.Offset(0, 1)
            If r.Offset(0, 1).Value = Me.ComboBox3.Value _
                And Not cLsList.Exists(r.Value) Then
                cLsList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox2.AddItem r.Value
            End If
                ComboBox3.Enabled = False
        Next r
          End If
          
    End With
    
End Sub

Private Sub UserForm_Initialize()
    Set sList = CreateObject("Scripting.Dictionary")
    With Sheets("Sheet1")
    
        Set rall = .Range("b2", .Range("b" & .Rows.Count).End(xlUp))
        For Each r In rall
            If Not sList.Exists(r.Value) Then
                sList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox1.AddItem r.Value
            End If
        Next r
        
        Set rbll = .Range("c2", .Range("c" & .Rows.Count).End(xlUp))
        For Each r In rbll
            If Not sList.Exists(r.Value) Then
                sList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox2.AddItem r.Value
            End If
        Next r
        
          Set rcll = .Range("d2", .Range("d" & .Rows.Count).End(xlUp))
          For Each r In rcll
            If Not sList.Exists(r.Value) Then
                sList.Add Key:=r.Value, Item:=r.Value
                Me.ComboBox3.AddItem r.Value
            End If
        Next r
        
    End With
End Sub



Re: ทำให้ ComboBox filter ข้อมูลหลาย criteria

Posted: Tue Aug 06, 2019 8:04 pm
by snasui
:D ช่วยยกตัวอย่างการเลือกมาทั้ง 3 ComboBox ว่า

หากเลือก ComboBox1, 2 และ 3 เป็นค่าหนึ่ง ๆ แล้วให้ ComboBox ที่เหลือแสดงแสดงอย่างไร จะได้สะดวกในการทำความเข้าใจครับ