Search code examples
excelvbatextboxautofilter

AutoFilter on multi values found on TextBox (ActiveX)


I have a TextBox on my sheet to get its value to be used as a criteria on another AutoFilter code.
I have set MutliLine property of that textbox to be True. If I copied one cell and paste on the textbox and pressed Enter, then the code runs correctly.
But If copied multi cells and paste on the textbox and pressed Enter, then the result of AutoFilter is nothing with no error raised.
I found the values are pasted already on textbox.
So, I need the Sub Filter_WoNumber accept all the values on textbox as a criteria.
In Advance, greatly thanks for your helps.
This is the code on sheet module:

Private Sub TextBox3_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)

    If KeyCode = Asc(vbCr) Then                 'Run code after press EnterKey
       If Me.TextBox3.Value <> "" Then
            crit_Filter = TextBox3.Value        '"crit_Filter" is a public variable
            Filter_WoNumber
       End If
    End If
    End Sub

and this is the main sub used to AutoFilter:

Public crit_Filter As String

Sub Filter_WoNumber()

    Dim ws As Worksheet, lRow As Long, lcol_n As Long, lastcol As String, rng As Range
    
    Set ws = ActiveSheet

     lRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row                      'Last_Row on Column "A"
       lcol_n = ws.Cells(2, ws.Columns.Count).End(xlToLeft).Column          'Last_Column number on Row_2
        lastcol = Split(Cells(1, lcol_n).Address(True, False), "$")(0)      'Letter of Last_Column

    Set rng = ws.Range("A2:" & lastcol & lRow)                              'Source Range to apply Filter on it

    If Not ws.AutoFilterMode Then rng.AutoFilter                            'Set AutoFilter if not already set
       ws.AutoFilter.ShowAllData
      
    rng.AutoFilter field:=1, Criteria1:=crit_Filter, Operator:=xlFilterValues

End Sub 

Solution

  • MultiLine property only allows to the text to pass on the next line... Also to paste consecutive cells, separating their values by line end separator. You need to extract an array which to contain the separated strings to be used in the next (filtering) step.

    So, try the next way:

    1. Change the public variable declaration:
    Public crit_Filter As Variant
    
    1. Change the text box event code:
    Private Sub TextBox3_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
       If KeyCode = Asc(vbCr) Then                              'Run code after press EnterKey
           If Me.TextBox3.Value <> "" Then
                crit_Filter = Split(TextBox3.Text, vbCrLf) '"crit_Filter" is a public (array) variable
                Filter_WoNumber
           End If
        End If
    End Sub
    

    Not tested, but it should work, I think...

    Edited:

    I tested the above code part and it works as I supposed, except the fact that after pasting a multi range in the text box an extra empty line is also inserted. So, the next function is able to trim it:

    Function Filt(arr) As Variant
       Dim ar, ub As Long, i As Long, k As Long
       ar = arr: ub = UBound(ar)
       For i = UBound(arr) To 0 Step -1
           k = k + 1
           If arr(i) <> "" Then ReDim Preserve ar(ub - k + 1): Exit For
       Next i
       Filt = ar
    End Function
    

    And the splitting line in the event code should be changed in the next way:

       crit_Filter = Filt(Split(TextBox3.Text, vbCrLf)) '"crit_Filter" is a public (array) variable
    

    Second Edit:

    To filter all empty cells in the copied range (from the text box), please use the next function:

    Function filtEmpty(arr) As Variant 'filters all empty elements
       Dim ar, i As Long, k As Long
       ReDim ar(UBound(arr))
    
       For i = LBound(arr) To UBound(arr)
           If arr(i) <> "" Then ar(k) = arr(i): k = k + 1
       Next i
       If k > 0 Then ReDim Preserve ar(k - 1)
       
       filtEmpty = ar
    End Function
    

    Of course, instead of:

    you should use:

         crit_Filter = filtEmpty(Split(TextBox3.Text, vbCrLf))