从集合VBA返回索引号

时间:2014-08-18 00:38:28

标签: excel-vba collections indexing key vba

如果我创建了一个集合,我可以搜索该集合并从集合中搜索 RETURN THE INDEX 号码吗?

由于我的新手身份,我无法发布我正在尝试做的截图,所以让我试着解释一下我想要实现的目标:

我有一个Excel格式的仓库数据库的历史记录,长达几千行 - 每行代表一个产品的交易进出多达10个不同的箱子。我的目标是识别成千上万行中所有可能的不同垃圾箱,将那些~10个垃圾箱复制/转置到列标题,然后完成每笔交易并将交易数量(+ 1,-3等)复制到正确的因此,能够分离交易并且更容易地识别并生成何时产品移入/移出每个相应仓的计算。这将排序看起来像数据透视表,但这不是真正的工作方式。

这是我目前正在处理的代码,带有注释。我的问题在上一条评论中有解释:

Sub ForensicInventory()
Dim BINLOCAT As Collection
Dim Rng As Range
Dim Cell As Range
Dim sh As Worksheet
Dim vNum As Variant
Dim BINcol As Integer
Dim ACTcol As Integer
Dim QTYcol As Integer
Dim i As Integer
Dim lastrow As Long
Dim x As Long

'This part is used to find the relevant columns that will be used later
BINcol = ActiveSheet.Cells(1, 1).EntireRow.Find(What:="BINLABEL", LookIn:=xlValues, _
    LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False).Column
ACTcol = ActiveSheet.Cells(1, 1).EntireRow.Find(What:="ACTION", LookIn:=xlValues, _
    LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False).Column
QTYcol = ActiveSheet.Cells(1, 1).EntireRow.Find(What:="QUANTITY", LookIn:=xlValues, _
    LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False).Column

lastrow = Cells(Rows.Count, 1).End(xlUp).Row

i = 0
Set sh = ActiveWorkbook.ActiveSheet
Set Rng = sh.Range(sh.Cells(2, BINcol), sh.Cells(Rows.Count, BINcol).End(xlUp))
Set BINLOCAT = New Collection

'This next section searches the bin column and builds the collection of unique bins that I am interested in.
On Error Resume Next
    For Each Cell In Rng.Cells
        If Len(Cell.Value) <> 8 And Not IsEmpty(Cell) Then
            BINLOCAT.Add Cell.Value, CStr(Cell.Value)
        End If
    Next Cell
On Error GoTo 0

'Now I take those unique bin names and I put them into a column header on the same spreadsheet, starting in column 10, and spacing every 2 cells thereafter.
For Each vNum In BINLOCAT
    Cells(1, 10 + i).Value = vNum
    i = i + 2
Next vNum

    'Here is where the problem exists for me.  This code works and succeeds in copying the QTY
    'to column 10, but what I really want to do is determine the index number of the bin from BINLOCAT,
    'and use that index number to place the value under the appropriate column header.
For x = 2 To lastrow
  Select Case Cells(x, ACTcol).Value
      Case "MOVE-IN"
        Cells(x, 10).Value = Cells(x, QTYcol).Value
      Case "MOVE-OUT"
        Cells(x, 10).Value = -Cells(x, QTYcol).Value
      Case Else
  End Select
Next x

End Sub

在“For x = 2 to lastrow”循环中,我需要找到一种方法来从搜索集合BINLOCAT中的bin中获取INDEX编号(1,2,3等)。 BINLOCAT一旦创建,就是静态的。我想象的是:

neededcolumn = BINLOCAT.item(cells(x,BINcol).value).index (pseudocode)

然后我会将Case Stmt中的10s替换为“neededcolumn”,这样就行了。

也许我采取了错误的方法,但在我看来,我需要这个集合才能有效地完成搜索部分。有任何想法或解决方案的链接?基于我在其他地方阅读的内容,我认为我所描述的这种能力是不可用的,但我不确定我是否已经理解了迄今为止我所读到的关于馆藏的所有内容。

2 个答案:

答案 0 :(得分:0)

不使用for循环,而是使用for n = 1 to BINLOCAT.Count循环 - 然后n就是你的索引。还是我误解了?

答案 1 :(得分:-1)

免责声明:好的,我将回答我自己的问题,但根据@Rory在8月18日13:07发表的评论,我得到了这个答案。所以,谢谢你,罗里!罗瑞的答案本身没有以我需要的方式启发我(或者我太愚蠢而无法看到它 - 总是可能的),所以我不接受他的答案,但我想承认他的帮助。我仍然怀疑可能有比我正在做的更好的方式,所以请随时评论/回答/纠正我。

为了简单和彻底,假设以下起始数据: 范围( “A1:A16”)=

  • BM182B
  • BM182B
  • BM182B
  • BM182B
  • BM182B
  • AS662B
  • BM182B
  • BM182B
  • BM182B
  • BM182B
  • AS702B
  • AS642B
  • BM182B
  • BM182B
  • BM182B
  • BM182B

根据Rory的评论,这是我提出的第一段代码:

    Sub TestofCollection()
    Dim BinCollection1 As Collection
    Dim n As Integer
    Dim x As Integer

    Set BinCollection1 = New Collection

    n = 1

    On Error Resume Next
        For Each Cell In Range("A1:A16")
            BinCollection1.Add n, CStr(Cell.Value)
            n = n + 1
        Next Cell
    On Error GoTo 0

    For x = 1 To BinCollection1.Count
        Range("B" & x).Value = BinCollection1.Item(x)
    Next x

    End Sub

这个问题是输出或我得到的“索引”实际上是每个bin在列表中第一次出现时的位置。因此,输出段的结果是“1,6,11,12”而不是列表“BM182B,AS662B,AS702B,AS642B”的所需“1,2,3,4”。是否有更好的方法,我不知道,但我的解决方案是在下一个代码中创建一个“集合的集合”,如下所示:

    Sub TestofCollection2()
    Dim BinCollection1 As Collection
    Dim BinCollection2 As Collection

    Set BinCollection1 = New Collection
    Set BinCollection2 = New Collection

    n = 1

    On Error Resume Next
        For Each Cell In Range("A1:A16")
            BinCollection1.Add Cell.Value, CStr(Cell.Value)
        Next Cell

        For Each x In BinCollection1
            BinCollection2.Add n, BinCollection1.Item(x)
            n = n + 1
        Next x
    On Error GoTo 0

    For x = 1 To BinCollection2.Count
        Range("C" & x).Value = BinCollection2.Item(x)
    Next x

    'Test output result should be 3 below
    MsgBox "Test Output:  " & BinCollection2.Item("as702b")

    End Sub

所以现在,基于这种双重收集工作,我可以搜索我的数千行的二进制列,并确定它们的索引来创建我的偏移量。使用列表中的那些键,索引显示为“1,2,3,4”。

这是我在Stack Overflow上的第一个问题和第一个答案。我可能会花几天时间来看看是否有人有更好的答案,但是我会在这里“接受”我自己的答案,因为这对我有帮助(如果以后出现更好的答案,我可以“接受”我的答案吗? )。再次,评论或建议非常感谢和接受。感谢您的观看。