EDIT: Query is called from vba, used to create array, passed to create form:
QueryFieldAsSeparatedString("Batch", "TLR", "Batch")
strBndls = Replace(strBndls, ",", ";")
subNewControls strBndls, "frmSelectBundle"
The reason I thought this quicksort would work is because batch #13 gets lumped in with the 1's using the sortby clause.
Example table:
desired string returned: 1, 1a, 1b, 2, 2a, 3, 6, 6a, 7, 7a, 7b, 8, 9, 11, 13, 13a
Current Output Side Note: there are duplicates in this table that have different information separating them (shipment_box# and product_size). I'm hoping to group them since the operator would be entering data against the whole batch on the same order and child batch (batches with a letter), regardless of other data
Original Post:
I am attempting to sort a column in an access table. I found this code from VBA array sort function? and am attempting to make it work. I would have commented on the post but am unable to comment since I am new to the forum.
Specifically I am looking at this bit of code:
Public Sub QuickSort(ByRef Field() As String, ByVal LB As Long, ByVal UB As Long)
Dim P1 As Long, P2 As Long, Ref As String, TEMP As String
P1 = LB
P2 = UB
Ref = Field((P1 + P2) / 2)
Do
Do While (Field(P1) < Ref)
P1 = P1 + 1
Loop
Do While (Field(P2) > Ref)
P2 = P2 - 1
Loop
If P1 <= P2 Then
TEMP = Field(P1)
Field(P1) = Field(P2)
Field(P2) = TEMP
P1 = P1 + 1
P2 = P2 - 1
End If
Loop Until (P1 > P2)
If LB < P2 Then Call QuickSort(Field, LB, P2)
If P1 < UB Then Call QuickSort(Field, P1, UB)
End Sub
I use this block of code to create a delimited string of all records in a 'Product Batch' field.
Public Function QueryFieldAsSeparatedString(ByVal fieldName As String, _
ByVal tableOrQueryName As String, _
Optional ByVal criteria As String = "", _
Optional ByVal sortBy As String = "", _
Optional ByVal delimiter As String = ", " _
) As String
' Paramter description
' fieldName = Is the name of the field containing the values
' we want in our comma separated string
' tableOrQueryName = Is the name of table or query containing the column
' criteria = The criteria to filter the data
' sortBy = An optional sort expression to sort the data
' delimiter = The delimiter used to separate the values. It defaults
' to a comma and a blank, but you can use anything you
' like there
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim sql As String
Dim whereCondition As String
Dim sortExpression As String
Dim retVal As String
Set db = CurrentDb
' If there where any criteria passed to the function, we build a WHERE-condition for SQL
If Len(criteria) > 0 Then
whereCondition = " WHERE " & criteria
End If
' If there was a sort expression passed to the function, we build a ORDER BY for SQL
If Len(sortBy) > 0 Then
sortExpression = " ORDER BY " & sortBy
End If
' building the complete SQL string
sql = "SELECT " & fieldName & " FROM " & tableOrQueryName & whereCondition & sortExpression &
";"
' opening a recordset
Set rs = db.OpenRecordset(sql, dbOpenForwardOnly, dbReadOnly)
Do Until rs.EOF
' here we are looping through the records and, if the value is not NULL,
' concatenate the field value of each record with the delimiter
If Not IsNull(rs.Fields(0).Value) Then
retVal = retVal & Nz(rs.Fields(0).Value, "") & delimiter
End If
rs.MoveNext
Loop
' we cut away the last delimiter
retVal = Left(retVal, Len(retVal) - Len(delimiter))
' setting the return value of the function
QueryFieldAsSeparatedString = retVal
' cleaning up our objects
rs.Close
Set rs = Nothing
Set db = Nothing
End Function
This list is put into an array and used to dynamically create a batch number selection form, where each item in the list becomes a checkbox with the batch as a label. So an operator can choose which batch(es) have been worked on that day.
What my challenge/question is how would I go about sorting the batch string? The format is: 1, 1a, 2, 2a, 2b, ...
but comes in, in the order it is in the table. So it looks like 2a, 1, 2b, 1a, 1b, 2, ...
I'm going between the quicksort and figuring out a way to order/group the table before the string is even created, which may be in the second block of code; just not used properly.
The end goal would be to create another array consisting of the selected batches to continue data entry.
Any thoughts or questions are greatly appreciated!
elaborating on the comments. First use regular expressions to split batch into batch# and batchletters. https://medium.com/factory-mind/regex-tutorial-a-simple-cheatsheet-by-examples-649dc1c3f285 https://software-solutions-online.com/vba-regex-guide/
Public Function RegexMatch(value As String, pattern As String) As String
'this code depends on adding a reference microsoft vbscript regular expressions 5.5 (in code window go tools-references)
Dim result As String
If IsNull(value) Then Exit Function
Dim regex As RegExp
' Initialise the Regex object '
Set regex = New RegExp
With regex
.Global = True
.IgnoreCase = False
.MultiLine = True
.pattern = pattern
End With
' Test the value against the pattern '
Set Matches = regex.Execute(value)
If Matches.Count > 0 Then
result = Matches.Item(0)
End If
RegexMatch = result
End Function
Batch#: RegexMatch([Batch],"(\d+)")
BatchLetters: RegexMatch([Batch],"(\D+)")
Then create a query selecting everything and adding Batch# and BatchLetters. arrange variables in order you want to sort. I chose Shipment_Box, Product_Size, Batch#, BatchLetters
Thats it. I saw no need to concatenate batch into a string as you can set the rowsource of a combobox or listbox directly to the query.