【问题标题】:Retrieve multiple values associated with single ID in excel在excel中检索与单个ID关联的多个值
【发布时间】:2016-08-07 09:48:52
【问题描述】:

我很好奇是否有更简单的解决方案来检索与 Excel 中的单个 ID 关联的值。

我已经探索了 INDEX 解决方案来查找列表中的多个值,但这并不是真正动态的,并且会以垂直顺序而不是我需要的水平顺序为您提供结果。 (请参阅下面的所需结果)

我使用的示例函数是这样的

"=IF(ISERROR(SMALL(IF(IF(ISERROR(SEARCH($A$9,$A$1:$A$7)),FALSE,TRUE),ROW($A$1:$A$7)), ROW($C$1:$C$7))),"",INDEX($A$1:$C$7,SMALL(IF(IF(ISERROR(SEARCH($A$9,$A$1:$A$7)), FALSE,TRUE),ROW($A$1:$A$7)),ROW($C$1:$C$7)),3))"

*忽略此示例的引用。

我有两张正在处理的工作表,基本上需要从“数字工作表”中检索与单个 ID 关联的值,并将它们存储在“主工作表”上,请参阅下图以获得更清晰的解释。公式需要找到与ID关联的后续数字,并将其放在后续列中,如下所示。

*注意:任何用户 ID 都可以请求任意数量的票证,因此范围可以从 1-100(仅以 3 为例)

在这里感谢 excel 大师的任何指导。我能想到的唯一其他解决方案是使用 vba 代码检索每个值并将其存储在数组中,然后从数组中检索值。让我知道你的想法!

提前致谢!

主表:

数字表:

想要的结果:

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    将以下公式放入Master Sheet的单元格C2[1]中

    {=IFERROR(INDEX(Numbers!$A:$C,SMALL(IF(Numbers!$A$1:$A$1000=$A2,ROW(Numbers!$A$1:$A$1000)),INT((COLUMN(A:A)-1)/2)+1),MOD(COLUMN(A:A)-1,2)+2),"")}
    

    [1] 我假设它是第 2 行,因为很遗憾您没有显示行号。

    公式是数组公式。将其输入到不带大括号的单元格中,然后按 [Ctrl] + [Shift] + [Enter] 确认。大括号会自动出现。

    然后根据需要将公式向右和向下填充。

    【讨论】:

    • 哇这个好用!谢谢你!真的很简单!
    【解决方案2】:

    你可以试试这个代码

    Sub main()        
        Dim IdRng As Range, cell As Range, filtCell As Range
        Dim i As Long
    
        With Worksheets("Master Sheet") 
            Set IdRng = .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)).SpecialCells(XlCellType.xlCellTypeConstants)
        End With
    
        With Worksheets("Numbers")
            With .Cells(1, 1).CurrentRegion
                For Each cell In IdRng  
                    .AutoFilter field:=1, Criteria1:=cell.value '<--| filter it on current department value
                    If Application.WorksheetFunction.Subtotal(103, .Cells.Resize(, 1)) > 1 Then
                        For Each filtCell In .Offset(1, 1).Resize(.Rows.Count - 1, 1).SpecialCells(XlCellType.xlCellTypeVisible)
                            cell.End(xlToRight).Offset(, 1).Resize(, 2).value = filtCell.Resize(, 2).value
                        Next filtCell
                    End If
                Next cell
            End With
            .AutoFilterMode = False
        End With
    
        With Worksheets("Master Sheet").Cells(1, 1).CurrentRegion.Rows(1) 
            .Insert
            With .Offset(-1)
                .Font.Bold = True
                .Resize(, 2) = Array("ID", "Name")
                For i = 1 To .Columns.Count - 2 Step 2
                    .Offset(, 1 + i).Resize(, 2) = Array("Description " & (i + 1) / 2, "Number " & (i + 1) / 2)
                Next i
            End With
        End With
    
    End Sub
    

    【讨论】:

    • 感谢您花时间考虑这个问题,但我在上面有一个更简单的方法,我现在将其标记为答案。
    • 不客气。每种方法都有其缺点:VBA 的缺点是您必须编写代码并从某个地方调用它(按钮、快捷方式、Alt-F8 ...)。公式方法的缺点是,用公式填充的单元格越多,文件越大(字节)越慢,尤其是数组公式。如果您感谢我的贡献,您可能想要投票|
    【解决方案3】:

    VBA 可能是更好的途径,使用 .Find 和 .FindNext 是我的选择。

    Attached 是一个通用的 FindAll 函数,因此您可以查找包含相关 ID 的所有单元格,然后一次处理一个单元格。

    Function FindAll(What, _
        Optional SearchWhat As Variant, _
        Optional LookIn, _
        Optional LookAt, _
        Optional SearchOrder, _
        Optional SearchDirection As XlSearchDirection = xlNext, _
        Optional MatchCase As Boolean = False, _
        Optional MatchByte, _
        Optional SearchFormat) As Range
    
        'LookIn can be xlValues or xlFormulas, _
         LookAt can be xlWhole or xlPart, _
         SearchOrder can be xlByRows or xlByColumns, _
         SearchDirection can be xlNext, xlPrevious, _
         MatchCase, MatchByte, and SearchFormat can be True or False. _
         Before using SearchFormat = True, specify the appropriate settings for the Application.FindFormat _
         object; e.g. Application.FindFormat.NumberFormat = "General;-General;""-"""
    
        Dim SrcRange As Range
        If IsMissing(SearchWhat) Then
            Set SrcRange = ActiveSheet.UsedRange
        ElseIf TypeOf SearchWhat Is Range Then
            Set SrcRange = IIf(SearchWhat.Cells.Count = 1, SearchWhat.Parent.UsedRange, SearchWhat)
        ElseIf TypeOf SearchWhat Is Worksheet Then
            Set SrcRange = SearchWhat.UsedRange
        Else: Set SrcRange = ActiveSheet.UsedRange
        End If
        If SrcRange Is Nothing Then Exit Function
    
        'get the first matching cell in the range first
        With SrcRange.Areas(SrcRange.Areas.Count)
            Dim FirstCell As Range: Set FirstCell = .Cells(.Cells.Count)
        End With
    
        Dim CurrRange As Range: Set CurrRange = SrcRange.Find(What:=What, After:=FirstCell, LookIn:=LookIn, LookAt:=LookAt, _
            SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
    
        If Not CurrRange Is Nothing Then
            Set FindAll = CurrRange
            Do
                Set CurrRange = SrcRange.Find(What:=What, After:=CurrRange, LookIn:=LookIn, LookAt:=LookAt, _
                SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
                If CurrRange Is Nothing Then Exit Do
                If Application.Intersect(FindAll, CurrRange) Is Nothing Then
                    Set FindAll = Application.Union(FindAll, CurrRange)
                Else: Exit Do
                End If
            Loop
        End If
    End Function
    

    【讨论】:

    • 谢谢@Flephal,我会试一试并返回结果。
    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 2019-11-27
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 2011-09-27
    相关资源
    最近更新 更多