Vlookupまたは同様の関数を使用してワークシートを検索し、アカウント番号を照合してから、指定された値を返そうとしています。私の問題は、アカウント番号が重複しているため、結果を1つの文字列に連結したいということです。
Acct No CropType
------- ---------
0001 Grain
0001 OilSeed
0001 Hay
0002 Grain
最初のワークシートにあり、2番目のワークシートには他の情報を含むAcct Noがあり、一致するすべての結果を2番目のワークシートの1つの列にまとめる必要があります。 「穀物油糧種子干し草」
これがあなたのためにそれをする関数です。 Vlookupとは少し異なり、範囲全体ではなく検索列のみを指定します。次に、3番目のパラメーターとして、取得するために左(負の数)または右(正)に移動する列の数を指定します。あなたの戻り値。
セパレーターを使用するオプションも追加しました。あなたの場合は「」を使用します。アカウント番号の最初の行がAで、結果が行Bであると仮定した場合の、関数呼び出しは次のとおりです。
=vlookupall("0001", A:A, 1, " ")
関数は次のとおりです。
Function VLookupAll(ByVal lookup_value As String, _
ByVal lookup_column As range, _
ByVal return_value_column As Long, _
Optional seperator As String = ", ") As String
Dim i As Long
Dim result As String
For i = 1 To lookup_column.Rows.count
If Len(lookup_column(i, 1).text) <> 0 Then
If lookup_column(i, 1).text = lookup_value Then
result = result & (lookup_column(i).offset(0, return_value_column).text & seperator)
End If
End If
Next
If Len(result) <> 0 Then
result = Left(result, Len(result) - Len(seperator))
End If
VLookupAll = result
End Function
ノート:
これを行う1つの方法は、配列数式を使用してすべての一致を非表示の列に入力し、それらの値を文字列に連結して表示することです。
=IFERROR(INDEX(cropTypeValues,SMALL(IF(accLookup=accNumValues,ROW(accNumValues)-MIN(ROW(accNumValues))+1,""),ROW(A1))),"")
配列数式として入力し(Ctrl + Shift + Enter)、必要なだけコピーします。
数式の説明が必要な場合はお知らせください。
これが私のコードです。これは、列を基準にすることを選択できるため、Excelのvlookupよりも優れており、確実にセパレーター(キャリッジリターンも)...
Function Lookup_concat(source As String, tableau As Range, separator As String, colSRC As Integer, colDST As Integer) As String
Dim i, y As Integer
Dim result As String
If separator = "CRLF" Then
separator = Chr(10)
End If
y = tableau.Rows.Count
result = ""
For i = 1 To y
If (tableau.Cells(i, colSRC) = source) Then
If result = "" Then
result = tableau.Cells(i, colDST)
Else
result = result & separator & tableau.Cells(i, colDST)
End If
End If
Next
Lookup_concat = result
End Function
また、ギフトとして、同じセルの複数の要素を(同じセパレーターに基づいて)検索することもできます。本当に便利
Function Concat_Lookup(source As String, tableau As Range, separator As String, colSRC As Integer, colDST As Integer) As String
Dim i, y As Integer
Dim result As String
Dim Splitted As Variant
If separator = "CRLF" Then
separator = Chr(10)
End If
Splitted = split(source, separator)
y = tableau.Rows.Count
result = ""
For i = 1 To y
For Each Word In Splitted
If (tableau.Cells(i, colSRC) = Word) Then
If result = "" Then
result = tableau.Cells(i, colDST)
Else
Dim Splitted1 As Variant
Splitted1 = split(result, separator)
If IsInArray(tableau.Cells(i, colDST), Splitted1) = False Then
result = result & separator & tableau.Cells(i, colDST)
End If
End If
End If
Next
Next
Concat_Lookup = result
End Function
前のサブにはこの機能が必要です
Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
IsInArray = (UBound(Filter(arr, stringToBeFound)) > -1)
End Function
私はちょうど同じような問題を抱えていて、長い間同じような解決策を探してきましたが、私を本当に納得させるものは何もありませんでした。マクロまたは特別な関数を作成する必要がありましたが、私のニーズでは、最も簡単な解決策は、たとえば、ピボットテーブルを使用することです。 Excel。
データから新しいピボットテーブルを作成し、最初に行ラベルとして「Acct No」を追加し、次にRowLabelとして「CropType」を追加すると、アカウントごとにすべての作物タイプが一覧表示される非常に優れたグループになります。ただし、単一のセルではそれは行われません。