Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

Visual Basic for Applications/Bubble Sort on Multiple Keys

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

Summary Array Sort on Three Keys This rather long VBA code listing allows bubble sorting of an array on three keys. It is sometimes called an intersort. In case it is not clear what that means, suppose there are many names to sort; each with two forenames and a surname. The names records occupy a row each and their parts are in separate columns. The first key might sort the surnames column, but there could be many records called Smith. Then the second key sorts among the first forenames where the surnames were similar. And there might still be a lot of John Smith name records that are the same. The third key sorts the second forename column for those cases where there are records with the same surname and first forename combination. A similar function can be found on Excel worksheets in the advanced sort functions. Users unfamiliar with this sort type might well experiment there to better understand the process. The function here has options for ascending or descending sorts, row sort or column sort, and the option to return the sorted work in another array or the original. Up to three keys can be specified, though if there are unused keys, say, because only two intersorts are needed, it is assumed that Key1 and Key2 will be used before Key3. In any case, unreasonable settings will result in message box advice. Function SortArr2D3Keys(vA As Variant, _ Optional Key1 As Long = -1, _ Optional Key2 As Long = -1, _ Optional Key3 As Long = -1, _ Optional ByVal bIsAscending As Boolean = True, _ Optional ByVal bIsRowSort As Boolean = True, _ Optional ByRef vR As Variant) As Boolean '-------------------------------------------------------------------------------------- ' Procedure : SortArr2D3Keys ' Purpose : Bubblesorts a 2D array using 3 keys, up or down, on any column or row. ' For example, sorting using up to three columns; ' Eg; first sorts surnames, then sorts among same surnames for first names, ' then among similar surnames with same first names for middle names. ' Options include in-place, with the source changed, or ' if supplied, returned in vR, with the source array intact. ' Optional parameters default to: ROW SORT, ASCENDING. ' Trailing key options that are not needed should be set to same as previous. '--------------------------------------------------------------------------------------- ASSIGNMENTS: Dim condition1 As Boolean, vW As Variant, Temp Dim i As Long, j As Long, y As Long, t As Variant Dim loR As Long, hiR As Long, loC As Long, hiC As Long Dim r As Long, c As Long, bWasMissing As Boolean Dim sCombo As String, reply Dim b1Used As Boolean, b2Used As Boolean, b3Used As Boolean 'find bounds of vA data input array loR = LBound(vA, 1): hiR = UBound(vA, 1) loC = LBound(vA, 2): hiC = UBound(vA, 2) 'find whether optional vR was initially missing bWasMissing = IsMissing(vR) If Not bWasMissing Then Set vR = Nothing KEYCHECKS: If Key1 <> -1 Then b1Used = True 'check key within bounds If bIsRowSort And (Key1 < loC Or Key1 > hiC) Then MsgBox "Sort key1 out of bounds" Exit Function End If If Not bIsRowSort And (Key1 < loR Or Key1 > hiR) Then MsgBox "Sort key1 out of bounds" Exit Function End If End If If Key2 <> -1 Then b2Used = True 'check key within bounds If bIsRowSort And (Key2 < loC Or Key2 > hiC) Then MsgBox "Sort key2 out of bounds" Exit Function End If If Not bIsRowSort And (Key2 < loR Or Key2 > hiR) Then MsgBox "Sort key2 out of bounds" Exit Function End If End If If Key3 <> -1 Then b3Used = True 'check key within bounds If bIsRowSort And (Key3 < loC Or Key3 > hiC) Then MsgBox "Sort key3 out of bounds" Exit Function End If If Not bIsRowSort And (Key3 < loR Or Key3 > hiR) Then MsgBox "Sort key3 out of bounds" Exit Function End If End If sCombo = CStr(Abs(b1Used)) & CStr(Abs(b2Used)) & CStr(Abs(b3Used)) 'MsgBox sCombo Select Case sCombo Case "000" 'no keys selected If bIsRowSort Then reply = MsgBox("No keys selected." & vbCrLf & _ "Use lower bound column for a single key?", vbCritical + vbQuestion + vbYesNo, "Please confirm your selection...") Select Case reply Case vbYes Key1 = loC Case Else Exit Function End Select Else reply = MsgBox("No keys selected." & vbCrLf & _ "Use lower bound row for a single key?", vbCritical + vbQuestion + vbYesNo, "Please confirm your selection...") Select Case reply Case vbYes Key1 = loR Case Else Exit Function End Select End If Case "100", "110", "111" 'proceed normally Case Else MsgBox "Only three combinations of sort keys are possible" & vbCrLf & _ "Key1 alone, Key1 with Key2, or Key1 with Key2 and Key3." Exit Function End Select WORKARRAY: 'use a working array for sorting vW = vA STEERING: 'steer input options If bIsRowSort Then GoTo ROWSORT Else GoTo COLSORT ROWSORT: 'row sort using 3 intersort keys 'Sort rows of array using first column index, Key1 For i = loR To hiR - 1 For j = i + 1 To hiR 'set < for descending, and > for ascending If bIsAscending Then condition1 = vW(i, Key1) > vW(j, Key1) Else condition1 = vW(i, Key1) < vW(j, Key1) End If If condition1 Then For c = loC To hiC Temp = vW(i, c) vW(i, c) = vW(j, c) vW(j, c) = Temp Next End If Next Next If b2Used Then 'Sort rows of array using second column index, Key2 For i = loR To hiR - 1 For j = i + 1 To hiR 'if-condition avoids independence of second sort 'note that a third stage would have THREE terms If vW(i, Key1) = vW(j, Key1) Then 'set < for descending, and > for ascending If bIsAscending Then condition1 = vW(i, Key2) > vW(j, Key2) Else condition1 = vW(i, Key2) < vW(j, Key2) End If If condition1 Then For c = loC To hiC Temp = vW(i, c) vW(i, c) = vW(j, c) vW(j, c) = Temp Next End If End If Next Next Else GoTo TRANSFERS End If If b3Used Then 'Sort rows of array using third column index, Key3 For i = loR To hiR - 1 For j = i + 1 To hiR 'if-condition avoids independence of second sort 'note that a third stage would have THREE terms If vW(i, Key1) = vW(j, Key1) And vW(i, Key2) = vW(j, Key2) Then 'set < for descending, and > for ascending If bIsAscending Then condition1 = vW(i, Key3) > vW(j, Key3) Else condition1 = vW(i, Key3) < vW(j, Key3) End If If condition1 Then For c = loC To hiC Temp = vW(i, c) vW(i, c) = vW(j, c) vW(j, c) = Temp Next End If End If Next Next End If GoTo TRANSFERS COLSORT: 'column sort using 3 intersort keys 'Sort columns of array using first row index, Key1 For i = loC To hiC - 1 For j = i + 1 To hiC 'set < for descending, and > for ascending If bIsAscending Then condition1 = vW(Key1, i) > vW(Key1, j) Else condition1 = vW(Key1, i) < vW(Key1, j) End If If condition1 Then For c = loR To hiR Temp = vW(c, i) vW(c, i) = vW(c, j) vW(c, j) = Temp Next End If Next Next If b2Used Then 'Sort columns of array using second row index, Key2 For i = loC To hiC - 1 For j = i + 1 To hiC 'if-condition avoids independence of second sort 'note that a third stage would have THREE terms If vW(Key1, i) = vW(Key1, j) Then 'set < for descending, and > for ascending If bIsAscending Then condition1 = vW(Key2, i) > vW(Key2, j) Else condition1 = vW(Key2, i) < vW(Key2, j) End If If condition1 Then For c = loR To hiR Temp = vW(c, i) vW(c, i) = vW(c, j) vW(c, j) = Temp Next End If End If Next Next Else GoTo TRANSFERS End If If b3Used Then 'Sort columns of array using third row index, Key2 For i = loC To hiC - 1 For j = i + 1 To hiC 'if-condition avoids independence of second sort 'note that a third stage would have THREE terms If vW(Key1, i) = vW(Key1, j) And vW(Key2, i) = vW(Key2, j) Then 'set < for descending, and > for ascending If bIsAscending Then condition1 = vW(Key3, i) > vW(Key3, j) Else condition1 = vW(Key3, i) < vW(Key3, j) End If If condition1 Then For c = loR To hiR Temp = vW(c, i) vW(c, i) = vW(c, j) vW(c, j) = Temp Next End If End If Next Next End If GoTo TRANSFERS TRANSFERS: 'decide whether to return in vA or vR If Not bWasMissing Then 'vR was the intended return array 'so return vR leaving vA intact vR = vW Else: 'vR is not intended 'so reload vA with vR vA = vW End If 'set return function value SortArr2D3Keys = True End Function