Excel: affiche la liste des valeurs en fonction de la requête dans la plage

1

J'ai une table comme celle-ci:

a    |    tomato
b    |    pear
c    |    tomato
d    |    pear

J'aimerais créer une formule qui me permette de sélectionner les rangées contenant des tomates et celles contenant des poires. le résultat de la formule serait donc "a, c" pour la requête pour la tomate et "b, d" pour la requête pour la tomate.

cela peut-il être fait dans Excel (et si oui, comment?)

Je vous remercie!

Haaid
la source
Il n'y a pas de fonction de feuille de calcul qui concatre (de manière conditionnelle) les valeurs de chaîne de la cellule de plage en une valeur. Vous pouvez résoudre la tâche en utilisant des colonnes supplémentaires ou en utilisant une fonction définie par l'utilisateur (code VBA - la solution la plus simple à mon avis).
Akina
Bonjour Akina, merci pour votre réponse. Pouvez-vous expliquer ce que vous entendez par "utiliser des colonnes supplémentaires?" Parce que si je pouvais juste obtenir un retour comme un | c dans deux colonnes différentes, puis je froid ensuite concaténer ces cellules pour obtenir le résultat souhaité.
Haaid
@ Akina Vous n'avez pas besoin d'une fonction qui concatène de manière conditionnelle. Vous pouvez générer les valeurs appropriées avec une fonction de tableau, puis utiliser CONCAT()ou TEXTJOIN(). Aucune colonne supplémentaire ni VBA n'est requis. (À moins que vous n'ayez pas Excel 2016, bien sûr.)
robinCTS
À moins que vous n'ayez pas Excel 2016, bien sûr. Hélas, seulement 2010 :( ...
Akina
@Akina Il suffit d'utiliser mon fichier UDF poly-fill fourni ;-) (ou vous pouvez rechercher d'autres versions en ligne.) Au fait, je ne suis que 2007 :-P
robinCTS

Réponses:

1

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.

Capture d'écran de la feuille de travail

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.
robinCTS
la source
0

La fonction définie par l'utilisateur peut aider.

Imaginez que vous ayez les données suivantes sur la feuille de calcul:

  |  A  |  B
--+-----+---------
1 |  a  |  tomato
2 |  b  |  pear
3 |  c  |  tomato
4 |  d  |  pear

Ouvrez l'éditeur VBA (Alt-F11). Insérer un nouveau module (Insert - Module). Insérez le code ci-dessous:

Public Function GetValues(rngSource As Range, strValue As String) As String
Dim i As Integer
If rngSource.Columns.Count <> 2 Then
    GetValues = "#ERROR - Source range must have 2 columns!"
    Exit Function
End If
For i = 1 To rngSource.Rows.Count
    If rngSource.Cells(i, 2) = strValue Then
        GetValues = GetValues & "," & rngSource.Cells(i, 1)
    End If
Next
GetValues = Mid(GetValues, 2)
End Function

Fermez l'éditeur VBA.

Passez à la feuille de calcul. Insérez une valeur "tomate" dans la cellule D1.

Sélectionnez la cellule E1. Insérez la formule ci-dessous:

=GetValues(A1:B4;D1)

La valeur de la cellule E1 est 'a, c'. Modifiez la valeur D1 en "pear" - la valeur E1 changera. Modifiez la valeur D1 en "pomme" - la valeur E1 deviendra une chaîne vide.

Akina
la source