多个Vlookup或IF条件?

时间:2018-08-27 11:53:41

标签: excel vlookup

我有两个数据文件,

一个由数据组成的文件,例如

Column A     Column B     Column C (describes column B)
Germany       Munich       City 
Munich        Germany      Country
Germany       Berlin       Capital
France        Paris        Capital
Paris         France       Country
Spain         Barcelona    City
Spain         Madrid       Capital
Italy         Rome         Capital

另一个数据集为

Column A
France
Paris
Germany
Munich
Italy
Rome
Spain
Madrid
Barcelona

我想在数据集2中获得一个新列,该列说明下一行中的日期是城市还是首都。

例如

Column A     Column B  
Germany      Capital - Berlin, City - Munich
Munich       Munich - Country
France       Capital - Paris
Spain        Barcelona - City and Madrid- Capital   
.
. 
.

2 个答案:

答案 0 :(得分:1)

使用TextJoin作为数组公式

=TEXTJOIN(", ",TRUE,IF(E1=$A$1:$A$8,$B$1:$B$8 & " - " & $C$1:$C$8,""))

作为数组公式,退出编辑模式时必须使用Crtl-Shift-Enter而不是Enter进行确认。

TEXTJOIN是Office 365 Excel引入的

enter image description here


要使公式更具动态性:

=TEXTJOIN(", ",TRUE,IF(E1=$A$1:INDEX(A:A,MATCH("zzz",A:A)),$B$1:INDEX(B:B,MATCH("zzz",A:A)) & " - " & $C$1:INDEX(C:C,MATCH("zzz",A:A)),""))

现在这将增加(或缩小)仅对数据集的有效引用。随着增加的行,它也将引用新项目,而无需进行任何不必要的迭代。


如果没有Office 365 Excel,我们可以将输出拆分为不同的单元格。

=IFERROR(INDEX($B$1:INDEX($B:$B,MATCH("zzz",$A:$A)) &" - " & $C$1:INDEX($C:$C,MATCH("zzz",$A:$A)),AGGREGATE(15,6,ROW($A$1:INDEX($A:$A,MATCH("zzz",$A:$A)))/($A$1:INDEX($A:$A,MATCH("zzz",$A:$A))=$E1),COLUMN(

将此内容放在左上方的单元格中,然后上下复制。

enter image description here


如果必须在同一单元格中有输出并且没有TEXTJOIN,则将此代码用作UDF和上面的相同TEXTJOIN公式:

Function TEXTJOIN(delim As String, skipblank As Boolean, arr)
    Dim d As Long
    Dim c As Long
    Dim arr2()
    Dim t As Long, y As Long
    t = -1
    y = -1
    If TypeName(arr) = "Range" Then
        arr2 = arr.Value
    Else
        arr2 = arr
    End If
    On Error Resume Next
    t = UBound(arr2, 2)
    y = UBound(arr2, 1)
    On Error GoTo 0

    If t >= 0 And y >= 0 Then
        For c = LBound(arr2, 1) To UBound(arr2, 1)
            For d = LBound(arr2, 1) To UBound(arr2, 2)
                If arr2(c, d) <> "" Or Not skipblank Then
                    TEXTJOIN = TEXTJOIN & arr2(c, d) & delim
                End If
            Next d
        Next c
    Else
        For c = LBound(arr2) To UBound(arr2)
            If arr2(c) <> "" Or Not skipblank Then
                TEXTJOIN = TEXTJOIN & arr2(c) & delim
            End If
        Next c
    End If
    TEXTJOIN = Left(TEXTJOIN, Len(TEXTJOIN) - Len(delim))
End Function

答案 1 :(得分:1)

在我什至无法回答你的问题之前:

  

我要假装您提供的第二行中的“ Muninch”   数据只是您的错误。

如果没有,那么您的问题将无法回答,因为Excel没有识别国家和城市字符串的内置逻辑。

从技术上讲,您可以检查它是否包含在第二个数据表的“国家/地区”范围内,如果不包含,则可以假定它是一个城市,但对我们所有人(更重要的是,请您帮个忙)并正确地对数据进行排序! / p>

我想说的是,每一列都必须包含各自类型的唯一数据:

 Country      City       Type
 -------      ----       -----
 Italy        Milan      City
 Italy        Rome       Capital
 Germany      Munich     City
 Amsterdam    Amsterdam  Capital   // < A BIG NO-NO !!!

如果您的答案是,但“但我将它们放在一列中!” ,那么我只是建议您删除这些数据并手动进行转录,因为这样做会浪费更多时间想出一种检测数据何时为国家或城市的算法,而不是简单地手动对数据进行排序的方法。

此外,应该不惜一切代价避免冲突的数据结构/类型,无论是在编程,数据库,数据表还是在您能想到的任何事情上。

正如古老的谚语所说,你不要把苹果和橘子混在一起


现在我们将杂货分类了:

我真的想不出一种通过VLOOKUP通过公式实现的有效方法。
我们需要采用方法的另一种方法:

我们的目标是:

  1. 浏览第二个由独特国家/地区组成的数据表
  2. 在主数据表上使用find操作提取数据
  3. 将其附加到步骤1中表格的相邻列中。
  4. 庆祝好吧我们做到了..!
  

假设大数据表位于Sheet1和国家/地区中   Sheet2

中的数据表

enter image description here enter image description here

我们相应地实现了这一目标:

Option Explicit
Private Sub loop_through_countries()
   Dim ws1 As Worksheet: Set ws1 = Sheets("Sheet1")
   Dim ws2 As Worksheet: Set ws2 = Sheets("Sheet2")
   Dim lr1 As Long ' last active row in sht1
   Dim lr2 As Long ' last active row in sht2
   Dim searchrange As Range 'big data table
   Dim cell As Range ' cell to loop through countries table
   Dim temp As Range ' temp to hold result of find operation
   Dim result As String ' storing result

   lr1 = ws1.Cells(ws1.Rows.Count, 1).End(xlUp).Row
   lr2 = ws2.Cells(ws2.Rows.Count, 1).End(xlUp).Row

   ws1.Range("A1:A" & lr1).Copy ' we add extra column, as we need data to "check off"
   ws1.Range("A1").EntireColumn.Insert ' basically, we need to remove data _ 
                                         from array upon checking for it
   ws1.Range("A1").PasteSpecial xlPasteAll ' otherwise we'd be stuck in endless loop

   Set searchrange = ws1.Range("B2:B" & lr1)

   For Each cell In ws2.Range("A2:A" & lr2) ' for country table

      Set temp = searchrange.Find(cell, LookIn:=xlValues)
      If Not temp Is Nothing Then 'if found
         Do Until temp Is Nothing
             If result = "" Then ' no comma in result if it's first argument
                result = temp.Offset(0, 1) + " - " + temp.Offset(0, 2)
             Else
                result = result + ", " + temp.Offset(0, 1) + " - " + temp.Offset(0, 2)
             End If

             temp = "Checked"
             Set temp = searchrange.FindNext(temp)
         Loop

       Else
          cell.Offset(0, 1) = "No matches found!"
       End If

       cell.Offset(0, 1) = result   '  print result to adjacant column

       ' and we need to reseult our result and temp
       Set temp = Nothing
       result = ""

    Next cell

    ws1.Range("B1").EntireColumn.delete ' and we delete the extra helping column

End Sub

让我们看看它是否结出果实:

好吧,已经有一些双关语了!
最重要的是,尽管有点复杂,但它的工作原理是:

enter image description here

如果您有任何疑问,请告诉我,我很乐意解释


  

编辑:该死的@ScottCraner及其神奇的公式。公平地说,我提供的代码可在任何动态范围内工作,而    公式需要手动调整,因此有一些用途    尽管如此,代码。

     

尽管我不得不说,他颇可笑    设法用1行编写了我的数百行代码。   为了简单起见,对他的回答表示支持,但是请选择您认为合适的任何内容。