【问题标题】:Automate Listbox Selection自动选择列表框
【发布时间】:2014-03-05 18:50:36
【问题描述】:

我有一个列表框,我希望它能够自动化,这样当我输入一个项目的总数量时,它会多选行,直到达到该总数。在 MS Access 的范围内,我想做什么?我一直在寻找和寻找,似乎找不到任何东西可以告诉我从哪里开始。

' Spin through the Array adding up rows to fulfill the needed quantity, following will search and possibly use part of a BIN
    If ListArray(i, 1) <> "" And ListArray(i, 1) <= iQty Then           ' skip empty array; check if less than qty
        While index <= Me.lstShipping.ListCount
            lstShipping(ListArray(i, 0)) = True                         ' select this row in ListBox
            iSelected = iSelected + ListArray(i, 1)                     ' track total qty selected
                If iSelected = iQty Then                                ' if enough is selected, end
                    Exit While
                End If
        index += 1
        End While

【问题讨论】:

  • 我不明白。要开始的列表框中有什么?输入的总数在哪里?之后的列表框是什么样子的?
  • 列表框包含仓库中存储容器 (BINS) 的列表。这些 BINS 中的每一个都包含一个特定产品的编号,并且每个产品都有一个批号。我有一个查询来提取它并将其填充到表单上的列表框中。可以有许多包含相同批号的 BINS,所以我想要做的是当我运送某个批号时,它会抓取我从主表单输入的总数并选择相应的批次,直到它足以等于总数.我可以过滤列表框,但不能过滤它。这样就清楚了吗?
  • 是的,我相当肯定在 VBA 中你可以做到这一点。为清楚起见,假设您的列表框有 5 个项目,其值分别为 1、2、3、4、5。如果您总共输入 6 个,您希望选择前 3 个项目。但是如果你输入 7 会发生什么?您要选择项目 3 和 4 吗?
  • @WayneG.Dunn... 理想情况下,我想使用 1、2 和 4,这样我就可以清空尽可能多的 BINS 并将它们腾出来用于其他货物;但我现在并不挑剔,可以在设置可行的解决方案后对其进行调整。
  • 我修改了代码,使其从最小数量的第一个开始。根据箱的数量、箱中的数量、所需的数量,您可能会收到一条消息,因为它太复杂了。试一试,看看这个新代码是否接近你需要的......

标签: vba ms-access listbox multi-select


【解决方案1】:

已更新以添加缺少的功能... 以下代码将在您的列表框中旋转,寻找匹配的“批号”并选择可提供所需数量的行。列表框数量被放置到一个数组中,然后进行排序,以便首先使用最小数量来释放大多数垃圾箱。我懒得让代码取消选择多个先前选择的行来达到正确的数量,但是一个 msgbox 会提醒你这一点。只需调用传递数量和 Lot# 的函数即可。

Option Compare Database
Option Explicit

Dim myarray()       As Variant

Private Sub cmdSearchBins_Click()
    Mark_ListBox_Rows Me.txtQty, "Lot-A"
End Sub

Function Mark_ListBox_Rows(Qty As Integer, LotNbr As String)
Dim i       As Integer
Dim i2      As Integer
Dim iStart  As Integer
Dim iQty    As Integer
Dim iReserved   As Integer
Dim iAddRow     As Integer
Dim iColUsed    As Integer
Dim iMaxQtyAvail    As Integer

'(1)Either pass the qty (and Lot #) to this routine, or change code to get Qty from another control and set iQty
'(2) Modify code for correct column (I am using col 4 (3 if relative to zero))
'(3) Most times automatic selection will be made. If unable to find simple (one row) solution, let the user pick.

iColUsed = 3        ' (relative to zero)
iMaxQtyAvail = 0

If IsNull(Qty) Or Qty = 0 Then
    MsgBox "You must specify the Quantity!", vbOKOnly, "No Quantity Entered"
    Exit Function
End If


If Me.List2.ColumnHeads = True Then         ' Check if listbox has headings
    iStart = 1                              ' Adjust starting row + 1
Else
    iStart = 0
End If

ReDim myarray(Me.List2.ListCount, 2)        'Resize Array as needed

'Populate Array with ListBox Row & Qty
i2 = 0
For i = 0 To Me.List2.ListCount             ' Spin through listbox
    If Me.List2.Column(2, iStart + i) = LotNbr Then             ' Make sure Lot # matches
        If Me.List2.Column(iColUsed, iStart + i) <> 0 Then      ' Make sure not = 0 (doubt it is in your list, but...)
            myarray(i2, 0) = iStart + i2                        ' Save Row number, then Qty
            myarray(i2, 1) = Int(Me.List2.Column(iColUsed, iStart + i))
            iMaxQtyAvail = iMaxQtyAvail + Int(Me.List2.Column(iColUsed, iStart + i))
            'Debug.Print "List Row: " & i2 & vbTab & "Qty: " & myarray(i2, 1)
            i2 = i2 + 1
        End If
    End If
Next i

If iMaxQtyAvail < Qty Then
    MsgBox "All rows combined only have a quantity of: " & iMaxQtyAvail & vbCrLf & "You asked for quantity of : " & Qty, vbOKOnly, "Insufficient Quantity Available"
    GoTo End_Here
End If

myarray = BubbleSrt(myarray, True)                          ' Sort my Array by Quantity

'    For i = 0 To UBound(myarray)                                ' List what the Array looks like after sorting.
'        Debug.Print "Array: " & i & vbTab & myarray(i, 0) & " - " & myarray(i, 1)
'    Next i

iQty = Qty
iReserved = 0

For i = 0 To Me.List2.ListCount             'Deselect ALL rows in Listbox - in case someone already started....
    List2.Selected(i) = False
Next i

For i = 0 To UBound(myarray)                ' Spin through the Array adding up rows to fulfill the desired quantity
    'The following will search and possibly use part of a bin.
    If myarray(i, 1) <> "" And myarray(i, 1) <= iQty Then           ' Skip empty Array; check if <= Qty
        If iReserved + myarray(i, 1) <= iQty Then
            'Debug.Print "Row: " & myarray(iStart + i, 0) & vbTab & "Qty: " & myarray(iStart + i, 1)
            List2.Selected(myarray(i, 0)) = True       ' Select this row in Listbox
            iReserved = iReserved + myarray(i, 1)       ' Keep track of total reserved so far
            If iReserved = iQty Then                            ' If just the right number, get outta here!
                'Me.txtReserved = iReserved
                GoTo End_Here
            End If
        Else    ' Need to Adjust
            ' Not so simple. Need to see if can deselect a prior selected row and keep this row to arrive at total.
            'Debug.Print "Need to Adjust; Qty Required / Current Reserved + ListItem = " & Qty & " / " & iReserved + myarray(iStart + i, 1)
            iAddRow = i                                 ' Save the row with the qty that would put us over the limit.
            For i2 = iStart + i To 1 Step -1            ' Walk backwards so we deselect largest qty.
                If ((iReserved + myarray(iAddRow, 1)) - myarray(i2, 1)) = iQty Then
                    ' Found the right combination. Deselect this row, and select the row from earlier
                    'Debug.Print "Swap Rows"
                    List2.Selected(myarray(i2, 0)) = False          ' Unselect this row in Listbox
                    List2.Selected(myarray(iAddRow, 0)) = True      ' Select this row in Listbox
                    iReserved = iReserved + myarray(iAddRow, 1) - myarray(i2, 1)   ' Count Total Reserved
                    'Me.txtReserved = iReserved
                    GoTo End_Here
                End If
            Next i2
            ' Yikes! I don't frrl like coding to handle deselecting some combination of 2 or more!!!
            MsgBox "Qty Needed = " & Qty & vbCrLf & "Qty selected = " & iReserved & vbCrLf & vbCrLf & "Please manually select/deselect to obtain desired quantity", vbOKOnly, "Manually Select Quantity"
            GoTo End_Here
        End If
    End If
Next i

    If iQty > iReserved Then
        MsgBox "Unable to find sufficient part quantity!", vbOKOnly, "Not Enough Parts"
        'Deselect ALL
        For i = 0 To Me.List2.ListCount
            List2.Selected(i) = False
        Next i
    End If

End_Here:
'Me.txtQty = Me.txtQty + 1
End Function

Public Function BubbleSrt(ArrayIn As Variant, Ascending As Boolean)

Dim SrtTemp As Variant
Dim i As Long
Dim j As Long
Dim SrtTemp0 As Variant
Dim SrtTemp1 As Variant

If Ascending = True Then
    For i = LBound(ArrayIn) To UBound(ArrayIn)
         For j = i + 1 To UBound(ArrayIn)
             If ArrayIn(i, 1) > ArrayIn(j, 1) Then
                 SrtTemp0 = ArrayIn(j, 0)
                 SrtTemp1 = ArrayIn(j, 1)
                 ArrayIn(j, 0) = ArrayIn(i, 0)
                 ArrayIn(j, 1) = ArrayIn(i, 1)
                 ArrayIn(i, 0) = SrtTemp0
                 ArrayIn(i, 1) = SrtTemp1
             End If
         Next j
     Next i
Else
    For i = LBound(ArrayIn) To UBound(ArrayIn)
         For j = i + 1 To UBound(ArrayIn)
             If ArrayIn(i) < ArrayIn(j) Then
                 SrtTemp = ArrayIn(j)
                 ArrayIn(j) = ArrayIn(i)
                 ArrayIn(i) = SrtTemp
             End If
         Next j
     Next i
End If

BubbleSrt = ArrayIn

End Function

【讨论】:

  • 两个问题:(1)我相当确定列表框是按 Bin # 或 Lot# 排序的,还是两者都排序? (2) 列表框中有多少列(我假设至少3:|Bin|Lot|Qty|),列的顺序是什么?
  • 谢谢,今晚我会检查一下... 1. 按 BIN# 排序,但我可以按最好的排序。 2. |垃圾箱# |货号 |批次# |产品数量 |托盘数量 |
  • 你的列表框有标题吗?如果可以,我可以处理。
  • 我在 BubbleSrt(myarray, True) 处遇到错误...是否需要添加一个函数才能使其正常工作,因为我不知道内置的 BubbleSort 函数。
  • 我的错-我刚刚更新了答案以包含其他功能(最后)-对不起!
猜你喜欢
  • 2011-04-11
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多