Filter detection

Solved
Shadorb Posted messages 60 Status Member -  
Shadorb Posted messages 60 Status Member -
Hello,



I wanted to know if it was possible to maybe detect the index of the active filter? In order to create a code that would depend on the active filter.

Thank you very much.

3 answers

  1. ThauTheme Posted messages 1564 Status Member 160
     
    Hello Shadorb, hello forum,

    The code below returns the first active filter. If there is only one, it should be fine; otherwise, adjustments will be needed...

    Public Sub Macro1() Dim O As Worksheet 'declares the variable O (Sheet) Dim I As Byte 'declares the variable I (Increment) Dim CF As Integer 'declares the variable CF (Filtered Column) Set O = Sheets("Feuil1") 'defines the sheet O (to be adjusted for your case) If O.FilterMode Then 'condition: if the sheet O is filtered For I = 1 To O.AutoFilter.Filters.Count 'loops through all columns If O.AutoFilter.Filters.Item(I).On Then CF = I: Exit For 'if the column is filtered, sets the variable CF, exits the procedure Next I 'next column in the loop End If 'end of the condition MsgBox CF 'message displaying CF End Sub


    --
    See you later,
    ThauTheme
    1
    1. Shadorb Posted messages 60 Status Member
       
      If I understand correctly, it returns the number of the column where the filter is active.

      It helps me move forward, but it's not entirely my question. How can I know which index is selected in this filter? If I sort by heating, how can I detect that it's indeed heating and not sanitary that is selected in the filter?

      EDIT: After discussing with the interested parties, it was agreed that only one filter will be active at a time.
      0
  2. ThauTheme Posted messages 1564 Status Member 160
     
    Re,

    It's exactly the answer to your question!... It returns the index of the filter and not the cell value... It seems to me that's what you asked for, right?

    You just need to adjust the message, if your table starts in A1:

    MsgBox Cells(1, CF).Value

    where 1 corresponds to the row number.

    --
    See you later,
    ThauTheme
    0
    1. Shadorb Posted messages 60 Status Member
       
      In that case, I don't understand then.
      How can it give me 3 here?
      http://hpics.li/92baa3c

      I think we're not talking about the same thing :)
      0
    2. ThauTheme Posted messages 1564 Status Member 160
       
      When you flat a tire? Do you bring a photo to your mechanic to get it fixed?
      0
      1. Shadorb Posted messages 60 Status Member > ThauTheme Posted messages 1564 Status Member
         
        It's funny, haven't I already had that one?

        I can't share the Excel, otherwise it would already be done and we wouldn't be talking about it anymore.
        0
    3. ThauTheme Posted messages 1564 Status Member 160
       
      So good luck!...
      0
  3. Anonymous user
     
    Good evening Shadorb,

    Since you didn't specify the name of your sheet, I will assume it's Sheet1.

    In your message #2, you wrote: "If I sort by heating how
    do I detect that it's indeed heating and not sanitary that is selected
    in the filter?".

    So looking at your screenshot, I see that it concerns column no. 2 of the table, thus the 2nd filter (there's one per column).

    MsgBox Worksheets("Sheet1").AutoFilter.Filters(2).Criteria1

    If you have filtered this column with the criterion "HEATING",
    the above line should display "HEATING";

    It's up to you to remove the first character if you want to test only
    "HEATING", but nothing prevents you from leaving it as is and
    testing "HEATING".

    Note: I think you also need to add some code to
    detect if the autofilter is active, and only if so, "query" what the criterion is.

    But for that, I'll leave it to you!

    Let me know if you succeeded, then mark the topic as "Resolved".
    Otherwise, you can ask me for further details.

    Best regards. 😊
    0
    1. Shadorb Posted messages 60 Status Member
       
      Thank you, that's exactly what I'm looking for. However, I have a couple of questions: how do I test the selected criterion? I mean, I have HEATING, SANITARY, and ELECTRICITY, how can I test the others? It works great for heating but only for that.

      Another thing, can we detect the "filter modified" event? So that I can manage the code when the user sorts directly. (For now, I have a button).

      Finally, when filtering by a criterion, I need to find the last populated row. In order to create a total row below it. The problem is that the rows seem just hidden, and it counts all the others ignoring the filter. (I'm not sure if I've explained that well)

      I'm using this:
      LastLineFeuil1 = Worksheets(1).Range("C" & Rows.Count).End(xlUp).Row


      Thank you.
      0
    2. Anonymous user > Shadorb Posted messages 60 Status Member
       
      1) You wrote: "It works great for heating but only that one.";
      if it returns Criteria1 "=HEATING", there is no reason for it not to return "=SANITARY" or "=ELECTRICITY".

      But maybe your first question wasn't for the same column, but for
      the others? In that case, you just need to put the correct filter number, that is to say
      the number of the corresponding column. So:

      a) For column 1 "Member", it's filter 1
      b) For column 2 "Activity", it's filter 2
      c) For column 3 "Supplier", it's filter 3
      d) For column 4 "Selling price", it's filter 4
      e) For column 5 "Cost price", it's filter 5

      So you just need to put the correct number n for:
      Worksheets("Sheet1").AutoFilter.Filters(n).Criteria1

      But leave Criteria1! Criteria2 is for a test that includes 2 values.

      Example: is greater than or equal to 20 And is less than or equal to 100.
      In this case, Criteria1: ">=20" and Criteria2: "<=100".

      -------------------------------------------------------

      2) Look at this line of code:

      MsgBox Worksheets("Sheet1").AutoFilter.Filters(n).On
      n is the column number of the table = filter number
      On is for On / Off: active or not

      If there is no filter criterion for the column in question,
      it returns FALSE; otherwise, it returns TRUE,
      and only then check the filter criteria.

      For what you're asking, I believe there is no other way
      than to compare, for each filter, the values "before" and "after"
      first of On, then possibly of Criteria1 and Criteria2.

      Because if On was before FALSE then became after TRUE (or vice versa),
      that's enough to determine that the filter for the column in question has been
      modified: no need then to test Criteria1 (and even less Criteria2).

      What I mean is that you should test Criteria2 only if, for before
      and after: On = TRUE and Criteria1 is the same.

      And you should also check .Operator: 1 for And; 2 for Or

      -------------------------------------------------------

      3) When we use an automatic filter, it is fortunate that the rows that
      do not match the criterion(s) are only hidden and not
      deleted! This is completely normal, and it also allows to:

      a) Change the criterion, and see again the rows previously hidden
      that correspond to the new criterion(na).

      b) Disable the automatic filter, and see again all the rows
      of the table.

      But if your line of code:

      LastLineSheet1 = Worksheets(1).Range("C"&Rows.Count).End(xlUp).Row

      does not return the number of the last row, the only explanation I see is that you have one or more other data under your
      table, and thus the .End(xlUp).Row gets stuck on it, before being able to "encounter" the last row of your table located higher.

      Looking forward to your reply. ????
      0
    3. Shadorb Posted messages 60 Status Member > Anonymous user
       
      Thank you very much, it's really helping me make progress.
      So, to count the unhidden lines I've done this:
      LastLineFeuil1 = Worksheets(1).Range("D" & Rows.Count).End(xlUp).Row
      For l = 4 To LastLineFeuil1
      If Not Rows(l).Hidden Then R = R + 1
      Next l

      Probably not the best solution but it does what it needs to do.

      Then I have a rather tricky problem:
      If (Worksheets(1).AutoFilter.Filters(4).On = True) Then
      MsgBox Worksheets(1).AutoFilter.Filters(4).Criteria1
      MsgBox (R)
      Else
      MsgBox ("Supplier filter not used")
      End If


      I just shifted the test column but I get an error that occurs sometimes, I can't identify the source. Error '91' Object variable or With block variable not set.

      If I understand what it means, shouldn't it go into the else of my loop?
      Then, I didn't quite understand how to test the filter change.
      Should I store the current filter value in a string and then compare it with the next one?

      The user will definitely have to use a button to launch the test, right?

      See you soon.
      0
    4. Anonymous user > Shadorb Posted messages 60 Status Member
       
      Hello Shadorb,

      1) To count the unhidden rows, try this instead:

       LastLineFeuil1 = Worksheets(1).Range("D" & Rows.Count).End(xlUp).Row R = WorksheetFunction.Subtotal(103, Range("D4:D" & LastLineFeuil1)) 

      - no need for the For l.. Next l loop (l lowercase, not I uppercase)
      - no need for the If Not Rows(l).Hidden Then R = R + 1 test

      But be careful to always leave 103: that's the code for COUNTA
      so that the Subtotal function returns the number of values
      in the specified range while ignoring hidden rows.

      ---------------------------------------------------------

      I used the same starting line as you: 4; assuming your header row is in row 3, and the first data row is row 4, just
      below.

      I also kept your same column D, but you can choose another one
      if you prefer. In any case, the result will be the same since for
      all the columns of your table, the hidden rows are of course
      the same.

      ---------------------------------------------------------

      For more information on the function used, type in a blank cell
      of your Excel sheet: =subtotal( ; click on fx in front of the formula bar,
      and check the online help. Don’t forget the point (.) between “sub” and “total”!

      =================================

      2) In your Else, there is: "Supplier filter not used", which therefore indicates that
      you are testing the filter of the "Supplier" column. However, on the screenshot of your
      initial table, it is column number 3; so your filter is number 3, not 4!

      Unless, of course, you have added another column before, but I don't think so; if you have changed the structure of your table, send me another screenshot (with row numbers and column letters)!

      ---------------------------------------------------------

      You have put unnecessary parentheses, which makes me think that you have already
      programmed in Turbo-Pascal before, right?  😉

      The " = True" test is also unnecessary; the 2 successive MsgBoxes can be combined
      into one (advantage: 1 box instead of 2); and by “factoring” filter 3, it gives:

       With Worksheets(1).AutoFilter.Filters(3) If .On Then MsgBox .Criteria1 & vbLf & R Else MsgBox "Supplier filter not used" End If End With 

      On the other hand, note that your 2 previous lines to calculate R
      are only useful if we display this R; so since it's useful for the first part of the If only, and not for the Else, we move the
      2 lines in question into the If, before using R:

       With Worksheets(1).AutoFilter.Filters(3) If .On Then LastLineFeuil1 = Worksheets(1).Range("D" & Rows.Count).End(xlUp).Row R = WorksheetFunction.Subtotal(103, Range("D4:D" & LastLineFeuil1)) MsgBox "Criterion: " & .Criteria1 & vbLf & "Number of rows: " & R Else MsgBox "Supplier filter not used" End If End With 

      ---------------------------------------------------------
      Attention!

      Do not move your first line if the rest of your code needs LastLineFeuil1;
      do not move your second line if the rest of your code needs R.
      ---------------------------------------------------------

      You will also notice that I added a little text before displaying the criterion
      and before R; if you like it less, put another text or remove "“...“ & ".

      =================================

      3) Error 91 does not concern whether to enter the Else or not; if it's
      "Object variable not defined", it means that VBA cannot find an object
      that something (expression, method, property, or else) depends on;
      if it's "Block variable not defined", the block is not necessarily an If..Then..Else block, it can also be a With..End block or something else...

      I don't think your error 91 was due to your filter number error,
      but check if it reproduces when you set filter number 3 (with
      my code above). Because if that has resolved, there's no need to look further!

      However, if it does reproduce, I would need you to show me the part of code
      where it occurs, and also tell me on which line it stops and highlight in yellow
      when you click on the debug button.

      =================================

      4) Setting up a button for the user to run the macro that checks whether there has been a filter change or not depends on what you want to do; and for what purpose would you want the user to know that the filter has been modified?

      So it is not necessary for the user to run this test themselves:
      if you really need it, you can do it automatically via VBA,
      without any user intervention; knowing at what time you want this test to be made: for example, only when running the corresponding macro, or based on an event like "on activating
      the Worksheets(1) sheet" or something else...

      =================================

      This present message is already super long, so for the way to test
      the filter change, we will see that another time, when you have resolved
      all the problems above.

      Best regards.  😊
      0
    5. Shadorb Posted messages 60 Status Member > Anonymous user
       
      When you explain, you really go all out, it's cool!

      Indeed, the table has slightly changed, and with the filter below activated, it crashes.
      http://hpics.li/59c9dff

      Since I don't know how to highlight in yellow on the site, I'm sending you a debugging image again.
      http://hpics.li/dbc6d44

      Honestly, I don't understand this error. I have activated filter number 4. I must not understand something about how the filters work.
      0