自动化列表框选择

时间:2014-03-05 18:50:37

标签: listbox access-vba multi-select totals

我有一个我希望能够自动化的列表框,这样当我输入一个项目的总数量时,它将多次选择行直到达到该总数。在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

1 个答案:

答案 0 :(得分:0)

更新以添加缺少的功能...以下代码将在您的列表框中旋转,寻找匹配的“Lot#”并选择将提供所需数量的行。列表框数量被放入一个数组中,然后进行排序,这样它将需要最小的数量来释放大多数垃圾箱。我懒得让代码取消选择多个先前选择的行来达到正确的数量,但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