Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

index / match multi critères

4 réponses
Avatar
LaurentC
Bonjour Í  tous


Dans une cellule, j'ai la formule suivante qui me va Í  ravir :-)

=INDEX(TblOpérations[PRU];EQUIV(1;((TblOpérations[Titre]="Cisco
Systems")*(TblOpérations[DateOpé]<="19/07/2022")*(TblOpérations[PRU]<>""));0))

Comme attendue, elle me renvoie la première occurence du tableau
correspondant aux critères.

Je souhaite obtenir la même chose en VBA.

LaDate = CDate("19/07/2022")
LeTitre = "Cisco Systems"
msgbox Application.Index(Range("TblOpérations[[All],[PRU]]"),
Application.Match(1, (Range("TblOpérations[[All],[Titre]]") = LeTitre)
* (Range("TblOpérations[[All],[DateOpé]]") <= LaDate) *
(Range("TblOpérations[[All],[PRU]]")<>""), 0))

erreur 1004, la méthode range de l'objet global Í  échoué

J'ai essayé plein de choses sans succès :-(

Comment faire ?

J'ai l'impression que c'est le Match qui va pas ...

Merci pour vos suggestions
@+Laurent

4 réponses

Avatar
MichD
Le 14/08/22 Í  11:11, LaurentC a écrit :
=INDEX(TblOpérations[PRU];EQUIV(1;((TblOpérations[Titre]="Cisco
Systems")*(TblOpérations[DateOpé]<="19/07/2022")*(TblOpérations[PRU]<>""));0))

Bonjour,
Essaie comme ceci. Évidemment, je n'ai pas l'application pour effectuer
un test.
Dim D As Date
D = CDate("19/07/2022")
With Application
x = .Index(Range("TblOpérations[PRU]", .Match(1,
((Range("TblOpérations[Titre]") = _
"Cisco Systems") * (Range("TblOpérations[DateOpé]") <= D) * _
(Range("TblOpérations[PRU]") <> "")), 0)))
End With
La fonction de conversion Cdate() utilise le format court de la date
définie par défaut dans le panneau de configuration Windows.
La date que tu passes Í  la fonction doit être dans le même format que
celui de panneau de configuration.
En supposant que ton classeur se promène sur plusieurs ordinateurs
différents, il serait plus sécuritaire d'utiliser la fonction DateSerial
comme ceci : D = DateSerial(2022, 7, 19) . La formule sera indépendante
du format date par défaut du panneau de configuration de Windows.
MichD
Avatar
MichD
Le 14/08/22 Í  12:16, MichD a écrit :
Le 14/08/22 Í  11:11, LaurentC a écrit :
=INDEX(TblOpérations[PRU];EQUIV(1;((TblOpérations[Titre]="Cisco
Systems")*(TblOpérations[DateOpé]<="19/07/2022")*(TblOpérations[PRU]<>""));0))

Bonjour,
Essaie comme ceci. Évidemment, je n'ai pas l'application pour effectuer
un test.
Dim D As Date
D = CDate("19/07/2022")
With Application
x = .Index(Range("TblOpérations[PRU]", .Match(1,
((Range("TblOpérations[Titre]") = _
        "Cisco Systems") * (Range("TblOpérations[DateOpé]") <= D) * _
        (Range("TblOpérations[PRU]") <> "")), 0)))
End With
La fonction de conversion Cdate() utilise le format court de la date
définie par défaut dans le panneau de configuration Windows.
La date que tu passes Í  la fonction doit être dans le même format que
celui de panneau de configuration.
En supposant que ton classeur se promène sur plusieurs ordinateurs
différents, il serait plus sécuritaire d'utiliser la fonction DateSerial
comme ceci : D = DateSerial(2022, 7, 19) . La formule sera indépendante
du format date par défaut du panneau de configuration de Windows.
MichD

Une autre alternative pour le format date,
Si ladite date est dans une cellule de la feuille de calcul dans un
format reconnu par Excel, utilise quelque chose du genre :
worksheets("Feuil").range("A5") ' Ce n'est qu'un exemple.
MichD
Avatar
LaurentC
Bonsoir
J'ai fait un truc immonde ... qui renvoie le résultat escompté, j'vais
faire avec :-(
Merci pour ton aide
@+Laurent
Sub TestPruTitreDate()
MsgBox PruTitreDate("Cisco Systems", "20/07/2022")
End Sub
Function PruTitreDate(LeTitre As String, LaDate As Date)
'renvoie le dernier PRU connu dans TblOpérations Í  cette date ou
antérieur
Dim DernièreLigne As Integer
Dim RangeTitre As Range
Dim RangePru As Range
Dim TempDouble As Double
'viellir LaDate au soir de LaDate Í  23:59:59
LaDate = Int(LaDate) + 1 - 1 / 24 / 60 / 60
'si il n'y a pas de Stock Í  cette date
If WorksheetFunction.SumIfs(Range("TblOpérations[Qté]"),
Range("TblOpérations[Titre]"), LeTitre,
Range("TblOpérations[DateOpé]"), "<=" & CDbl(LaDate)) = 0 Then
PruTitreDate = 0
Exit Function
End If
DernièreLigne Range("TblOpérations").ListObject.Range.Cells(1).End(xlDown).Row
'trouve le numéro de ligne de LaDate
TempDouble = Application.XLookup(CDbl(LaDate),
Range("TblOpérations[DateOpé]"), Range("TblOpérations[PRU]"), , -1,
1).Row
ChercheTitre:
'défini les Ranges
Set RangeTitre = Range("TblOpérations[Titre]").Offset(TempDouble -
Range("TblOpérations[#Headers]").Row - 1, 0).Resize(DernièreLigne -
TempDouble + 1, 1)
Set RangePru = Range("TblOpérations[PRU]").Offset(TempDouble -
Range("TblOpérations[#Headers]").Row - 1, 0).Resize(DernièreLigne -
TempDouble + 1, 1)
'trouve LeTitre et renvoi PRU de la ligne trouvée
TempDouble = Application.XLookup(LeTitre, RangeTitre, RangePru).Value
'si PRU = 0
If TempDouble = 0 Then
'prend cette ligne de titre trouvée + 1
TempDouble = Application.XLookup(LeTitre,
Range("TblOpérations[Titre]"), Range("TblOpérations[PRU]"), , -1,
1).Row + 1
'et cherche encore
GoTo ChercheTitre
Else
PruTitreDate = TempDouble
End If
Set RangeTitre = Nothing
Set RangePru = Nothing
End Function
Avatar
MichD
Le 14/08/22 Í  15:58, LaurentC a écrit :
Bonsoir
J'ai fait un truc immonde ... qui renvoie le résultat escompté, j'vais
faire avec :-(
Merci pour ton aide
@+Laurent
Sub TestPruTitreDate()
MsgBox PruTitreDate("Cisco Systems", "20/07/2022")
End Sub
Function PruTitreDate(LeTitre As String, LaDate As Date)
'renvoie le dernier PRU connu dans TblOpérations Í  cette date ou antérieur
Dim DernièreLigne As Integer
Dim RangeTitre As Range
Dim RangePru As Range
Dim TempDouble As Double
'viellir LaDate au soir de LaDate Í  23:59:59
LaDate = Int(LaDate) + 1 - 1 / 24 / 60 / 60
'si il n'y a pas de Stock Í  cette date
If WorksheetFunction.SumIfs(Range("TblOpérations[Qté]"),
Range("TblOpérations[Titre]"), LeTitre, Range("TblOpérations[DateOpé]"),
"<=" & CDbl(LaDate)) = 0 Then
   PruTitreDate = 0
   Exit Function
End If
DernièreLigne > Range("TblOpérations").ListObject.Range.Cells(1).End(xlDown).Row
'trouve le numéro de ligne de LaDate
TempDouble = Application.XLookup(CDbl(LaDate),
Range("TblOpérations[DateOpé]"), Range("TblOpérations[PRU]"), , -1, 1).Row
ChercheTitre:
'défini les Ranges
Set RangeTitre = Range("TblOpérations[Titre]").Offset(TempDouble -
Range("TblOpérations[#Headers]").Row - 1, 0).Resize(DernièreLigne -
TempDouble + 1, 1)
Set RangePru = Range("TblOpérations[PRU]").Offset(TempDouble -
Range("TblOpérations[#Headers]").Row - 1, 0).Resize(DernièreLigne -
TempDouble + 1, 1)
'trouve LeTitre et renvoi PRU de la ligne trouvée
TempDouble = Application.XLookup(LeTitre, RangeTitre, RangePru).Value
'si PRU = 0
If TempDouble = 0 Then
   'prend cette ligne de titre trouvée + 1
   TempDouble = Application.XLookup(LeTitre,
Range("TblOpérations[Titre]"), Range("TblOpérations[PRU]"), , -1, 1).Row
+ 1
   'et cherche encore
   GoTo ChercheTitre
Else
   PruTitreDate = TempDouble
End If
Set RangeTitre = Nothing
Set RangePru = Nothing
End Function

Bonjour,
Quelques remarques générales, un peu tatillonnes, je l'avoue!
A ) Í  moins qu'une date particulière contienne des heures, minutes ou
seconde, au lieu d'utiliser Cdbl(date), Clng(date) est suffisant.
B ) MsgBox PruTitreDate("Cisco Systems", "20/07/2022")
Peux-tu me dire si "03/01/2022" représente
A ) le 3 janvier 2022 au format français DD/MM/AA
OU
B ) le 3 mars 2022 au format américain. MM/DD/AA
Peu importe l'utilisateur, le paramètre LaDate As Date de la fonction
dans mon exemple va toujours utiliser le format défini dans le panneau
de configuration de Windows.
Dans ta procédure "TestPruTitreDate", tu aurais pu utiliser ceci :
Sub TestPruTitreDate()
Dim D As Date
'La saisie de la date est faite au format : année/Mois/Jour
'Ce format est compris par Excel et interpréter correctement
'peu importe le format défini dans le panneau de configuration
'de Windows.
D = DateValue("2022/07/12")
MsgBox Format(D, "DD/MM/YY") 'un petit test
MsgBox PruTitreDate("Cisco Systems", D)
End Sub
Pour trouver la dernière ligne d'un tableau, tu as aussi ceci :
With Range("TblOpérations")
S = .Row + .Rows.Count - 1
End With
La fonction "XLOOKUP" est une nouveauté d" "Office 365", cela veut dire
que je ne peux pas utiliser ton classeur dans la version Excel 2016... ;-))
MichD