Page 13 of 38 FirstFirst ... 3111213141523 ... LastLast
Results 121 to 130 of 380

Thread: Appendix Thread. ( Codes for other Threads, etc.) Event Coding Drpdown Data validation

  1. #121
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10

    Filter for columns not for rows. Phill Turd Sorted

    continued from last post.......

    Private Sub Worksheet_Change(ByVal Target As Range)
    This reacts to changes of values in column A, for example when selecting a value from the drop down list
    Initially a "Blank" selection is changed to "" , and if a "-" was given then the original range is restored

    The rest of this routine is very similar to the routine here https://www.eileenslounge.com/viewto...245286#p245218 The difference is that we need here now to determine one set of column indices to use in a code line like pseudo the following to get the required filtered range
    Output() = Index ( Cells , allRowIndicies , someColumnIndicies)
    ( The previous example at that link required all columns and 2 sets of some rows for two outputs based on a column having a Y or not )




    Code:
    Sub testieCLDoWhile()
    Dim testieletter As String
     Let testieletter = CLDoWhile(3) ' should return "C"
    End Sub
    '   CLDoWhile  is a Function to get column letter from column number
    Function CLDoWhile(ByVal lclm As Long) As String 'Using chr function and Do while loop      For example http://www.excelforum.com/excel-programming-vba-macros/796472-how-to-go-from-column-number-to-column-letter.html
    Dim rest As Long 'Variable for what is "left over" after subtracting as many full 26's as possible
        Do
        '    Let rest = ((lclm - 1) Mod 26) 'Gives 0 to 25 for Column Number "Left over" 1 to 26. Better than ( lclm Mod 26 ) which gives 1 to 25 for clm 1 to 25 then 0 for 26
        '    Let FukOutChrWithDoWhile = Chr(65 + rest) & FukOutChrWithDoWhile 'Convert rest to Chr Number, initially with full number so the "units" (0-25), then number of 26's left over (if the number was so big to give any amount of 26's in it, then number of 26's in the 26's left over (if the number was so big to give any amount of 26 x 26's in it, Enit ?
        '    'OR
        Let CLDoWhile = Chr(65 + (((lclm - 1) Mod 26))) & CLDoWhile
        Let lclm = (lclm - (1)) \ 26 'This gives the number of 26's ( if any ), but just the excact part, in the next number down , - so applying the rest formula to this new number will again leave a difference "left over" rest.
        'lclm = (lclm - (rest + 1)) \ 26 ' As the number is effectively truncated here, any number from 1 to (rest +1)  will do in the formula
        Loop While lclm > 0 'Only loop further if number was big enough to still have 0-25's in it
    End Function
    '
    '
    Sub testieWksChange()
     Call Worksheet_Change(Me.Range("A2"))
     Let Application.EnableEvents = True ' Just incase it got turned off
    End Sub
    
    Private Sub Worksheet_Change(ByVal Target As Range)
        If IsArray(Target.Value) Then Exit Sub
    Rem 1 main worksheet data range info
    Dim CntItms As Long: Let CntItms = Me.Range("B" & Rows.Count & "").End(xlUp).Row
        If Application.Intersect(Target, Me.Range("A2:A" & CntItms & "")) Is Nothing Then Exit Sub ' only do anything for a selection in the A column range.
    Dim CntClms As Long: Let CntClms = Me.Cells.Item(1, Columns.Count).End(xlToLeft).Column
        If Target.Value = "Blank" Then Let Application.EnableEvents = False: Let Target.Value = "": Let Application.EnableEvents = True
    Rem 2 test data range reset
        If Target.Value = "-" Then
         Let Application.EnableEvents = False
         Let Me.Range("C1", Me.Cells.Item(CntItms, Worksheets("Sheet1 (2)").Cells.Item(1, Columns.Count).End(xlToLeft).Column)).Value = Worksheets("Sheet1 (2)").Range("C1", Worksheets("Sheet1 (2)").Cells.Item(CntItms, Worksheets("Sheet1 (2)").Cells.Item(1, Columns.Count).End(xlToLeft).Column)).Value
         Let Application.EnableEvents = True
    Rem 3 Get indices( column numbers) for required columns, and all row indicies
        '3a) indices( column numbers) for required columns
        Else ' selected value is a unique value or ""  for  "Blank"
        Dim arrLine() As Variant: Let arrLine() = Me.Range(Me.Cells.Item(Target.Row, 1), Me.Cells.Item(Target.Row, CntClms)).Value ' I dont need the first and third column, but it makes it easier to keep track of the correct columns indicie
        Dim Cnt As Long
        Dim strClms As String: Let strClms = "1 2 " ' For our required columns containing in this row the target selected value
            For Cnt = 3 To CntClms ' check columns from 3 for a match to the value in column 1
                If CStr(arrLine(1, Cnt)) = CStr(Target.Value) Then ' This is indication of wanted column as it contains the value
                 Let strClms = strClms & Cnt & " "
                Else
                End If
            Next Cnt
         Let strClms = Left(strClms, Len(strClms) - 1) ' Take off last " "
        Dim clmsSpt() As String: Let clmsSpt() = Split(strClms, " ", -1, vbBinaryCompare)
        Dim Clms() As String: ReDim Clms(1 To UBound(clmsSpt()) + 1) ' for        {1,2,7,9} = required columns
            For Cnt = 0 To UBound(clmsSpt())
             Let Clms(Cnt + 1) = clmsSpt(Cnt)
            Next Cnt
        '3b) all data ro indicies
        Dim Rws() As Variant: Let Rws() = Evaluate("=Row(1:" & CntItms & ")") ' = {1;2;3;4;5;6;7;8;9;.......... , CntItms} = required rows ( all rows are required )
    Rem 4 Output filtered columns
         Dim arrOut() As Variant: Let arrOut() = Application.Index(Cells, Rws(), Clms())
         Let Application.EnableEvents = False
         Me.Cells.ClearContents
         Let Range("A1").Resize(UBound(arrOut(), 1), UBound(arrOut(), 2)).Value = arrOut()
         Let Application.EnableEvents = True
        End If
    End Sub
    
    
    Sub testsort()
    
    Dim df As String, d As String
     df = "df"
     Dim var
      If IsNumeric(df) Then var = CLng(df)
     Dim dg As String
     dg = "dg"
     MsgBox (dg > df) & "   " & (dg > d)
     
    
    End Sub
    A Folk, A Forum, A Fuhrer ….

  2. #122
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10

    Simplified coding

    Simplified coding for yasser
    https://eileenslounge.com/viewtopic....245769#p245769

    Coding for worksheet code module for worksheet "Sheet1"
    Code:
    Option Explicit
    Public Sub Worksheet_SelectionChange(ByVal Target As Range)
        If IsArray(Target.Value) Then Exit Sub
    Rem 1 main worksheet data range info
    Dim CntItms As Long: Let CntItms = Me.Range("B" & Rows.Count & "").End(xlUp).Row
        If Application.Intersect(Target, Me.Range("A2:A" & CntItms & "")) Is Nothing Then Exit Sub
        If Worksheets("DataSaladinValagationLists").Range("A" & Target.Row & "").Value <> "" Then Exit Sub
    Dim CntClms As Long: Let CntClms = Me.Cells.Item(1, Columns.Count).End(xlToLeft).Column
    Rem 2 make drop down list for this row
    
     Let Application.EnableEvents = False
     Me.Range("C" & Target.Row & "", Me.Cells.Item(Target.Row, CntClms)).SpecialCells(xlCellTypeConstants).Copy
     Let Application.EnableEvents = True
    Dim Dtaobj As Object
     Set Dtaobj = GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
     Dtaobj.GetFromClipboard: Dim strClip As String: Let strClip = Dtaobj.GetText()
     Let strClip = Left(strClip, Len(strClip) - 2)
    Application.CutCopyMode = False
    Dim strSptInDrpPlop() As String: Let strSptInDrpPlop() = Split(strClip, vbTab, -1, vbBinaryCompare)
    Dim UnEeks As String
    Dim Cnt As Long
        For Cnt = 0 To UBound(strSptInDrpPlop())
         If InStr(1, UnEeks, Trim(strSptInDrpPlop(Cnt)), vbBinaryCompare) = 0 And Not Trim(strSptInDrpPlop(Cnt)) = "" And Not strSptInDrpPlop(Cnt) = vbTab Then
          Let UnEeks = UnEeks & Trim(strSptInDrpPlop(Cnt)) & " "
         Else
         End If
        Next Cnt
    
     Let UnEeks = Left(UnEeks, Len(UnEeks) - 1)
     
     Let strSptInDrpPlop() = Split(UnEeks, " ", -1, vbBinaryCompare)
    
    Dim Eye As Long, Jay As Long
        For Eye = 0 To UBound(strSptInDrpPlop()) - 1
           For Jay = Eye + 1 To UBound(strSptInDrpPlop())
               If IsNumeric(strSptInDrpPlop(Eye)) And IsNumeric(strSptInDrpPlop(Jay)) Then
                    If CLng(strSptInDrpPlop(Eye)) > CLng(strSptInDrpPlop(Jay)) Then
                    Dim Temp As String: Let Temp = strSptInDrpPlop(Jay): Let strSptInDrpPlop(Jay) = strSptInDrpPlop(Eye): Let strSptInDrpPlop(Eye) = Temp
                    Else
                    End If
               Else
                    If strSptInDrpPlop(Eye) > strSptInDrpPlop(Jay) Then
                     Let Temp = strSptInDrpPlop(Jay): Let strSptInDrpPlop(Jay) = strSptInDrpPlop(Eye): Let strSptInDrpPlop(Eye) = Temp
                    Else
                    End If
               End If
           Next Jay
        Next Eye
    
        With Worksheets("DataSaladinValagationLists")
         Let .Range("A" & Target.Row & "").Value = "-"
         Let .Cells.Item(Target.Row, 2).Resize(1, UBound(strSptInDrpPlop()) + 1).Value = strSptInDrpPlop()
         Let .Cells.Item(Target.Row, UBound(strSptInDrpPlop()) + 3).Value = "Blank"
        End With
    
    Target.Validation.Delete
    Target.Validation.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1:="=DataSaladinValagationLists!A" & Target.Row & ":" & CLDoWhile(UBound(strSptInDrpPlop()) + 3) & "" & Target.Row & ""
    End Sub
    Function CLDoWhile(ByVal lclm As Long) As String
    Dim rest As Long
        Do
          
        Let CLDoWhile = Chr(65 + (((lclm - 1) Mod 26))) & CLDoWhile
        Let lclm = (lclm - (1)) \ 26
        
        Loop While lclm > 0
    End Function
    Public Sub Worksheet_Change(ByVal Target As Range)
        If IsArray(Target.Value) Then Exit Sub
    Rem 1 main worksheet data range info
    Dim CntItms As Long: Let CntItms = Me.Range("B" & Rows.Count & "").End(xlUp).Row
        If Application.Intersect(Target, Me.Range("A2:A" & CntItms & "")) Is Nothing Then Exit Sub
    Dim CntClms As Long: Let CntClms = Me.Cells.Item(1, Columns.Count).End(xlToLeft).Column
        If Target.Value = "Blank" Then Let Application.EnableEvents = False: Let Target.Value = "": Let Application.EnableEvents = True
    Rem 2 test data range reset
        If Target.Value = "-" Then
         Let Application.EnableEvents = False
         Let Me.Range("C1", Me.Cells.Item(CntItms, Worksheets("Sheet1 (2)").Cells.Item(1, Columns.Count).End(xlToLeft).Column)).Value = Worksheets("Sheet1 (2)").Range("C1", Worksheets("Sheet1 (2)").Cells.Item(CntItms, Worksheets("Sheet1 (2)").Cells.Item(1, Columns.Count).End(xlToLeft).Column)).Value
         Let Application.EnableEvents = True
    Rem 3 Get indices( column numbers) for required columns, and all row indicies
        
        Else
        Dim arrLine() As Variant: Let arrLine() = Me.Range(Me.Cells.Item(Target.Row, 1), Me.Cells.Item(Target.Row, CntClms)).Value
        Dim Cnt As Long
        Dim strClms As String: Let strClms = "1 2 "
            For Cnt = 3 To CntClms
                If CStr(arrLine(1, Cnt)) = CStr(Target.Value) Then
                 Let strClms = strClms & Cnt & " "
                Else
                End If
            Next Cnt
         Let strClms = Left(strClms, Len(strClms) - 1)
        Dim clmsSpt() As String: Let clmsSpt() = Split(strClms, " ", -1, vbBinaryCompare)
        Dim Clms() As String: ReDim Clms(1 To UBound(clmsSpt()) + 1)
            For Cnt = 0 To UBound(clmsSpt())
             Let Clms(Cnt + 1) = clmsSpt(Cnt)
            Next Cnt
        
        Dim Rws() As Variant: Let Rws() = Evaluate("=Row(1:" & CntItms & ")")
    Rem 4 Output filtered columns
         Dim arrOut() As Variant: Let arrOut() = Application.Index(Cells, Rws(), Clms())
         Let Application.EnableEvents = False
         Me.Cells.ClearContents
         Let Range("A1").Resize(UBound(arrOut(), 1), UBound(arrOut(), 2)).Value = arrOut()
         Let Application.EnableEvents = True
        End If
    End Sub


    Extra coding to go in normal code module
    Code:
    Option Explicit
    Sub Phillip_Filters()
    Dim Ws1 As Worksheet: Set Ws1 = ThisWorkbook.Worksheets("Sheet1")
     Dim Lr As Long: Let Lr = Ws1.Range("B" & Rows.Count & "").End(xlUp).Row
    Dim Cnt As Long
     Let Application.EnableEvents = False
        For Cnt = 2 To Lr
         Call Sheet1.Worksheet_SelectionChange(Ws1.Range("A" & Cnt & ""))
        Next Cnt
     Let Application.EnableEvents = True
    End Sub
    
    Sub ClearFilers()
    Dim Ws1 As Worksheet: Set Ws1 = ThisWorkbook.Worksheets("Sheet1")
     Dim Lr As Long: Let Lr = Ws1.Range("B" & Rows.Count & "").End(xlUp).Row
     Let Application.EnableEvents = False
     Ws1.Range("A2:A" & Lr & "").Validation.Delete
     Ws1.Range("A2:A" & Lr & "").ClearContents
     Let Application.EnableEvents = True
     Worksheets("DataSaladinValagationLists").Cells.ClearContents
    End Sub
    A Folk, A Forum, A Fuhrer ….

  3. #123
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10

    Sir Narios ... Positioning of procedure separation in the Visual Basic Development Environment

    Positioning of procedure separation Line in the Visual Basic Development Environment

    These are some notes based on a discussion here.. http://www.eileenslounge.com/viewtopic.php?f=30&t=31756
    Lisa Green had noticed something strange in how VBA divides procedures.....

    It appears that in VBA, that is to say in the Visual Basic Development Environment Window , ( that window seen by hitting Alt+F11 from a spreadsheet ) , the convention has been set to separate procedures by a line extending across the code pane Window.
    We see these as appearing as a series of underscores, __________________ , extending across the Visual Basic Development Environment Window
    Code:
    End Sub  '  The dividing line appears to us as a line of underscores ____ 
    


    Usually, if we did write exactly this ' The dividing line appears to us as a line of underscores ____ ' , on that terminating line above , then we would not see those underscores, ____ , as they get hidden in the terminating line:
    Hidden_____InDividingLine.JPG : https://imgur.com/7DyP9Om
    Attachment 2142
    The above screenshot shows the simplest case of routines with no “space” in between. In that simple case, the position of the dividing line is as expected in between the procedures. The situation is a bit more complicated if there is a separation in between procedures….

    Effect of blank lines ( or ‘commented lines ) In Between
    Between procedures we may add blank lines or ' comment lines. If this is done, it appears that the convention has been set to place the line somewhere between the procedures in this blank/ ‘comment range, and the lines above the line “belong” to the procedure above, that is to say the last or preeceding procedure, and the lines below the line “belong” to the procedure below, that is to say the next procedure, http://www.eileenslounge.com/viewtop...=31756#p245845

    The documentation is not 100% clear on how the position of the dividing is determined , that is to say how the row on which it physically appears as a long series of underscores, __________________ is determined
    There is no obvious logic to the way in which the dividing line can be positioned, that is to say , how to determine on which the dividing line appears as a long series of underscores, __________________

    Some initial experiments suggest that is influenced by positioning of blank lines and any single underscores _

    Line continuation / Break points : single underscores _
    We note in passing , that single underscores are used in coding generally to allow us to divide a single line of code into several lines for ease of reading. For example:
    Code:
    ' http://www.excelfox.com/forum/showthread.php/2293-Move-values-in-rows-at-the-end-of-the-preceding-row-*SOLVED*?p=10891#post10891
    Sub LineContunuationUnderscores() ' https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/program-structure/how-to-break-and-combine-statements-in-code
      Dim LastRow As Long
      LastRow = Cells(Rows.Count, "A").End(xlUp).Row
      
    ' Without line breaks
      Range("A1:A" & LastRow) = Evaluate(Replace(Replace("IF(ISNUMBER(0+SUBSTITUTE(SUBSTITUTE(A2:A#,"" "",""""),"","","""")),IF(LEFT(A1:A@,4)=""2018"",TRIM(A1:A@&"" ""&A2:A#),""""),IF(LEFT(A1:A@,4)=""2018"",A1:A@,""""))", "#", LastRow + 1), "@", LastRow))
      
    ' With Line breaks
      LastRow = _
         Cells(Rows.Count, "A").End(xlUp).Row
      Range("A1:A" & LastRow) = Evaluate(Replace(Replace(  _
                                "IF(ISNUMBER(0+SUBSTITUTE(SUBSTITUTE(" &  _
                                "A2:A#,"" "",""""),"","","""")),IF(LEFT(A1:A@,4)" & _
                                "=""2018"",TRIM(A1:A@&"" ""&A2:A#),"""")," &  _
                                "IF(LEFT(A1:A@,4)=""2018"",A1:A@,""""))", "#", _
                                LastRow + 1), "@", LastRow))
    '  This is _
         acceptable in _
    or out of a  procedure
    End Sub
    '  This is _
         acceptable in _
    or out of a  procedure__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    Further, we note that the line continuation , sometimes called a line break, _ , also applies to comments whether in a procedure or between procedures:
    ' This is _
    acceptable in _
    or out of a procedure


    _._________

    Determining position of horizontal line dividing procedures when blank or comment lines are between procedures
    Sir Narios
    .

    The documentation is not 100% clear on how the position of the dividing is determined , that is to say how the row on which it physically appears as a long series of underscores, __________________ is determined
    There is no obvious logic to the way in which the dividing line can be positioned, that is to say , how to determine on which the dividing line appears as a long series of underscores, __________________
    Some initial experiments suggest that is influenced by positioning of blank lines and any single underscores _
    There appear to be 3 scenarios to consider in order to place the line somewhere in between, ( 4 if you consider the simple case of all lines containing comments or all lines being blank )

    Scenario 0
    ' _(0)
    If all lines are blank, or all lines are full with comments ( which exclude line continuations )
    No single underscores in any line
    The break is immediately after the Last/ upper procedure. (This is the same as the case for no separation between routines )
    Scenario 0 .JPG : https://imgur.com/pA4grFL
    Attachment 2143
    Code:
    Sub Scenario_0()
    ' _(0)
    End Sub___________________________________________________________________________________________________________________________________________________________________________________________________________
    
    
     Sub senario_0()
    ' _(0)
    End Sub_____________________________________________________________________________________________________________________________________________________________________________________________________________________
    '
    '
    '
    Sub surnario_0()
    ' _(0)
    End Sub_____________________________________________________________________________________________________________________________________________________________________________________________________________________________

    Scenario 1
    ' _(i) Attachment 2141 SirNario_1.JPG . https://imgur.com/zmr2up2
    If no line continuations are present and there is a one or more blank lines, then the line before the first blank line down from the upper routine is taken as the break point.
    No single underscores in any line
    Code:
    Sub Senario_1()
    ' _(i)
    End Sub
    '
    '________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    
    Sub surnaria_1()
    ' _(i)
    End Sub
    '____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    
    ''
    
    '
    Sub Sirnario_1()
    ' _(i)
    End Sub_______________________________________________________________________________________________________________________________________________________________________________________________________________
    
    
    '
    '
    Sub snaria_1()
    ' _(i)
    End Sub

    Scenario 2
    ' _(ii) Attachment 2144 SirNario_2.JPG : https://imgur.com/D2LqloV
    If there are one or more line continuations present then the break point will be placed at the first blank line down after the last line after the line continuation … unless scenario (iii)
    Code:
    Sub Scnari_2()
    ' _(ii)
    End Sub
    
    ''
    '
    ' _
    
    '____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    
    '
    
    Sub Sernario_2()
    ' _(ii)
    End Sub
    '
    '
    ' _
    '
    '___________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    
    '
    Sub Sirnarnio_2()
    ' _(ii)
    End Sub
    Scenario 3
    ' _ (iii) Attachment 2146 SirNario_3.JPG : https://imgur.com/ho56uBN
    There are no blank lines after the first line looking down after the last line continuation looking down, or after the first line looking down after the last line continuation looking down all lines contain comments . In this case, the break is at the line after the line on which the line continuation is on.

    Code:
    Sub scenario_3()
    ' _(iii)
    End Sub
    ''
    ' _
    ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    '
    '
    Sub SirNario_3()
    ' _(iii)
    End Sub
    
    '
    ' _
    '____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    '
    '
    Sub snuaro_3()
    ' _(iii)
    End Sub
    '
    
    '
    ' _
    ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    
    
    
    
    
    Sub SirNario_3()
    
    End Sub
    '
    ' _
    '____________________________________________________________________________________________________________________________________________________________________________________________________________________________________
    
    
    
    Sub SurNario_3()
    
    End Sub
    Attached Images Attached Images
    A Folk, A Forum, A Fuhrer ….

  4. #124
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10

    "What’s in a String"- VBA break down Loop through character contents of a string

    Rotines for this excelfox Thread
    http://www.excelfox.com/forum/showth...0943#post10943

    This is part 1 of the coding. The second part is in the next post. The second part must be copied directly under this part in the same code module

    Code:
    Option Explicit           '
    Option Compare Binary     '     https://docs.microsoft.com/de-de/dotnet/visual-basic/language-reference/statements/option-compare-statement
    
    Sub TestWtchaGot()
    ' In the practice we would likely have our string obtained from some method and would have it held in some string variable
    Dim strTest As String   '                             "Pointer" to a "Blue Print" (or Form, Questionnaire not yet filled in, a template etc.)"Pigeon Hole" in Memory, sufficient in construction to house a piece of Paper with code text giving the relevant information for the particular Variable Type. VBA is sent to it when it passes it. In a Routine it may be given a particular “Value”, or (“Values” for Objects). There instructions say then how to do that and handle(store) that(those). At Dim the created Paper is like a Blue Print that has some empty spaces not yet filled in. A String is a bit tricky. The Blue Print code line Paper in the Pigeon Hole will allow to note the string Length and an Initial start memory Location. This Location well have to change frequently as strings of different length are assigned. Instructions will tell how to do this. Theoretically a special value vbNullString is set to aid in quick checks.. But..http://www.mrexcel.com/forum/excel-questions/361246-vbnullstring-2.html#post44116
     Let strTest = Chr(1) & "Hi" & vbCrLf & vbTab & """u."""
     Call WtchaGot(strIn:=strTest)
    ' Call WtchaGot(Chr(1) & "Hi" & vbCrLf & vbTab & """u.""")
    End Sub
    
    Sub WtchaGot(ByVal strIn As String)
    Rem 1  ' Output "sheet hardcopies"
    '1a) Worksheets     'Make a Temporary Sheet, if not already there, in Current Active Workbook, for a simple list of all characters
        If Not Evaluate("=ISREF(" & "'" & "WotchaGotInString" & "'!Z78)") Then '   ( the '  are not important here, but iin general allow for a space in the worksheet name like  "Wotcha Got In String"
        Dim Wb As Workbook '                                   ' ' Dim:  ' Preparing a "Pointer" to an Initial "Blue Print" in Memory of the Object ( Pigeon Hole with a bit of paper or code lines on that can be filled in to refer to a specific Objec of this type ) . This also us to get easily at the Methods and Properties throught the applying of a period ( .Dot) ( intellisense )                     '
         Set Wb = ActiveWorkbook '  '                            Set now (to Active Workbook - one being "looked at"), so that we carefull allways referrence this so as not to go astray through Excel Guessing inplicitly not the one we want...         Set: Values are filled at the memory locations and the directions there are specified in the variable "Blue Print "Pointer". In this case a Filled in Blue Print is passed.      http://www.excelforum.com/excel-programming-vba-macros/1138804-help-understanding-class-instancing-cant-set-ws-new-worksheet-intellisense-offers-it-4.html#post4387191                                '
         Wb.Worksheets.Add After:=Wb.Worksheets.Item(Worksheets.Count) 'A sheeet is added and will be Active
        Dim ws As Worksheet '
         Set ws = ActiveSheet 'Rather than rely on always going to the active sheet, we referr to it Explicitly so that we carefull allways referrence this so as not to go astray through Excel Guessing implicitly not the one we want...    Set: Values are filled at the memory locations and the directions there are specified in the variable "Blue Print "Pointer". In this case a Filled in Blue Print is passed.      http://www.excelforum.com/excel-programming-vba-macros/1138804-help-understanding-class-instancing-cant-set-ws-new-worksheet-intellisense-offers-it-4.html#post4387191            ' Values are filled at the memory locations and the directions there are specified in the variable "Blue Print "Pointer". In this case a Filled in Blue Print is passed.      http://www.excelforum.com/excel-programming-vba-macros/1138804-help-understanding-class-instancing-cant-set-ws-new-worksheet-intellisense-offers-it-4.html#post4387191
         ws.Activate: ws.Cells(1, 1).Activate ' ws.Activate and activating a cell sometimes seemed to overcome a strange error
         Let ws.Name = "WotchaGotInString"
        Else ' The worksheet is already there , so I just need to set my variable to point to it
         Set ws = ThisWorkbook.Worksheets("WotchaGotInString")
        End If
    '1b) Array
    Dim myLenf As Long: Let myLenf = Len(strIn)  '            ' Long is very simple to handle, - final memory "size" type is known (123.456 and 000.001 have same "size" computer memory ) , and so a Address suggestion can be given for the next line when the variable is filled in.  '( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) If you need some sort of validation the value should only be within the range of a Byte/Integer otherwise there's no point using anything but Long.--upon/after 32-bit, Integers (Short) need converted internally anyways, so a Long is actually faster. )       https://www.mrexcel.com/forum/excel-questions/803662-byte-backward-loop-4.html
    Dim arrWotchaGot() As String: ReDim arrWotchaGot(1 To myLenf + 1, 1 To 2) ' +1 for header  Array for the output 2 column list.  The type is known and the size,  but I must use this ReDim  method simply because the dim statement  Dim( , )  is complie time thing and will only take actual numbers
     Let arrWotchaGot(1, 1) = Format(Now, "DD MMM YYYY") & vbLf & "Lenf is   " & myLenf: Let arrWotchaGot(1, 2) = Left(strIn, 20)
    Rem 2  String anylaysis
    'Dim myLenf As Long: Let myLenf = Len(strIn)
    Dim Cnt As Long
        For Cnt = 1 To myLenf ' ===Main Loop========================================================================
        ' Character analysis: Get at each character
        Dim Caracter As Variant ' String is probably OK.
        Let Caracter = Mid(strIn, Cnt, 1) ' '    the character in strIn at position from the left of length 1
        '2a) The character added to a single  WotchaGot  long character string to look at and possibly use in coding
        Dim WotchaGot As String ' This will be used to make a string that I can easilly see and also is in a form that I can copy and paste in a code line  required to build the full string of the complete character string
            '2a)(i) Most common characters and numbers to be displayed as "seen normally" ' -------2a)(i)--
            If Caracter Like "[A-Z]" Or Caracter Like "[0-9]" Or Caracter Like "[a-z]" Then ' Check for normal characters
            Let WotchaGot = WotchaGot & """" & Caracter & """" & " & " ' This will give the sort of output that I need to write in a code line, so for example if I have a123 , this code line will be used 4 times and give like a final string for me to copy of   "a" & "1" & "2" & "3" &      I would phsically need to write in code  like  strVar = "a" & "1" & "2" & "3"   -  i could of course also write  = "a123"   but the point of this routine is to help me pick out each individual element
            Else ' Some other things that I would like to "see" normally - not "normal simple character" - or by a VBA constant, like vbCr vbLf  vbTab
             Select Case Caracter ' 2a)(ii)_1
              Case " "
               Let WotchaGot = WotchaGot & """" & " " & """" & " & "
              Case "!"
               Let WotchaGot = WotchaGot & """" & "!" & """" & " & "
              Case "$"
               Let WotchaGot = WotchaGot & """" & "$" & """" & " & "
              Case "%"
               Let WotchaGot = WotchaGot & """" & "%" & """" & " & "
              Case "~"
               Let WotchaGot = WotchaGot & """" & "~" & """" & " & "
              Case "&"
               Let WotchaGot = WotchaGot & """" & "&" & """" & " & "
              Case "("
               Let WotchaGot = WotchaGot & """" & "(" & """" & " & "
              Case ")"
               Let WotchaGot = WotchaGot & """" & ")" & """" & " & "
              Case "/"
               Let WotchaGot = WotchaGot & """" & "/" & """" & " & "
              Case "\"
               Let WotchaGot = WotchaGot & """" & "\" & """" & " & "
              Case "="
               Let WotchaGot = WotchaGot & """" & "=" & """" & " & "
              Case "?"
               Let WotchaGot = WotchaGot & """" & "?" & """" & " & "
              Case "'"
               Let WotchaGot = WotchaGot & """" & "'" & """" & " & "
              Case "+"
               Let WotchaGot = WotchaGot & """" & "+" & """" & " & "
              Case "-"
               Let WotchaGot = WotchaGot & """" & "-" & """" & " & "
              Case "_"
               Let WotchaGot = WotchaGot & """" & "_" & """" & " & "
              Case "."
               Let WotchaGot = WotchaGot & """" & "." & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    A Folk, A Forum, A Fuhrer ….

  5. #125
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10
    This is the second part of the coding from the last post

    This should be copied and pasted directly under the coding from the last post


    Code:
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '                   ' 2a)(ii)_2
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
    '          Case " "
    '           Let WotchaGot = WotchaGot & """" & " " & """" & " & "
              Case vbCr
               Let WotchaGot = WotchaGot & "vbCr & "  ' I actuall would write manually in this case like     vbCr &
              Case vbLf
               Let WotchaGot = WotchaGot & "vbLf & "
              Case vbCrLf
               Let WotchaGot = WotchaGot & "vbCrLf & "
              Case """"   ' This is how to get a single   "    No one is quite sure how this works.  My theory that,  is as good as any other,  is that  syntaxly   """"    or  "  """  or    """    "   are accepted.   But  in that the  """  bit is somewhat strange for VBA.   It seems to match  the first and Third " together as a  valid pair   but  the other  " in the middle of the  3 "s is also syntax OK, and does not error as    """     would  because  of the final 4th " which it syntaxly sees as a valid pair matched simultaneously as it does some similar check on the  first  and Third    as a concluding  string pair.  All is well except that  the second  "  is captured   within a   accepted  enclosing pair made up of the first and third  "   At the same time the 4th  "  is accepted as a final concluding   "   paired with the   second which it is  using but at the same time now isolated from.
               Let WotchaGot = WotchaGot & """" & """" & """" & """" & " & "                                ' The reason why  ""  ""   would not work is that    at the end of the  "" the next empty  character signalises the end of a  string pair, and only if  it saw a " would it keep checking the syntax rules which  then lead in the previous case to  the situation described above.
              Case vbTab
               Let WotchaGot = WotchaGot & "vbTab & "
              ' 2a)(iii)
                Case Else
                 WotchaGot = WotchaGot & "Chr(" & Asc(Caracter) & ")" & " & "
                'Let CaseElse = Caracter
            End Select
            End If ' End of the "normal simple character" or not ' -------2a)------Ended-----------
        '2b)  A 2 column Array for convenience of a list
         Let arrWotchaGot(Cnt + 1, 1) = Cnt & "           " & Caracter: Let arrWotchaGot(Cnt + 1, 2) = Asc(Caracter) ' +1 for header
        Next Cnt ' ========Main Loop=================================================================================
        If WotchaGot <> "" Then Let WotchaGot = Left(WotchaGot, Len(WotchaGot) - 3) ' take off last " & "    ( 2 spaces one either side of a  & )
    Rem 3 Output
    '3a) String
    MsgBox prompt:=WotchaGot: Debug.Print WotchaGot ' Hit Ctrl+g from the VB Editor to get a copyable version of the entire string
    '3b) List
    Dim NxtClm As Long: Let NxtClm = 1 ' In conjunction with next  If  this prevents the first column beine taken as 0 for an empty worksheet
     If Not ws.Range("A1").Value = "" Then Let NxtClm = ws.Cells.Item(1, Columns.Count).End(xlToLeft).Column + 1
     Let ws.Cells.Item(1, NxtClm).Resize(UBound(arrWotchaGot(), 1), UBound(arrWotchaGot(), 2)).Value = arrWotchaGot()
    End Sub
    '
    A Folk, A Forum, A Fuhrer ….

  6. #126
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10

    Simple Array Bubble Sort Example with Range.Sort Equivalent

    Coding in support of this excelfox Thread:
    llkslksjjsjfaslkjflkajflkjflfjj later sajfsladj


    Code:
    Option Explicit
    
    
    '
    ' Range.Sort Example
    Sub RangeSortExample()
     range("G13:K19").Sort Key1:=range("G13:K19").Columns("B:B"), Order1:=xlAscending, Key2:=range("G13:K19").Columns("D:D"), order2:=xlAscending, MatchCase:=False, Key3:=range("G13:K19").Columns("E:E"), order3:=xlDescending, MatchCase:=False
    End Sub ' Matchcase:=False '
    
    
    
    
    ' Simplist Sort
    Sub SimpleArraySort()
    Rem 0 test data, worksheets info
    Dim WsS As Worksheet: Set WsS = ThisWorkbook.Worksheets("Sorting")
    Dim RngToSort As range: Set RngToSort = WsS.range("A2:B9")
    ' alternative:
    ' Set RngToSort = Selection '                          ' Selection.JPG : https://imgur.com/HnCdBt8
    Dim arrTS() As Variant: Let arrTS() = RngToSort.Value ' We would have to use  .Value  for a range capture of this sort because  .Value  returns a field of Variant types.  But also at this stage we want to preserve string and number types
    Dim arrOut() As Variant: Let arrOut() = arrTS() ' could simply use the original array and sort that
    ' column to be used for determining order of rows sorted array: the values in this column will be looked at
    Dim Clm As Long: Let Clm = 1
    Rem 1 Simple Bubble Sort
    Dim rOuter As Long ' ========"Left Hand"=====================Outer Loop=====================================
        For rOuter = 1 To UBound(arrTS(), 1) - 1 ' For row 1 to the (last row -1)  last row, given by the first dimension upper limit of the array
        Dim rInner As Long ' -------Inner Loop-------------"Right Hand"--------------------------
            For rInner = rOuter + 1 To UBound(arrOut(), 1)
                'If arrOut(rOuter, Clm) > arrOut(rInner, Clm) Then           ' This means that I am bigger than the next. So I will swap . I keep doing this which will have the effect of putting the smallest in the current rOuter. By the this and all next rOuter, I miss out the last, and any previous, which means I effectively do the same which puts the next smallest in this next rOuter.
                If UCase(CStr(arrOut(rOuter, Clm))) > UCase(CStr(arrOut(rInner, Clm))) Then
                Dim Temp As Variant ' I want to Swap those 2 above - I cant easilly in any coding change two values simulataneosly. So one of them Element values will put in this temporary place. This Element Values will then be given the other. Finally the other Element will be given this temporary value
                Dim Clms As Long '-------| with the condition met  a loop is done for all columns in the array in which those two values used in the comparison are replaced at each column
                    For Clms = 1 To UBound(arrOut(), 2)
                     Let Temp = arrOut(rOuter, Clms): Let arrOut(rOuter, Clms) = arrOut(rInner, Clms): Let arrOut(rInner, Clms) = Temp
                    Next Clms '----------| for each column in the array at the two rows rOuter and rInner
                Else
                End If
            Next rInner ' ---------------------------------------------------------------------
        Next rOuter ' ===========================================================================================
    Rem 2 Output for easy of demo
     RngToSort.Offset(0, RngToSort.Columns.Count).Clear                     ' WsS.Columns("C:D").Clear ' CHANGE TO SUIT
     Let RngToSort.Offset(0, RngToSort.Columns.Count).Value = arrOut
     Let RngToSort.Offset(0, RngToSort.Columns.Count).Interior.Color = vbYellow
    End Sub
    ' Approximate equivalent to the above routune, using VBA Range.Sort Method '  https://docs.microsoft.com/de-de/office/vba/api/excel.range.sort
    Sub Range_Sort()
    Rem 0 test data, worksheets info
    Dim WsS As Worksheet: Set WsS = ThisWorkbook.Worksheets("Sorting")
    Dim RngToSort As range: Set RngToSort = WsS.range("A2:B9")
    ' alternative:
    ' Set RngToSort = Selection '                          ' Selection.JPG : https://imgur.com/HnCdBt8
    Rem 1 For demo purposes we will sort a copy of the range
     RngToSort.Offset(0, RngToSort.Columns.Count * 2).Clear                                                ' WsS.Columns("E:F").Clear ' CHANGE TO SUIT
     RngToSort.Copy Destination:=RngToSort.Offset(0, RngToSort.Columns.Count * 2)
     Dim RngCopy As range: Set RngCopy = RngToSort.Offset(0, RngToSort.Columns.Count * 2)
     RngCopy.Sort Key1:=RngCopy.Columns("A:A"), Order1:=xlAscending, MatchCase:=False
    '
     Let RngCopy.Interior.Color = vbGreen
    End Sub
    Typical results:
    The sorted array is displayed in the spreadsheet along side the original range used as test data for the inputted array. ( The yellow highlighted range is that produced by the array sort routine, Sub SimpleArraySort() , and the green highlighted range is that produced by the VBA Range.Sort method routine, Sub Range_Sort()
    More examples in next post.

    _____ ( Using Excel 2007 32 bit )
    Row\Col
    A
    B
    C
    D
    E
    F
    G
    1
    2
    c WasB2 A WasB5 A WasB5
    3
    AB WasB3 Aa WasB4 Aa WasB4
    4
    Aa WasB4 AB WasB3 AB WasB3
    5
    A WasB5 B WasB7 B WasB7
    6
    C WasB6 b WasB8 b WasB8
    7
    B WasB7 bcde WasB9 bcde WasB9
    8
    b WasB8 C WasB6 c WasB2
    9
    bcde WasB9 c WasB2 C WasB6
    10
    Worksheet: Sorting
    A Folk, A Forum, A Fuhrer ….

  7. #127
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10
    Further Examples using the routines from the previous post
    The sorted array is displayed in the spreadsheet along side the original range used as test data for the inputted array. ( The yellow highlighted range is that produced by the array sort routine, Sub SimpleArraySort() , and the green highlighted range is that produced by the VBA Range.Sort method routine, Sub Range_Sort()

    _____ ( Using Excel 2007 32 bit )
    Row\Col
    A
    B
    C
    D
    E
    F
    G
    1
    2
    c WasB2
    32
    WasB8
    6
    WasB7
    3
    AB WasB3
    6
    WasB7
    32
    WasB8
    4
    Aa WasB4 A WasB5 A WasB5
    5
    A WasB5 Aa WasB4 Aa WasB4
    6
    C WasB6 AB WasB3 AB WasB3
    7
    6
    WasB7 bcde WasB9 bcde WasB9
    8
    32
    WasB8 C WasB6 c WasB2
    9
    bcde WasB9 c WasB2 C WasB6
    10
    Worksheet: Sorting

    To reverse this to descending so that things “get smaller as you go down the rows”, you simply need to change
    the > to a < in the array routine
    and
    the Order1:=xlAscending to Order1:=xlDescending in the VBA Range.Sort routine
    _____ ( Using Excel 2007 32 bit )
    Row\Col
    A
    B
    C
    D
    E
    F
    G
    1
    2
    c WasB2 c WasB2 c WasB2
    3
    AB WasB3 C WasB6 C WasB6
    4
    Aa WasB4 bcde WasB9 bcde WasB9
    5
    A WasB5 AB WasB3 AB WasB3
    6
    C WasB6 Aa WasB4 Aa WasB4
    7
    6
    WasB7 A WasB5 A WasB5
    8
    32
    WasB8
    6
    WasB7
    32
    WasB8
    9
    bcde WasB9
    32
    WasB8
    6
    WasB7
    10
    Worksheet: Sorting


    I intended developing the solution into a function, so as a start to this, the routine will be modified to take an Optional argument of 0 or 1 , with the default of 0 being the case for an Ascending list. I am not being particularly efficient with the coding, and will duplicate sections.

    A full routine is posted in the next post
    A Folk, A Forum, A Fuhrer ….

  8. #128
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10

    Simpla Array Bubble Sort Program allowing for Ascending or Descending order

    The last routine, Sub TestieSimpleArraySort(), has a section dupilcated to allow for selection of a final list sorted in Ascending or descending order.
    If supplied 0, or , no GlLl argument is given, then the final list should be sorted in Ascending order


    Code:
    ' Simplist Sort2
    Sub TestieSimpleArraySort2()
     Call SimpleArraySort2(0)
    End Sub
    '
    Sub SimpleArraySort2(Optional ByVal GlLl As Long)
    Rem 0 test data, worksheets info
    Dim WsS As Worksheet: Set WsS = ThisWorkbook.Worksheets("Sorting")
    Dim RngToSort As range: Set RngToSort = WsS.range("A2:B9")
    ' alternative:
    ' Set RngToSort = Selection '                          ' Selection.JPG : https://imgur.com/HnCdBt8
    Dim arrTS() As Variant: Let arrTS() = RngToSort.Value ' We would have to use  .Value  for a range capture of this sort because  .Value  returns a field of Variant types.  But also at this stage we want to preserve string and number types
    Dim arrOut() As Variant: Let arrOut() = arrTS() ' could simply use the original array and sort that
    ' column to be used for determining order of rows sorted array: the values in this column will be looked at
    Dim Clm As Long: Let Clm = 1
    Rem 1 Simple Bubble Sort
    Dim rOuter As Long ' ========"Left Hand"=====================Outer Loop=====================================
        For rOuter = 1 To UBound(arrTS(), 1) - 1 ' For row 1 to the (last row -1)  last row, given by the first dimension upper limit of the array
        Dim rInner As Long ' -------Inner Loop-------------"Right Hand"--------------------------
            For rInner = rOuter + 1 To UBound(arrOut(), 1)
                'If arrOut(rOuter, Clm) > arrOut(rInner, Clm) Then           ' This means that I am bigger than the next. So I will swap . I keep doing this which will have the effect of putting the smallest in the current rOuter. By the this and all next rOuter, I miss out the last, and any previous, which means I effectively do the same which puts the next smallest in this next rOuter.
                If GlLl = 0 Then ' We want Ascending list
                    'If UCase(CStr(arrOut(rOuter, Clm))) > UCase(CStr(arrOut(rInner, Clm))) Then
                    If UCase(CStr(arrOut(rOuter, Clm))) > UCase(CStr(arrOut(rInner, Clm))) Then
                    Dim temp As Variant ' I want to Swap those 2 above - I cant easilly in any coding change two values simulataneosly. So one of them Element values will put in this temporary place. This Element Values will then be given the other. Finally the other Element will be given this temporary value
                    Dim Clms As Long '-------| with the condition met  a loop is done for all columns in the array in which those two values used in the comparison are replaced at each column
                        For Clms = 1 To UBound(arrOut(), 2)
                         Let temp = arrOut(rOuter, Clms): Let arrOut(rOuter, Clms) = arrOut(rInner, Clms): Let arrOut(rInner, Clms) = temp
                        Next Clms '----------| for each column in the array at the two rows rOuter and rInner
                    Else
                    End If
                Else ' GlLl is not 0 , so presumably we want Descending list
                    If UCase(CStr(arrOut(rOuter, Clm))) < UCase(CStr(arrOut(rInner, Clm))) Then
                    'Dim temp As Variant ' I want to Swap those 2 above - I cant easilly in any coding change two values simulataneosly. So one of them Element values will put in this temporary place. This Element Values will then be given the other. Finally the other Element will be given this temporary value
                    'Dim Clms As Long '-------| with the condition met  a loop is done for all columns in the array in which those two values used in the comparison are replaced at each column
                        For Clms = 1 To UBound(arrOut(), 2)
                         Let temp = arrOut(rOuter, Clms): Let arrOut(rOuter, Clms) = arrOut(rInner, Clms): Let arrOut(rInner, Clms) = temp
                        Next Clms '----------| for each column in the array at the two rows rOuter and rInner
                    Else
                    End If
                End If ' End of Ascending or Descending example
            Next rInner ' ---------------------------------------------------------------------
        Next rOuter ' ===========================================================================================
    Rem 2 Output for easy of demo
     RngToSort.Offset(0, RngToSort.Columns.Count).Clear                     ' WsS.Columns("C:D").Clear ' CHANGE TO SUIT
     Let RngToSort.Offset(0, RngToSort.Columns.Count).Value = arrOut()
     Let RngToSort.Offset(0, RngToSort.Columns.Count).Interior.Color = vbYellow
    End Sub


    Results for this callind procedure
    Code:
    Sub TestieSimpleArraySort2()
     Call SimpleArraySort2(0)
     Call SimpleArraySort
    End Sub
    '
    _____ ( Using Excel 2007 32 bit )
    Row\Col
    A
    B
    C
    D
    2
    c WasB2
    32
    WasB8
    3
    AB WasB3
    6
    WasB7
    4
    Aa WasB4 A WasB5
    5
    A WasB5 Aa WasB4
    6
    C WasB6 AB WasB3
    7
    6
    WasB7 bcde WasB9
    8
    32
    WasB8 C WasB6
    9
    bcde WasB9 c WasB2
    Worksheet: Sorting



    Results for this calling procedure
    Code:
    Sub TestieSimpleArraySort2()
     Call SimpleArraySort2(732847)
    End Sub
    '
    _____ ( Using Excel 2007 32 bit )
    Row\Col
    A
    B
    C
    D
    2
    c WasB2 c WasB2
    3
    AB WasB3 C WasB6
    4
    Aa WasB4 bcde WasB9
    5
    A WasB5 AB WasB3
    6
    C WasB6 Aa WasB4
    7
    6
    WasB7 A WasB5
    8
    32
    WasB8
    6
    WasB7
    9
    bcde WasB9
    32
    WasB8
    Worksheet: Sorting
    A Folk, A Forum, A Fuhrer ….

  9. #129
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10

    Simple Array Bubble Sort Example working similar to VBA Range.Sort with one Key1:=

    A further modification is done to the previous routines so that values that can be seen as numbers are compared as numbers in sorting. This is done so that, for example, a number like 46 would be seen as greater than 7. In previous routines, these would be compared as text values of "46" and "7". In a text comparison, the sort is done initially on the first character so that "4" would be seen as less that "7". ( The second character, "6", in this exampple is not used. A second character would only be used to sort if we had two values such as "46" and "49". In such an example VBA would place "49" above "46" for a text comparison

    We find that the VBA Range.Sort Method sees text as text and numbers typically as numbers , and the final purpose of the routines we are developing in the associated main forum Thread is to do somethhing similar to the VBA Range.Sort Method

    Code:
    '
    ' Simplist Sort3
    Sub TestieSimpleArraySort3()
     Call SimpleArraySort3(0)
    End Sub
    '
    Sub SimpleArraySort3(Optional ByVal GlLl As Long)
    Rem 0 test data, worksheets info
    Dim WsS As Worksheet: Set WsS = ThisWorkbook.Worksheets("Sorting")
    Dim RngToSort As range: Set RngToSort = WsS.range("A2:B9")
    ' alternative:
    ' Set RngToSort = Selection '                          ' Selection.JPG : https://imgur.com/HnCdBt8
    Dim arrTS() As Variant: Let arrTS() = RngToSort.Value ' We would have to use  .Value  for a range capture of this sort because  .Value  returns a field of Variant types.  But also at this stage we want to preserve string and number types
    Dim arrOut() As Variant: Let arrOut() = arrTS() ' could simply use the original array and sort that
    ' column to be used for determining order of rows sorted array: the values in this column will be looked at
    Dim Clm As Long: Let Clm = 1
    Rem 1 Simple Bubble Sort
    Dim rOuter As Long ' ========"Left Hand"=====================Outer Loop=====================================
        For rOuter = 1 To UBound(arrTS(), 1) - 1 ' For row 1 to the (last row -1)  last row, given by the first dimension upper limit of the array
        Dim rInner As Long ' -------Inner Loop-------------"Right Hand"--------------------------
            For rInner = rOuter + 1 To UBound(arrOut(), 1)
                'If arrOut(rOuter, Clm) > arrOut(rInner, Clm) Then           ' This means that I am bigger than the next. So I will swap . I keep doing this which will have the effect of putting the smallest in the current rOuter. By the this and all next rOuter, I miss out the last, and any previous, which means I effectively do the same which puts the next smallest in this next rOuter.
                If GlLl = 0 Then ' We want Ascending list
                    If IsNumeric(arrOut(rOuter, Clm)) And IsNumeric(arrOut(rInner, Clm)) Then ' Numeric case
                        'If UCase(CStr(arrOut(rOuter, Clm))) > UCase(CStr(arrOut(rInner, Clm))) Then
                        'If arrOut(rOuter, Clm) > arrOut(rInner, Clm) Then' If both values are seen to be numeric then this line would probably work, but as "belt and braces" we do the next
                        If CDbl(arrOut(rOuter, Clm)) > CDbl(arrOut(rInner, Clm)) Then
                        Dim temp As Variant ' I want to Swap those 2 above - I cant easilly in any coding change two values simulataneosly. So one of them Element values will put in this temporary place. This Element Values will then be given the other. Finally the other Element will be given this temporary value
                        Dim Clms As Long '-------| with the condition met  a loop is done for all columns in the array in which those two values used in the comparison are replaced at each column
                            For Clms = 1 To UBound(arrOut(), 2)
                             Let temp = arrOut(rOuter, Clms): Let arrOut(rOuter, Clms) = arrOut(rInner, Clms): Let arrOut(rInner, Clms) = temp
                            Next Clms '----------| for each column in the array at the two rows rOuter and rInner
                        Else
                        End If
                     Else ' Non numeric case
                        'If UCase(CStr(arrOut(rOuter, Clm))) > UCase(CStr(arrOut(rInner, Clm))) Then
                        If UCase(CStr(arrOut(rOuter, Clm))) > UCase(CStr(arrOut(rInner, Clm))) Then
                        'Dim temp As Variant ' I want to Swap those 2 above - I cant easilly in any coding change two values simulataneosly. So one of them Element values will put in this temporary place. This Element Values will then be given the other. Finally the other Element will be given this temporary value
                        'Dim Clms As Long '-------| with the condition met  a loop is done for all columns in the array in which those two values used in the comparison are replaced at each column
                            For Clms = 1 To UBound(arrOut(), 2)
                             Let temp = arrOut(rOuter, Clms): Let arrOut(rOuter, Clms) = arrOut(rInner, Clms): Let arrOut(rInner, Clms) = temp
                            Next Clms '----------| for each column in the array at the two rows rOuter and rInner
                        Else
                        End If
                    End If ' End of numeric or text comparison
                Else ' GlLl is not 0 , so presumably we want Descending list
                    If IsNumeric(arrOut(rOuter, Clm)) And IsNumeric(arrOut(rInner, Clm)) Then
                        If CDbl(arrOut(rOuter, Clm)) < CDbl(arrOut(rInner, Clm)) Then
                        'Dim temp As Variant ' I want to Swap those 2 above - I cant easilly in any coding change two values simulataneosly. So one of them Element values will put in this temporary place. This Element Values will then be given the other. Finally the other Element will be given this temporary value
                        'Dim Clms As Long '-------| with the condition met  a loop is done for all columns in the array in which those two values used in the comparison are replaced at each column
                            For Clms = 1 To UBound(arrOut(), 2)
                             Let temp = arrOut(rOuter, Clms): Let arrOut(rOuter, Clms) = arrOut(rInner, Clms): Let arrOut(rInner, Clms) = temp
                            Next Clms '----------| for each column in the array at the two rows rOuter and rInner
                        Else
                        End If
                    Else ' non numeric case
                        If UCase(CStr(arrOut(rOuter, Clm))) < UCase(CStr(arrOut(rInner, Clm))) Then
                        'Dim temp As Variant ' I want to Swap those 2 above - I cant easilly in any coding change two values simulataneosly. So one of them Element values will put in this temporary place. This Element Values will then be given the other. Finally the other Element will be given this temporary value
                        'Dim Clms As Long '-------| with the condition met  a loop is done for all columns in the array in which those two values used in the comparison are replaced at each column
                            For Clms = 1 To UBound(arrOut(), 2)
                             Let temp = arrOut(rOuter, Clms): Let arrOut(rOuter, Clms) = arrOut(rInner, Clms): Let arrOut(rInner, Clms) = temp
                            Next Clms '----------| for each column in the array at the two rows rOuter and rInner
                        Else
                        End If
                    End If ' End of numeric or text comparison
                End If ' End of Ascending or Descending example
            Next rInner ' ---------------------------------------------------------------------
        Next rOuter ' ===========================================================================================
    Rem 2 Output for easy of demo
     RngToSort.Offset(0, RngToSort.Columns.Count).Clear                     ' WsS.Columns("C:D").Clear ' CHANGE TO SUIT
     Let RngToSort.Offset(0, RngToSort.Columns.Count).Value = arrOut()
     Let RngToSort.Offset(0, RngToSort.Columns.Count).Interior.Color = vbYellow
    End Sub
    Final comparison results are shown in the next post
    A Folk, A Forum, A Fuhrer ….

  10. #130
    Fuhrer, Vierte Reich DocAElstein's Avatar
    Join Date
    Aug 2014
    Posts
    9,459
    Rep Power
    10
    The sorted array is displayed in the spreadsheet along side the original range used as test data for the inputted array. ( The yellow highlighted range is that produced by the array sort routine, Sub SimpleArraySort3() , and the green highlighted range is that produced by the VBA Range.Sort method routine, Sub Range_Sort()


    Ascending Order
    Code:
    Sub TestieSimpleArraySort3()
     Call SimpleArraySort3(0)
    End Sub
    '
    Code:
    Sub Range_Sort()
    Rem 0 test data, worksheets info
    Dim WsS As Worksheet: Set WsS = ThisWorkbook.Worksheets("Sorting")
    Dim RngToSort As range: Set RngToSort = WsS.range("A2:B9")
    ' alternative:
    ' Set RngToSort = Selection '                          ' Selection.JPG : https://imgur.com/HnCdBt8
    Rem 1 For demo purposes we will sort a copy of the range
     RngToSort.Offset(0, RngToSort.Columns.Count * 2).Clear                                                ' WsS.Columns("E:F").Clear ' CHANGE TO SUIT
     RngToSort.Copy Destination:=RngToSort.Offset(0, RngToSort.Columns.Count * 2)
     Dim RngCopy As range: Set RngCopy = RngToSort.Offset(0, RngToSort.Columns.Count * 2)
     RngCopy.Sort Key1:=RngCopy.Columns("A:A"), Order1:=xlAscending, MatchCase:=False
     'RngCopy.Sort Key1:=RngCopy.Columns("A:A"), Order1:=xlDescending, MatchCase:=False
     Let RngCopy.Interior.Color = vbGreen
    End Sub
    _____ ( Using Excel 2007 32 bit )
    Row\Col
    A
    B
    C
    D
    E
    F
    G
    1
    2
    c WasB2
    6
    WasB7
    6
    WasB7
    3
    AB WasB3
    32
    WasB8
    32
    WasB8
    4
    Aa WasB4 A WasB5 A WasB5
    5
    A WasB5 Aa WasB4 Aa WasB4
    6
    C WasB6 AB WasB3 AB WasB3
    7
    6
    WasB7 bcde WasB9 bcde WasB9
    8
    32
    WasB8 C WasB6 c WasB2
    9
    bcde WasB9 c WasB2 C WasB6
    10
    Worksheet: Sorting



    Descending Order
    Code:
    Sub TestieSimpleArraySort3()
     Call SimpleArraySort3(2246)
    End Sub
    '
    Code:
    Sub Range_Sort()
    Rem 0 test data, worksheets info
    Dim WsS As Worksheet: Set WsS = ThisWorkbook.Worksheets("Sorting")
    Dim RngToSort As range: Set RngToSort = WsS.range("A2:B9")
    ' alternative:
    ' Set RngToSort = Selection '                          ' Selection.JPG : https://imgur.com/HnCdBt8
    Rem 1 For demo purposes we will sort a copy of the range
     RngToSort.Offset(0, RngToSort.Columns.Count * 2).Clear                                                ' WsS.Columns("E:F").Clear ' CHANGE TO SUIT
     RngToSort.Copy Destination:=RngToSort.Offset(0, RngToSort.Columns.Count * 2)
     Dim RngCopy As range: Set RngCopy = RngToSort.Offset(0, RngToSort.Columns.Count * 2)
     'RngCopy.Sort Key1:=RngCopy.Columns("A:A"), Order1:=xlAscending, MatchCase:=False
     RngCopy.Sort Key1:=RngCopy.Columns("A:A"), Order1:=xlDescending, MatchCase:=False
     Let RngCopy.Interior.Color = vbGreen
    End Sub
    _____ ( Using Excel 2007 32 bit )
    Row\Col
    A
    B
    C
    D
    E
    F
    G
    1
    2
    c WasB2 c WasB2 c WasB2
    3
    AB WasB3 C WasB6 C WasB6
    4
    Aa WasB4 bcde WasB9 bcde WasB9
    5
    A WasB5 AB WasB3 AB WasB3
    6
    C WasB6 Aa WasB4 Aa WasB4
    7
    6
    WasB7 A WasB5 A WasB5
    8
    32
    WasB8
    32
    WasB8
    32
    WasB8
    9
    bcde WasB9
    6
    WasB7
    6
    WasB7
    10
    Worksheet: Sorting
    A Folk, A Forum, A Fuhrer ….

Similar Threads

  1. Replies: 185
    Last Post: 05-22-2024, 10:02 PM
  2. Replies: 293
    Last Post: 09-24-2020, 01:53 AM
  3. Appendix Thread. Diet Protokol Coding Adaptions
    By DocAElstein in forum Test Area
    Replies: 6
    Last Post: 09-05-2019, 10:45 AM
  4. Restrict data within the Cell (Data Validation)
    By dritan0478 in forum Excel Help
    Replies: 1
    Last Post: 07-27-2017, 09:03 PM

Posting Permissions

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