Count.if sur variant

Bonjour à tous

auriez-vous une solution à mon tracas du jour

Dim myMat As Variant
myMat = Application.WorksheetFunction.Index(shTest1.Range("A1:D5").Value, 0, 3)
'Recherche de la valeur maximale
Dim valMax As Double
valMax = Application.WorksheetFunction.Max(myMat)
'Récupération de l'indice de la valeur maximale
Dim myMatch As Integer
myMatch = Application.WorksheetFunction.Match(valMax, myMat, 0)
'Mais au fait, il y a peut-être plusieurs valeurs maximales
Dim myCount As Integer
myCount = Application.WorksheetFunction.CountIf(myMat, valMax)

En simplifié, je dois lire une plage, en extraire une colonne, chercher la valeur maximale, et vérifier si elle est unique. Dans la présentation ici c'est simpliste, mais l'idée est que en réalité tout ce fait en mémoire avec des références qui ne sont pas obligatoirement connue avant le lancement, une fois la lecture de la plage de données.

Pourquoi la fonction countif ne fonctionne pas sur myMat, alors que les autres functions Excel Max et Match fonctionnent ?

Merci pour votre éclairage

Bonjour Jeb,

as-tu un exemple en fichier excel ?

Salut

oui je peux fournir un fichier test, mais il n'a que peu d'intérêt. Le voici en pj ac la macro qui s'appelle test3

Merci bcp

Jeb

3sandbox2.xlsm (12.26 Ko)

Je ne comprends pas bien à vrai dire cette instruction

myMat = Application.WorksheetFunction.Index(shTest1.Range("A1:D5").Value, 0, 3)

Pour moi, myMat devrait être un objet range

Dim myMat As Variant
Set myMat = Range("A1:D5")
Debug.Print myMat.Address

Ceci fonctionne, mais pas pour match !

Option Explicit

Sub test3()
Dim shTest1 As Worksheet

Set shTest1 = Worksheets(1)
'Lecture d'une plage de valeur, et récupération de la colonne, ici 3
Dim myMat As Variant
'myMat = Application.WorksheetFunction.Index(shTest1.Range("A1:D5").Value, 0, 3)
Set myMat = Range("A1:D5")
Debug.Print myMat.Address

'Recherche de la valeur maximale
Dim valMax As Double
valMax = Application.WorksheetFunction.Max(myMat)
Debug.Print valMax

'Mais au fait, il y a peut-être plusieurs valeurs maximales
Dim myCount As Integer
myCount = Application.WorksheetFunction.CountIf(myMat, valMax)
Debug.Print myCount

End Sub

Re Salut

merci pour votre réponse

Il s'agirait donc du type de variable retourné par Index ?

Comme vous le savez, Index permet de récupérer une sous-matrice d'une matrice plus conséquente

Cela me permet de faire des calculs sur cette sous matrice. Il est donc important pour moi de pouvoir extraire dynamiquement cette sous-matrice.

Une idée ?

Merci bcp

Autant pour moi ... en effet je n'avais pas saisi que tu faisais les calculs sur un sous-ensemble, en l’occurrence une colonne (et c'est pourquoi match ne fonctionnait pas dans mon essai).

Il faudrait donc transformer ce sous-ensemble en range pour faire fonctionner countif

En introduisant ceci

Dim rng As Range
Set rng = Range("A1:D5").Offset(0, 2).Resize(5, 1)

on définit la colonne en décalant de 2 vers la droite et en redimensionnant à une colonne

Option Explicit

Sub test3()

'Lecture d'une plage de valeur, et récupération de la colonne, ici 3
Dim myMat As Variant
myMat = Application.WorksheetFunction.Index(Range("A1:D5").Value, 0, 3)

'Recherche de la valeur maximale
Dim valMax As Double
valMax = Application.WorksheetFunction.Max(myMat)
Debug.Print valMax

'Récupération de l'indice de la valeur maximale
Dim myMatch As Integer
myMatch = Application.WorksheetFunction.Match(valMax, myMat, 0)
Debug.Print myMatch

'Mais au fait, il y a peut-être plusieurs valeurs maximales
Dim myCount As Integer
Dim rng As Range
Set rng = Range("A1:D5").Offset(0, 2).Resize(5, 1)
myCount = Application.WorksheetFunction.CountIf(rng, valMax)

Debug.Print valMax, Application.WorksheetFunction.Match(valMax, myMat, 0)
Debug.Print valMax, Application.WorksheetFunction.CountIf(rng, valMax)
End Sub

Solution intéressante mais irréalisable en pratique car en fait j'utilise très peu les feuilles excel pour faire les calculs car toutes les données sont stockées en mémoire dans des tableaux dynamiques.

Il n'y a donc pas de solution immédiate

D'ailleurs si je fais un test bidon genre

Sub test4()
Dim myMat(1 To 5) As Double
myMat(1) = 0
myMat(2) = 3
myMat(3) = 2.3
myMat(4) = 5
myMat(5) = 5
Dim valMax As Double
valMax = Application.WorksheetFunction.Max(myMat)
'Récupération de l'indice de la valeur maximale
Dim myMatch As Integer
myMatch = Application.WorksheetFunction.Match(valMax, myMat, 0)
'Mais au fait, il y a peut-être plusieurs valeurs maximales
Dim myCount As Integer
myCount = Application.WorksheetFunction.CountIf(myMat, valMax)

End Sub

je bloque au même endroit

Merci bcp

Solution intéressante mais irréalisable en pratique car en fait j'utilise très peu les feuilles excel pour faire les calculs car toutes les données sont stockées en mémoire dans des tableaux dynamiques.

Fallait le dire, et c'est en effet plus intéressant !

Il faut remplacer WorksheetFunction.CountIfs(_______ par Application.Count(Application.Match_______

du genre

MsgBox Application.Count(Application.Match(ici_mon_tableau, Array(ici_mes_valeurs), 0))

edit : solution page suivante

Voici

Sub test4()
Dim myMat(1 To 5) As Double
myMat(1) = 0
myMat(2) = 3
myMat(3) = 2.3
myMat(4) = 5
myMat(5) = 5
Dim valMax As Double
valMax = Application.WorksheetFunction.Max(myMat)
'Récupération de l'indice de la valeur maximale
Dim myMatch As Integer
myMatch = Application.WorksheetFunction.Match(valMax, myMat, 0)
'Mais au fait, il y a peut-être plusieurs valeurs maximales
Dim myCount As Integer
'myCount = Application.WorksheetFunction.CountIf(myMat, valMax)
myCount = Application.Count(Application.Match(myMat, Array(valMax), 0))
Debug.Print myCount
End Sub

super ça marche

je n'ai pas compris la subtilité, je vais chercher

Mais merci bcp bcp bcp

Amicalement

Jeb

euh, en fait si tu peux m'expliquer la syntaxe

myCount = Application.Count(Application.Match(myMat, Array(valMax), 0))

je n'en suis pas aussi loin dans Excel moi

Merci

et ensuite je clos le sujet

euh, en fait si tu peux m'expliquer la syntaxe

myCount = Application.Count(Application.Match(myMat, Array(valMax), 0))

hé hé, ... si on met les valeurs recherchées dans un array (même une seule), le résultat est aussi un array que l'on peut alors dénombrer !

Merci à un certain @Jeeped

here's how it works:

It's an undocumented feature of Match(lookup value, lookup array, 0) that if you put an array as the lookup value, it will Match() each value in the array you entered against the lookup array.

et je n'ai pas essayé mais il est probable que l'on puisse alors récupérer l'array de sortie, mais je ne sais pas ce qu'elle contient ! à tester ...

Super merci

et pour clore, si tu passes le code sous le debugger VBA, tu vois qu'il y a plein de Erreur 2042 et que seules deux valeurs correspondent à un 1 (True). Cool

Merci à toi de nouveau et bonne fin de journée

Jeb

C'est exact, le Application.Count se fiche éperdument des erreurs.

Rechercher des sujets similaires à "count variant"