【问题标题】:Sort Alphanumeric Array Access-VBA排序字母数字数组访问-VBA
【发布时间】:2022-01-28 03:45:36
【问题描述】:

编辑:从 vba 调用查询,用于创建数组,传递给创建表单:

QueryFieldAsSeparatedString("Batch", "TLR", "Batch")  
strBndls = Replace(strBndls, ",", ";")
subNewControls strBndls, "frmSelectBundle"

我认为这种快速排序会起作用的原因是因为第 13 批使用 sortby 子句与 1 混为一谈。

示例表:

  • 订单号 |批量
  • 1 | 1
  • 1 | 13
  • 1 | 1b
  • 1 | 2
  • 1 | 2a
  • 1 | 1a
  • 1 | 3
  • 1 | 6
  • 1 | 7
  • 1 | 9
  • 1 | 11
  • 1 | 6a
  • 1 | 7b
  • 1 | 8
  • 1 | 13a
  • 1 | 7a

返回的所需字符串:1、1a、1b、2、2a、3、6、6a、7、7a、7b、8、9、11、13、13a

Current Output 旁注:此表中有重复项,它们具有不同的信息(shipment_box# 和 product_size)。我希望将它们分组,因为操作员将在同一订单和子批次(带有字母的批次)上针对整个批次输入数据,而不管其他数据如何

原帖:

我正在尝试对访问表中的列进行排序。我从VBA array sort function? 找到了这段代码,并试图让它工作。我本来想对帖子发表评论,但由于我是论坛的新手,所以无法发表评论。

具体来说我在看这段代码:

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

我使用此代码块在“产品批次”字段中创建所有记录的分隔字符串。

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

这个列表被放入一个数组中,用于动态创建一个批号选择表单,其中列表中的每一项都变成了一个以批次为标签的复选框。因此操作员可以选择当天工作的批次。

我的挑战/问题是如何对批处理字符串进行排序? 格式为: 1, 1a, 2, 2a, 2b, ...

但是按照表格中的顺序进入。所以看起来像 2a, 1, 2b, 1a, 1b, 2, ...

我正在快速排序和找出一种在创建字符串之前对表进行排序/分组的方法之间进行切换,这可能在第二个代码块中;只是没有正确使用。

最终目标是创建另一个包含所选批次的数组以继续数据输入。

非常感谢任何想法或问题!

【问题讨论】:

  • 当使用 sortBy 参数调用 QueryFieldAsSeparatedString 时,它不会以正确的顺序对其进行排序吗?为什么你需要一个单独的排序例程(如 QuickSort),数据库会为你做这一切。
  • 调用 QueryFieldAsSeparatedString 的代码在哪里?查询或文本框中的表达式?展示下。提供示例数据作为文本表。数字部分会走多高? 13a 将在 2a 之前排序。编辑问题。
  • 我编辑了添加信息的帖子。此外,数字将高达 30 年代中期,字母将高达 e。感谢您的快速回复!
  • 嗯,这是 alpha 排序,因此要么将值拆分为数字和 alpha 部分并按这些部分排序,要么使用占位符 0 构建值:002a 将在 017a 之前排序。
  • 有没有办法隐藏前导0?如果这是唯一的路线,我宁愿不看到...

标签: vba ms-access quicksort


【解决方案1】:

详细阐述 cmets。首先使用正则表达式将批次拆分为批次#和批次字母。 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+)")

然后创建一个查询,选择所有内容并添加 Batch# 和 BatchLetters。按您想要排序的顺序排列变量。我选择了 Shipment_Box、Product_Size、Batch#、BatchLetters

就是这样。我认为无需将批处理连接成字符串,因为您可以将组合框或列表框的行源直接设置为查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2023-03-26
    • 1970-01-01
    • 2021-05-03
    相关资源
    最近更新 更多