开发者

EXCEL - Look up a value in a list and return multiple corresponding values

开发者 https://www.devze.com 2023-04-01 08:12 出处:网络
I am trying to create a Tree Traversal in Excel for 开发者_如何学运维a schedule I have. I am at the point where I have 2 lists each 1006 cells long. The first is predecessors, the second is successors

I am trying to create a Tree Traversal in Excel for 开发者_如何学运维a schedule I have. I am at the point where I have 2 lists each 1006 cells long. The first is predecessors, the second is successors. I am trying to use a set of functions to display multiple results. For instance if I enter 3, I want all of the successors of task 3 to get listed. So far the code I have come up with is:

=IF(ISERROR(INDEX($A$1:$B$1006,SMALL(IF($A$1:$A$1006=$E$3,ROW($A$1:$A$1006)),ROW(1:1)),2)),"NO",INDEX($A$1:$B$1006,SMALL(IF($A$1:$A$1006=$E$3,ROW($A$1:$A$1006)),ROW(1:1)),2))

However when I input the predecessor, it does not display the correct successor.

Thank you in advance for whoever can help me


You cannot join values with formulas (or at least, i can't see an easy way to do it).

You can either call a procedure (faster but more intrusive):

Option Explicit

Sub Proc_ListPre()
Dim rData As Range, lLastrow As Long, i As Integer
Dim aValues() As Variant
Dim sFilter As String, sRes As String

'Ask for the value to filter to the user
sFilter = InputBox("Which predecessor do you want to analyse?", "Please type the predecessor you want")
If Len(sFilter) = 0 Then Exit Sub

'Define the range
'either use UsedRange (if only columns A and B are used)
'Set rData = ActiveSheet.UsedRange
'or use End(xlUp) if not
lLastrow = ActiveSheet.Range("a65536").End(xlUp).Row
Set rData = ActiveSheet.Range("A1:B" & lLastrow)
'Filter the predecessor with the criteria given in arg
rData.AutoFilter Field:=1, Criteria1:=sFilter

'Find the last row of the filtered data
lLastrow = ActiveSheet.Range("a65536").End(xlUp).Row
aValues = ActiveSheet.Range("A2:B" & lLastrow).Value
'Join the 2nd column of the array
'Join(WorksheetFunction.Index(aValues, 0, 2), ";") 'note that this doesn't work because index returns a 2D array
'Workaround to join the 2nd column
For i = 1 To UBound(aValues, 1)
    If Len(CStr(aValues(i, 2))) > 0 Then
        sRes = sRes & aValues(i, 2) & ";"
    End If
Next
sRes = Left(sRes, Len(sRes) - 1)
MsgBox sRes

ActiveSheet.AutoFilterMode = False
End Sub

or use a formula that you will call in your worksheet as =ListPre(mypredecessor)

Function ListPre(ByVal sFilter As String)
Dim rData As Range, lLastrow As Long, i As Integer
Dim aValues() As Variant
Dim sRes As String

'Define the range
'either use UsedRange (if only columns A and B are used)
'Set rData = ActiveSheet.UsedRange
'or use End(xlUp) if not
lLastrow = ActiveSheet.Range("a65536").End(xlUp).Row
Set rData = ActiveSheet.Range("A1:B" & lLastrow)
aValues = ActiveSheet.Range("A2:B" & lLastrow).Value

'Join the 2nd column of the array
'Join(WorksheetFunction.Index(aValues, 0, 2), ";") 'note that this doesn't work because it returns a 2D array
'Workaround to join the 2nd column
For i = 1 To UBound(aValues, 1)
    If Len(CStr(aValues(i, 2))) > 0 And CStr(aValues(i, 1)) = sFilter Then
        sRes = sRes & aValues(i, 2) & ";"
    End If
Next
sRes = Left(sRes, Len(sRes) - 1)
ListPre = sRes
End Function
0

精彩评论

暂无评论...
验证码 换一张
取 消