Cela peut être accompli sans aucune VBA en utilisant la TEXTJOIN()
fonction introduite dans Excel 2016. Si vous ne possédez pas cette version d'Excel, vous pouvez installer un fichier UDF à remplissage multiple. J'ai fourni un élément de base à la fin de cette réponse.
Tableau-entrez la formule suivante dans E2
:
{=TEXTJOIN(", ",TRUE,IFERROR(INDEX(A1:A5,N(IF(1,SMALL(IFERROR(1/(1/((B1:B5=D2)*ROW(B1:B5))),FALSE),ROW(INDEX(E:E,1):INDEX(E:E,ROWS(B1:B5))))))),""))}
La formule raffinée est la suivante:
{=
TEXTJOIN(
", ",
TRUE,
IFERROR(
INDEX(
A1:A5,
N(IF(1,
SMALL(
IFERROR(1/(1/((B1:B5=D2)*ROW(B1:B5))),FALSE),
ROW(INDEX(E:E,1):INDEX(E:E,ROWS(B1:B5)))
)
))
),
""
)
)}
Remarques:
- La formule raffinée fonctionne réellement si elle est entrée.
Ma version de l' TEXTJOIN()
UDF Poly-Fill:
'============================================================================================
' Module : <any standard module>
' Version : 0.1.1
' Part : 1 of 1
' References : Optional - Microsoft VBScript Regular Expressions 5.5 [VBScript_RegExp_55]
' Source : https://superuser.com/a/1331555/763880
'============================================================================================
Public Function TEXTJOIN( _
ByRef delimiter As String, _
ByRef ignore_empty As Boolean, _
ByRef text1 As Variant _
) _
As String
Dim ƒ As Excel.WorksheetFunction: Set ƒ = Excel.WorksheetFunction
Const DELIMITER_ As String = "#"
Const PATTERN_ As String = "^(?:#)+|(?:#)+$|(#){2,}"
Static rexDelimiterEscaper As Object ' VBScript_RegExp_55.RegExp ' ## Object
Static rexEmptyIgnorer As Object ' VBScript_RegExp_55.RegExp ' ## Object
If rexEmptyIgnorer Is Nothing _
Then
Set rexEmptyIgnorer = CreateObject("VBScript.RegExp") ' New VBScript_RegExp_55.RegExp ' ## CreateObject("VBScript.RegExp")
With rexEmptyIgnorer
.Global = True
.Pattern = PATTERN_ ' Replacement = "$1"
End With
Set rexDelimiterEscaper = CreateObject("VBScript.RegExp") ' New VBScript_RegExp_55.RegExp ' ## CreateObject("VBScript.RegExp")
With rexDelimiterEscaper
.Global = True
.Pattern = "(.)" ' Replacement = "\$1"
End With
End If
Dim varText1 As Variant
Select Case TypeName(text1)
Case "Range":
varText1 = ƒ.Transpose(text1.Value2)
If text1.Rows.Count = 1 Then
varText1 = ƒ.Transpose(varText1)
If text1.Columns.Count = 1 Then varText1 = Array(varText1)
End If
Case "Variant()":
On Error Resume Next
If LBound(text1, 2) <> LBound(text1, 2) Then
varText1 = text1
Else
varText1 = ƒ.Transpose(text1)
End If
On Error GoTo 0
Case Else:
varText1 = Array(text1)
End Select
If ignore_empty _
Then
With rexEmptyIgnorer
.Pattern = Replace(PATTERN_, DELIMITER_, rexDelimiterEscaper.Replace(delimiter, "\$1"))
TEXTJOIN = .Replace(Join(varText1, delimiter), "$1")
End With
Else
TEXTJOIN = Join(varText1, delimiter)
End If
End Function
Remarques:
- Ce n'est pas un remplissage multiple approprié:
- Les deux premiers arguments ne sont pas optionnels.
- Si vous ne souhaitez pas utiliser de délimiteur, vous devez passer une chaîne vide comme premier paramètre.
- Un seul autre argument (également requis) est autorisé.
- Vous pouvez transmettre n'importe quoi pour le troisième argument, à l' exception d' un tableau / intervalle multidimensionnel. Cela entraînerait une
#VALUE!
erreur.
- Il devrait être très rapide, en particulier pour les grandes entrées, car il n’utilise aucune boucle. Si vous n'ignorez pas les valeurs vides, ce sera rapide comme l'éclair. Les ignorer sera plus lent car deux expressions rationnelles et une manipulation de chaîne supplémentaire doivent également être utilisées.