Disons que j'ai une table comme celle-ci:
Country Region Mytext
USA North a
USA South b
Brasil North c
Brasil South d
Comment puis-je obtenir un pivot comme celui-ci dans Excel?
Country North South
USA a b
Brasil c d
Si 'mytext' était un nombre, je pourrais faire un tableau croisé dynamique: puisqu'il n'y a qu'une seule ligne par combinaison de pays et de région, min = max = sum = avg et n'importe laquelle de ces fonctions agrégées me montrerait en fait le résultat Je voudrais.
Mais que faire lorsque le champ que je souhaite n'est pas numérique? Avec la bibliothèque pandas de Python, je peux utiliser la méthode dataframe.pivot () même sur des champs non numériques, mais je n'ai pas trouvé de moyen de faire la même chose dans Excel. Je pourrais associer un numéro à chaque ligne, faites le pivot dans Excel pour afficher ce numéro, puis faites une recherche pour obtenir le texte associé, mais cela semble un processus plutôt compliqué pour quelque chose qui devrait vraiment être plus facile!
vous pouvez utiliser le Complément MS Power Query *. Les tables pivotantes sont sans vba très faciles. C'est gratuit et très efficace pour la transformation des données.
le M-Code
let
Source = Excel.CurrentWorkbook(){[Name="table1"]}[Content],
#"Pivot column" = Table.Pivot(Source, List.Distinct(Source[Region]), "Region", "Mytext")
in
#"Pivot column"
´ * de MS Office 2016, il est entièrement intégré dans Excel en tant que fonction Get & Transform .
Pour les futurs lecteurs - utilisez deux fonctionnalités ensemble:
Ruban> Outils de tableau croisé dynamique> Présentation du rapport> Afficher sous forme de tableau
et
Ruban> Outils de tableau croisé dynamique> Présentation du rapport> Répéter toutes les étiquettes d'élément
Les champs de ligne seront présentés de gauche à droite sous forme de texte répété verticalement.
Ajoutez le MyText en tant qu'étiquette de ligne sous l'étiquette Country, puis affichez le tableau croisé dynamique au format tabulaire sous l'onglet de conception du tableau croisé dynamique. Répétez les étiquettes d'élément pour le champ d'étiquette de ligne de pays.
Cela peut être fait, mais nécessite que VBA écrase temporairement une valeur "d'espace réservé" numérique dans votre tableau croisé dynamique avec du texte. Pour activer cela, vous devez définir EnableDataValueEditing = True pour le tableau croisé dynamique. Lors de l'actualisation, vous effectuez ensuite une recherche sur la valeur d'espace réservé numérique et la remplacez par du texte. Compliqué, oui. Solution de contournement, oui. Mais ça fait l'affaire. Notez que cela ne "colle" qu'à la prochaine actualisation du tableau croisé dynamique, ce code doit donc être déclenché à chaque actualisation.
Voici le code que j'utilise pour le faire dans l'un de mes propres projets. Mettez cela dans un module de code standard:
Function Pivots_TextInValuesArea(pt As PivotTable, rngNumeric As Range, rngText As Range, Optional varNoMatch As Variant)
Dim cell As Range
Dim varNumeric As Variant
Dim varText As Variant
Dim varResult As Variant
Dim bScreenUpdating As Boolean
Dim bEnableEvents As Boolean
Dim lngCalculation As Long
On Error GoTo errHandler
With Application
bScreenUpdating = .ScreenUpdating
bEnableEvents = .EnableEvents
lngCalculation = .Calculation
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
varNumeric = rngNumeric
varText = rngText
pt.EnableDataValueEditing = True
'Setting this to TRUE allow users or this code to temporarily overwrite PivotTable cells in the VALUES area.
'Note that this only 'sticks' until the next time the PivotTable is refreshed, so this code needs to be
' triggerred on every refresh
For Each cell In pt.DataBodyRange.Cells
With cell
varResult = Application.Index(varText, Application.Match(.Value2, varNumeric, 0))
If Not IsError(varResult) Then
cell.Value2 = varResult
Else:
If Not IsMissing(varNoMatch) Then cell.Value2 = varNoMatch
End If
End With
Next cell
errHandler:
If Err.Number > 0 Then
If gbDebug Then
Stop: Resume
Else:
MsgBox "Whoops, there was an error: Error#" & Err.Number & vbCrLf & Err.Description _
, vbCritical, "Error", Err.HelpFile, Err.HelpContext
End If
End If
With Application
.ScreenUpdating = bScreenUpdating
.EnableEvents = bEnableEvents
.Calculation = lngCalculation
End With
End Function
Et voici le résultat: un tableau croisé dynamique avec du texte dans la zone VALEURS:
Voici le tableau de conversion qui indique au code ce qu'il doit afficher pour chaque numéro:
J'ai attribué deux plages nommées à celles-ci, afin que mon code sache où trouver la table de recherche:
... et voici comment je déclenche la fonction et passe les arguments requis:
Option Explicit
Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
If Target.Name = "GroupView" Then Pivots_TextInValuesArea Target, [tbl_PivotValues.NumericValue], [tbl_PivotValues.TextValue]
End Sub
Ce code va dans le module de code de feuille de calcul qui correspond à la feuille de calcul où le tableau croisé dynamique est: