Une difficulté avec Evaluate [Résolu]

Magic_Doctor

XLDnaute Barbatruc
Bonjour,

Pour tenter de résoudre un problème, je pense devoir passer dabord par la résolution de celui-ci.

Supposons que dans la cellule A1 il y a la valeur 20.

Si, dans une macro j'écris :
[A2] = [$A$1]

Sur la feuille, dans la cellule A2 apparaîtra le contenu de la cellule A1, autrement dit 20.

Dans ma macro j'écris maintenant :
Dim ad As String
ad = [A1].Address
[A2] = ad

Sur la feuille, dans la cellule A2 apparaîtra bien $A$1.

Si j'écris dans la macro :
Dim ad As String
ad = [A1].Address
[A2] = [ad]

Sur la feuille, dans la cellule A2 apparaîtra $A$1.

Comment faire en sorte, suivant ce raisonnement, qu'apparaisse le contenu de la cellule A1 (20) ?
Peut-être en glissant un "INDIRECT" quelque part...
Je bataille depuis un moment, mais n'ai rien trouvé.
 

job75

XLDnaute Barbatruc
Bonjour Magic_Doctor, salut VIARD, ODVJ,

Dans ton 3ème exemple ad est une variable VBA, inconnue dans la feuille de calcul, VBA ignore les crochets.

Pour la question posée :
Code:
Dim ad As String
ad = [A1].Address
[A2] = Evaluate(ad)
A+
 

Magic_Doctor

XLDnaute Barbatruc
Re,

Merci pour vos réponses.
J'ai retenu celle de job. Mais, en fait, ça ne résoud quand même pas mon problème.
Dans un tableau j'ai plusieurs colonnes.
La première colonne s'appellera "Colonne des abscisses"
La deuxième colonne s'appellera "Colonne de référence"
La troisième colonne s'appellera "Colonne de comparaison"

La colonne des abscisses est TOUJOURS la première colonne.
Les 2 autres colonnes peuvent se trouver n'importe où dans le tableau et peuvent être contiguës ou pas.

Dans une cellule (fucshia) il y a une liste déroulante où se trouvent tous les items de la 1ère colonne (abscisses).
À chaque fois que l'on choisit un item de cette liste, le tableau est tronqué. Seules les valeurs de la colonne des abscisses ∈ [0 ; item choisi] seront prises en compte. En somme, la hauteur du tableau est variable.

Le but de l'opération est de comparer les valeurs de la colonne de comparaison avec celles de la colonne de référence, en fait les deux parties supérieures de ces colonnes tronquées (à moins, bien sûr, que l'item choisi soit 100).

Ça marche très bien et, ma foi, c'est clair sur la PJ.

Mon problème commence maintenant.
Tout en bas du tableau, il y a une cellule (orange) qui indique le pourcentage de valeurs de la colonne de comparaison identiques à la colonne de référence.
La formule, donnant ce résultat, marche très bien.
On pourrait s'arrêter là ! Mais, pour le fun et rester jeune, je me suis dit : "Et si on transformait cette purge de formule en une fonction". Car, après tout, dans bien des cas, sans se prendre la tête, ça pourrait être pratique.
Très mauvaise idée ! Car là commença mon cauchemar et de nouvelles angoisses existentielles...

J'ai commencé par rédiger une macro qui marche ! Je n'en revenais pas... Mais la retranscrire en une fonction... ¡Coño! ça ne marche plus. Je pense comprendre pourquoi, même si ça n'est pas forcément très clair dans mon esprit.

1/ Macro :
VB:
Sub MacroCompareCol()

Dim haut As Integer, f, plage1 As Range, plage2 As Range, plage3 As Range, x1 As Byte, x2 As Byte

Set plage1 = Range("B6:B38") 'colonne des "abscisses"
Set plage2 = Range("C6:C38") 'colonne de référence
Set plage3 = Range("D6:D38") 'colonne que l'on compare à la colonne précédente

x1 = plage2.Column - plage1.Column 'écart en colonnes entre "plage1" & "plage2"
x2 = plage3.Column - plage1.Column 'écart en colonnes entre "plage1" & "plage3"
Set f = Application.WorksheetFunction
haut = f.Match([C2], plage1, 0) 'hauteur des colonnes (C2 est la cellule où se trouve une valeur faisant partie des abscisses)
Set plage2 = plage1.Offset(, x1).Resize(haut, 1) 'redimensionnement de la plage2 suivant C2 choisi
Set plage3 = plage1.Offset(, x2).Resize(haut, 1) 'redimensionnement de la plage3 suivant C2 choisi
plage2.Name = "plage2"
plage3.Name = "plage3"

[D43] = [SumProduct(N(plage3 = plage2))] / haut * 100

End Sub

2/ Fonction :
VB:
Function CompareCol(num As Double, plage1 As Range, plage2 As Range, plage3 As Range) As Double
'Renvoie le pourcentage de valeurs identiques entre 2 colonnes dont la hauteur peut être variable
'Magic_Doctor
'- num : un nombre appartenant obligatoirement à la colonne des "abscisses"
'- plage1 : l'ensemble de cellules constituant la colonne des "abscisses" (où se trouve "num")
'- plage2 : l'ensemble de cellules constituant la colonne de référence
'- plage3 : l'ensemble de cellules constituant la colonne que l'on compare à la colonne précédente

Dim haut As Integer, f, x1 As Byte, x2 As Byte

x1 = plage2.Column - plage1.Column 'écart en colonnes entre "plage1" & "plage2"
x2 = plage3.Column - plage1.Column 'écart en colonnes entre "plage1" & "plage3"
Set f = Application.WorksheetFunction
haut = f.Match(num, plage1, 0) 'hauteur des colonnes
Set plage2 = plage1.Offset(, x1).Resize(haut, 1) 'redimensionnement de la plage2 suivant "num" choisi
Set plage3 = plage1.Offset(, x2).Resize(haut, 1) 'redimensionnement de la plage3 suivant "num" choisi
plage2.Name = "plage2"
plage3.Name = "plage3"

CompareCol = [SumProduct(N(plage3 = plage2))] / haut * 100

End Function

Le problème vient du fait que l'on nomme 2 plages. Du reste, après avoir actionné la macro, on remarquera que "plage1" & "plage2" apparaissent dans la petite fenêtre en haut et à gauche.
Je ne pense pas qu'une fonction ait le "droit" de faire ça.
Alors, plein d'espoir, je me suis dit : "Nous allons, fastoche, contourner le problème !"... et, plein d'optimisme, foudroyé par l'inspiration, je me suis mis automatiquement à écrire en fin de macro :
CompareCol = [SumProduct(N(plage3.Address = plage2.address))]
Car si j'écris (en supposant, par exemple, qu'après avoir choisi un nouvel item que plage2 = C6:C32 et plage3 = D6:D32) : CompareCol = [SumProduct(N(D6:D32 = C6:C32))]... Putain, ça marche !

D'où, ce fil.

Bref, un grand merci à celui qui résoudra ce problème... hummm... allez... cornélien.
 

Pièces jointes

  • Exemple.xlsm
    26 KB · Affichages: 17
Dernière édition:

job75

XLDnaute Barbatruc
Re,

Pas trop le temps d'étudier ton fichier et ton problème mais mets-toi bien ceci dans la tête :

Il ne faut pas utiliser les crochets pour évaluer une expression contenant des variables VBA, il faut utiliser la fonction Evaluate en concaténant les expressions VBA dans la chaîne des caractères.

Evaluate évalue en effet toujours un texte.

A+
 

Staple1600

XLDnaute Barbatruc
Bonsoir le fil, le forum

@Magic_Doctor
J'ai commencé par rédiger une macro qui marche !
Tu n’étais pas seul sur ce coup là :rolleyes:
https://www.excel-downloads.com/threads/problème-pour-traduire-une-fonction-excel-en-vba-résolu.20021401/
Notamment sur le :Set f = Application.WorksheetFunction

Toujours sympathique d'être zappé par le demandeur ;)

NB: J'attends toujours tes observations sur la fonction que j'ai écris différemment et de savoir si elle fonctionne chez toi.
 

Magic_Doctor

XLDnaute Barbatruc
Re,

Effectivement, j'ai appris Set f = Application.WorksheetFunction dans l'une de tes routines et ça m'a plu. Mais, franchement, ça ne change pas grand chose au problème. En revanche, esthétiquement pour la lecture, c'est plus agréable et ça prend moins de place.
 

job75

XLDnaute Barbatruc
Re Magic_Doctor, JM,

Ton fichier en retour avec la fonction CompareCol en D43.

PS : Set f = Application.WorksheetFunction c'est capillotracté, justifiable si on utilise f plusieurs fois.

A+
 

Pièces jointes

  • Exemple(1).xlsm
    32.3 KB · Affichages: 21

Discussions similaires