Results 1 to 10 of 193

Thread: Appendix Thread 2. ( Codes for other Threads, HTML Tables, etc.)

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #11
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    10,457
    Rep Power
    10
    4th macro, (macro explained in last few posts)


    Code:
    ' 4th macro           https://www.excelfox.com/forum/showthread.php/2922-VBA-Count-filtered-rows-in-the-table?p=23270&viewfull=1#post23270                      https://www.excelfox.com/forum/showthread.php/2056-Appendix-Thread-2-(-Codes-for-other-Threads-HTML-Tables-etc-)?p=23247&viewfull=1#post23247
    Private Sub Worksheet_Change(ByVal Target As Range)
    Rem -1 what cell changes don't interest me
         If Target.Cells.Count <> 1 Then Exit Sub              '  More than one cell changed, for example by pasiting new range in
         If Target.Row = 1 Then Exit Sub '                     '  Row 1 is always header so of no interst for adding data
        ' If Target.Value = "" Then Exit Sub '                 '  If we empty a cell we don't want the macro to do anything
    Rem 0 worksheets info, misc temporary stuff
    '0a)
    Dim WsRes As Worksheet: Set WsRes = ThisWorkbook.Worksheets("Results")
    Dim WsFlt As Worksheet: Set WsFlt = ThisWorkbook.Worksheets("Filters")
    Dim LcF As Long: Let LcF = WsFlt.Cells.Item(1, WsFlt.Columns.Count).End(xlToLeft).Column
        If Target.Column > LcF Then Exit Sub
    Dim LrF As Long: Let LrF = Cells.Item(1).Resize(100, LcF).Find(What:="*", after:=Cells.Item(100, 1), LookIn:=xlValues, lookat:=xlPart, searchorder:=xlByRows, searchdirection:=xlPrevious, MatchCase:=False).Row
        If LrF = 1 Then MsgBox prompt:="Nothing to be filterd by": Exit Sub
    '0b)(i)
    Dim rngFlt As Range: Set rngFlt = Range("A1").Resize(LrF, LcF)
    Dim arrFlt() As Variant
     Let arrFlt() = rngFlt.Value2
    '0b)(ii)
    Dim strFlts As String, Rw As Long, Clm As Long
        For Clm = 1 To LcF '  collecting the filter columns infomation as text
            If Cells.Item(1, Clm) = "" Then ' If the top cell is empy then....
            ' .... This will be an empty column, so do nozjing
            Else
             Let strFlts = strFlts & Cells.Item(1, Clm) ' This puts the header, like  Fname  at the start of the string
                For Rw = 2 To LcF '  loop down the rows in a column containing text
                    If Cells.Item(Rw, Clm) = "" Then
                    ' a row with a cell with nothing in it for this column under consideration
                    Else
                     Let strFlts = strFlts & "," & Cells.Item(Rw, Clm)
                    End If
                Next Rw
            ' we are finished with a filter text so..
             Let strFlts = strFlts & "|" '    ..so add an arbritrary thing t
            End If ' this was the check for an empty column indicated by nothing in the top cell
        Next Clm '   On to the next column
     Let strFlts = Left(strFlts, Len(strFlts) - 1)
     ' at this point we have something of this form in strFlts    Fname,rr,ll|FRegion,sh|FCountry
    
    Rem 1
    ' 1a) Get the text file as a long single string
    Dim FileNum As Long: Let FileNum = FreeFile(1)                                    ' https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/freefile-function
    Dim PathAndFileName As String, TotalFile As String
    ' Let PathAndFileName = ThisWorkbook.Path & Application.PathSeparator & "Itchy Bollocks.txt"   '
     Let PathAndFileName = ThisWorkbook.Path & Application.PathSeparator & "Itchy BollocksAlan.txt"   '
    ' Let PathAndFileName = ThisWorkbook.Path & Application.PathSeparator & "data-v9i8Rbfh1ul6_1diL56pb.csv"   '
    Open PathAndFileName For Binary As #FileNum 'Open Route to data. Binary is a fundamental type data input...
    ' Let TotalFile = Space(LOF(FileNum)) '....and wot receives it has to be a string of exactly the right length
    'Get #FileNum, , TotalFile
    '  Or  http://www.eileenslounge.com/viewtopic.php?p=295782&sid=f6dcab07c4d24e00e697fe4343dc7392#p295782
     Let TotalFile = Input(LOF(FileNum), FileNum)
    Close #FileNum
    '1b) 1 dimensional array where elements are text file lines
    Dim arr1D() As String: Let arr1D() = Split(TotalFile, vbCr & vbLf, -1, vbBinaryCompare)
    '1b(ii) !!!  I need the array of the header later
    Dim arrHdrs() As String: Let arrHdrs() = Split(arr1D(0), ",", -1, vbBinaryCompare) ' ###  I don't want to mess with the header later when using the dictionary but I need it to match the filter header to   This array is effectively one containing the values in the first row of the main table.
    '1c) put the text file lines into a  dictionary. These lines are not put in as text lines but as 1 dimensional arrray
    Dim Dik As Object
     Set Dik = CreateObject("Scripting.Dictionary")
    Dim DikCnt As Long
        For DikCnt = 1 To UBound(arr1D())  '                                             ###  Using  (1)  to start with will miss the header at  arr1D(0)
         Dik.Add Key:=DikCnt, Item:=Split(arr1D(DikCnt), ",", -1, vbBinaryCompare) ' Each item in the dictionary is a 1 dimensional array of a single row of the data range
        Next DikCnt
    Dim RwsCnt As Long: Let RwsCnt = Dik.Count
    Dim strRes As String: Let strRes = "Toltal rows: " & RwsCnt & vbCr & vbLf    '  First bit of info in the final string for output
    
    Rem 2
    '2a) Main outer loop  for Filter headers
    Dim Flts() As String: Let Flts() = Split(strFlts, "|", -1, vbBinaryCompare)
    Dim FltsCnt As Long
        For FltsCnt = 0 To UBound(Flts()) ' ========================================================
        Dim Hdr As String: Let Hdr = Flts(FltsCnt) '
        Debug.Print "Using Filter  " & Hdr & "     -----|---- -_-"
            If InStr(1, Hdr, ",", vbBinaryCompare) = 0 Then
            ' in this case the string in  Hdr  is just the header, and we go no further with any other looping
            Else ' at this point its time to do the innner loop for each of the  "things to look for to filtr out by"
            '2b)   a  Split  by the comma  ,  (that we put in in '0b)(ii)) wiil give all filled cell vaues , and ...
            Dim arrFtbys() As String: Let arrFtbys() = Split(Hdr, ",", -1, vbBinaryCompare)
            '2b(i)    The first element in the last made array will be the Filter header name, which we put in a variable, Hdr
             Let Hdr = arrFtbys(0)  '                    ...
            '2b)(ii)  The first element in the last made array will be the Filter header name, and we try to find that in the main table first row, that tell us where in the main table the column we are interested in is. This way the order of where the columns are in the main table is not important
            Dim MtchRes As Variant
    '                         !!!   I got the array of headers   arrHdrs()   earlier    !!!
             Let MtchRes = Application.Match(LCase(Mid(Hdr, 2)), arrHdrs(), 0) '  Either this will return us an VBA error ( it won't actually error ) ,  or it will give a number of the "position along" of where it makes a match
                If IsError(MtchRes) Then MsgBox prompt:="I can't find " & LCase(Mid(Hdr, 2)) & " in the Table": Exit Sub ' For the case of getting an VBA error returned I must have an incorrect header somewhere, maybe a typo in a header somewhere
            Rem 3   Filter out by loop
            Dim FtbyCnt As Long
                For FtbyCnt = 1 To UBound(arrFtbys()) ' ----------Filter out by loop-----------------
                Dim Ftby As String
                 Let Ftby = arrFtbys(FtbyCnt)
                Dim Sperm As Variant '   dicloop dicloop dicloop dicloop dicloop dicloop
                    '3b dicloop
                    For Each Sperm In Dik '  Sperm becomes the next dictionary  Key   Every time this is re done,  there will be less  Sperm  so this line and way of doing it means we are not looking in any found and removed in a previous of this, since they are not in  Dik  anymore
                        If InStr(1, Dik(Sperm)(MtchRes - 1), Ftby, vbBinaryCompare) = 0 Then
                        ' did not find the  "thing to filter out by"
                        Else ' we have a row now that needs to be removed, ans some note of which will be helpful to build the final results
                        Dim FOutDel As String:
                         Let FOutDel = FOutDel & Dik(Sperm)(MtchRes - 1) & vbCr & vbLf ' This will build us a list of matched cell content
                         Dik.Remove Key:=Sperm '  I remove this data line from the dictionary
                        End If
                    Next Sperm ' dicloop dicloop dicloop dicloop dicloop dicloop dicloop
                 Let FOutDel = Left(FOutDel, Len(FOutDel) - 2)
                 Let FOutDel = "Filterd out by """ & Ftby & """" & vbCr & vbLf & FOutDel                      '  ***Add an extra line at the front to say what I am filtering out by
                Debug.Print FOutDel
                Debug.Print "Filtered Out " & UBound(Split(FOutDel, vbCr & vbLf, -1, vbBinaryCompare))        ' ***that  extra line  at the front gives one too many, but as arrays from  Split  start at  indicie/index  0  then the upper bound value is one less than the count of elements,  so these two things cancel themselves out like  -1 +1
                 Let RwsCnt = Dik.Count
                Debug.Print "Left is: " & RwsCnt
                Dim FOutCnt As Long
                 Let FOutCnt = FOutCnt + UBound(Split(FOutDel, vbCr & vbLf, -1, vbBinaryCompare))
                 Let FOutDel = ""
                Next FtbyCnt ' --------------Filter out by loop--------------------------------------
            Debug.Print "Total rows/lines removed for filter " & Hdr & " was " & FOutCnt & vbCr & vbLf
            End If '  we were in a big  If Else  thing where a lot was done
    '     Let strRes = strRes & Mid(Hdr, 2) & " filter: " & RwsCnt - FOutCnt & " Left / Filtered " & FOutCnt & vbCr & vbLf
         Let strRes = strRes & Mid(Hdr, 2) & " filter: " & RwsCnt & " Left / Filtered " & FOutCnt & vbCr & vbLf
         Let FOutCnt = 0
        Next FltsCnt ' ==============================================================================
    
    Rem 5 Output
    WsRes.Activate
    WsRes.Range("A2").Select
     Let WsRes.Range("A2") = strRes
    
    End Sub
    Last edited by DocAElstein; 08-31-2023 at 12:38 PM.

Similar Threads

  1. VBA to Reply All To Latest Email Thread
    By pkearney10 in forum Outlook Help
    Replies: 11
    Last Post: 12-22-2020, 11:15 PM
  2. Appendix Thread. Diet Protokol Coding Adaptions
    By DocAElstein in forum Test Area
    Replies: 6
    Last Post: 09-05-2019, 10:45 AM
  3. Replies: 19
    Last Post: 04-20-2019, 02:38 PM
  4. Search List of my codes
    By PcMax in forum Excel Help
    Replies: 6
    Last Post: 08-03-2014, 08:38 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •