Несколько Vlookup или IF условие? - PullRequest
0 голосов
/ 27 августа 2018

У меня есть два файла данных,

один файл, состоящий из данных, таких как

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 голосов
/ 27 августа 2018

Прежде чем я смогу даже ответить на ваш вопрос:

Я сделаю вид, что "Muninch" во 2-м ряду вашего данные просто ошибка с вашей стороны.

Если нет, то на ваш вопрос невозможно ответить, потому что в Excel нет встроенной логики распознавания, какая строка является страной и городом.

Технически вы можете проверить, содержится ли он в диапазоне "Страна" второй таблицы данных, и если нет, мы можем предположить, что это город, но сделайте нам всем и, что еще важнее, себе одолжение и действительно отсортируете ваши данные!

Я пытаюсь сказать, что каждый столбец должен содержать уникальные данные соответствующего типа:

 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

Если у вас есть какие-либо вопросы, пожалуйста, дайте мне знать, я с удовольствием объясню


РЕДАКТИРОВАТЬ: Черт @ СкоттКрейнер и его магические формулы. Хотя, честно говоря, код, который я предоставил, будет работать с любым динамическим диапазоном, в то время как Формула должна быть скорректирована вручную , так что есть некоторая польза для код тем не менее.

Хотя я должен сказать, что это довольно комично, он удалось написать мои ~ сто строк кода в 1 строку. Проголосовал его ответ для простоты, но выбирай то, что посчитаешь нужным.

0 голосов
/ 27 августа 2018

Использовать 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
...