Utilisation de dictionnaire dans une fonction personalisée

vgendron

XLDnaute Barbatruc
Hello

pour répondre à un autre fil
j'ai créé une fonction personalisée qui utilise un dictionnaire
le but étant de créer une liste sans doublon

Cette fonction est utilisée en cellule G42 des feuilles Fab XX
Elle donne bien le résultat escompté SAUF que cette fonction est utilisée sur plusieurs feuilles.. et lorsque je bascule d'une feuille à l'autre, le résultat affiché est celui de la feuille précédente...-->il faut donc revalider pour que le résultat se mette à jour..
j'ai bien pensé à application.volatile. mais je ne vois pas pourquoi ca ne fonctionne pas..
vous remarquerez qu'il y a une autre fonction ConcatSolo (colonne J) qui elle se met parfaitement à jour..

est ce le fait d'utiliser un dictionnaire?? ou me manque juste un petit rien qui fait toute la différence?
 

vgendron

XLDnaute Barbatruc
Salut PiereJean

j'avais mis un lien vers le fil.. mais comme le fichier a bougé depuis. le voici ici

pour expliquer son fonctionnemnet
dans la page de garde: les actions possibles
1) il crée un nouvel ingrédient en lui mettant des allergènes contenus ou pas
bouton ajouter ingrédient colle le tout dans la feuille ListeIngrédients
ensuite. possibilité de modifier un ingrédient existant (à part son nom)
2) nom de recette (D18) avec numéro (N18)
bouton créer nouvelle fiche:
--> vérifie dans la feuille répertoire que la recette n'existe pas déjà
--> copie colle le FAB modèle

c'est dans cette feuille (qui se retrouve donc autant de fois qu'il y a de recettes) que les fonctions personalisées sont présentes

Dans ces feuilles de recette, on selectionne les ingrédients parmis la liste de validaiton (Colonne A)
la fonction personnalisée ConcatSolo(ingrédient), va voir dans la "ListeIngrédients" pour récuperer les allergènes en colonne J
si on change d'ingrédient, la fonction se met à jour automatiquement (principe du Application.volatile)

en G42, la fonction ConcatTotal, récupère tous les ingrédients de la recette (colonne A) et va voir les allergènes: avec un dico, on en sort une liste sans doublon

forcément, une autre recette ne contient pas les memes ingrédients. donc pas les meme allergènes.

dans le fichier ci joint: Fab26.01: 4 allergenes "Sulfite- crustacé -soja-gluten
fab2602: sulfites
quand je passe de 2601 à 2602, la liste Sulfite- crustacé -soja-gluten apparait toujours à moins de revalider la fonction...
idem si je change d'ingrédient sur la feuille

j'ai contourné le pb en rajoutant des activsheeet.calculate à chaque évènemetn change ou selection_change;. mais ca me parait pas académique...

j'ai essayé avec une autre fonction "avectab" avec des tableaux plutot qu'un dico..
je pensais avoir résolu, mais.. meme combat..
 

Pièces jointes

  • Fiche recette Rev7.xls
    239.5 KB · Affichages: 32

job75

XLDnaute Barbatruc
Bonjour vgendron, Pierre, cathodique,

Dans un module standard quand on ne précise pas la feuille un Range s'applique à la feuille active.

Il est donc normal que toutes les fonctions ConcatTotal renvoient la même valeur.

Pour y remédier :
Code:
With Application.Caller.Parent
Set ListeIngrédients = .Range("A8:A" & .Range("A7").End(xlDown).Row) 'on récupère la liste des ingrédients de la feuille
End With
A+
 

job75

XLDnaute Barbatruc
Bonjour à tous,

Il faut savoir vgendron que la méthode Find prend beaucoup de temps.

Et la création du Dictionary aussi.

Perso j'écrirais la fonction comme ceci :
Code:
Function ConcatTotal$(Liste)
Application.Volatile
Static d As Object
Dim nlig&, ncol%, i&, x$, j&, k%
If d Is Nothing Then
  Set d = CreateObject("Scripting.Dictionary") 'création
Else
  d.RemoveAll 'RAZ, beaucoup plus rapide qu'une création
End If
Liste = Liste: Ing = [Ing]: Allerg = [Allergènes] 'matrices, plus rapide
nlig = UBound(Ing): ncol = UBound(Allerg, 2)
For i = 1 To UBound(Liste)
  x = Liste(i, 1)
  If x <> "" Then
    For j = 2 To nlig
      If Ing(j, 1) = x Then
        For k = 1 To ncol
          If Allerg(j, k) <> "" Then d(Allerg(1, k)) = ""
        Next k
        Exit For
      End If
    Next j
  End If
Next i
If d.Count Then ConcatTotal = Join(d.keys, "-")
End Function
Et bien sûr formule en G42 =ConcatTotal(A8:A22) - inutile d'utiliser SIERREUR.

Edit : si l'on veut trier les d.keys alphabétiquement utiliser la macro bien connue Quick sort.

A+
 
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 299
Messages
2 086 996
Membres
103 423
dernier inscrit
Guyom GIL