Vérifier l'existance de donnée dans un DB avant ajout
Bonjour à tous,
J'ai un fichier Excel qui contient (entre autres) deux "bases de données" d'ingrédients avec leur profil nutritionnel.
Je cherche a créer une feuille pour ajouter de nouveau ingrédient dans la liste et vérifie que le produit n'existe pas déjà avant ajout.
Sur cette feuille, figure un tableau à compléter et deux boutons pour ajouter les ingrédients selon la zone réglementaire (USA et Europe).
Sur chaque bouton est déjà associé un code pour copier les données ajoutées. Maintenant, je voudrais ajouter la vérification que l'ingrédient n'existe pas déjà.
Pour cela, il faut aller vérifier dans la première colonne du tableau de la feuille USA ou Europe si l'ingrédient existe déjà puis s'il n'existe pas exécuter la copie et s'il existe, afficher dans le tableau en dessous les données déjà présentes dans la base et mettre un message box "déjà existant".
Voilà le code que j'ai envisagé pour la partie Europe (sachant que ça sera la même chose pour les USA en ajustant a la feuille USA) mais ça bug dès le début :-(. Pourriez-vous m'aider svp?
Voici le code (dans le module 3) que j'ai tapé pour le moment et le fichier. Pour moment, je n'ai pas encore rattaché ce code au bouton, sur le bouton Europe, il n'y a que la fonction ajout pour le moment.
Je vous remercie par avance
Bastien
Sub recherche_ingredient_deja_existant_EU()
Dim Ingredient_list As Range
Dim Ingrdeient1 As Range
Dim Exist_EU As Range
Dim Ingredient_EU As Range
Dim RgnEurope As Range
Ingredient_EU = Sheets("adding new ingredients").Range("C9")
'Nom de l'ingrédient qui sera recherché dans la liste Europe
If Ingredient_EU > 0 Then
Ingredient1 = Sheets("Europe").Range("Tableau1[ingrédients]").Find(what:=Ingredient_EU, lookat:=xlWhole).Address
End If
'Si range C9 sur feuille Adding new ingredients rempli, Trouver l'ingrédient dans le tableau 1, colonne ingrédient sur la page Europe et stocker son adresse
If Ingredient1 Is Nothing Then
Sheets("Adding new ingredients").Range("europe").Copy
Set RngEurope = Sheets("Europe").ListObjects("Tableau1").ListRows.Add.Range
RngEurope.Resize(, 26).Value = Sheets("Adding new ingredients").Range("europe").Value
Sheets("Adding new ingredients").Range("europe").FormulaR1C1 = ""
'si Ingredient1 est vide, alors copie des donnée dans le tableau sur Europe.
Else
MsgBox ("Deja existant")
'Afficher un Message "Deja existant" si Ingredient1 ou Ingredient2 >0
If Ingredient1 > 0 Then
Exist_EU = Range(Ingredient1).Row
Exist_EU.Resize(, 26).Value = Sheets("adding new ingredients").Range("Exist_EU")
End If
'Si Ingredient1 >0 alors selectioner la ligne du tableau correspondant a l'ingrédient recherché sur la page Europe et coller seulement les 26 première cases
'Reporter la selection sur la plage Exist_EU dans la page adding new ingredients
End If
End Sub
Bonsoir,
essayez en ajoutant un "Set" devant votre ligne de recherche, en effet pour attribuer un Range à un autre il faut :
Set MaPlage = LaZone.Find....
@ bientôt
LouReeD
Bonsoir,
Merci pour votre retour
J'ai fait les corrections en me basant sur votre commentaire (enfin j'espère que c'est à ça que vous pensez).
J'ai aussi passé le "If Ingredient1 is Nothing" en "If Ingredient1 =0"
ça donne ça
Sub recherche_ingredient_deja_existant_EU()
Dim Ingredient_list As Range
Dim Ingrdeient1 As Range
Dim Exist_EU As Range
Dim Ingredient_EU As Range
Dim RgnEurope As Range
Set Ingredient_EU = Sheets("adding new ingredients").Range("C9")
'Nom de l'ingrédient qui sera recherché dans la liste Europe
If Ingredient_EU > 0 Then
Ingredient1 = Sheets("Europe").Range("Tableau1[ingrédients]").Find(what:=Ingredient_EU, lookat:=xlWhole).Address
End If
'Si range C9 sur feuille Adding new ingredients rempli, Trouver l'ingrédient dans le tableau 1, colonne ingrédient sur la page Europe et stocker son adresse
If Ingredient1 = 0 Then
Sheets("Adding new ingredients").Range("europe").Copy
Set RngEurope = Sheets("Europe").ListObjects("Tableau1").ListRows.Add.Range
RngEurope.Resize(, 26).Value = Sheets("Adding new ingredients").Range("europe").Value
Sheets("Adding new ingredients").Range("europe").FormulaR1C1 = ""
'si Ingredient1 est vide, alors copie des donnée dans le tableau sur Europe.
Else
MsgBox ("Deja existant")
'Afficher un Message "Deja existant" si Ingredient1 ou Ingredient2 >0
If Ingredient1 > 0 Then
Set Exist_EU = Range(Ingredient1).Row
Exist_EU.Resize(, 26).Value = Sheets("adding new ingredients").Range("Exist_EU")
End If
'Si Ingredient1 >0 alors selectioner la ligne du tableau correspondant a l'ingrédient recherché sur la page Europe et coller seulement les 26 première cases
'Reporter la selection sur la plage Exist_EU dans la page adding new ingredients
End If
End SubC'est mieux en effet :-). Maintenant, j'ai bien le message box qui apparait (j'ai mis un ingredient deja existant pour tester)
Par contre ça bug a ce niveau du programme en selectionnant ".Row" et en surligant "Sub recherche_ingredient_deja_existant_EU()"
Set Exist_EU = Range(Ingredient1).Row
Je suppose que ce n'est pas comme ça qu'il faut faire pour selectionner la ligne du tableau correspondant à la cellule trouvée et stocké dans Ingredient1. Par contre, je ne vois pas comment faire, pourriez vous m'aider?
En vous remerciant par avance
Bastien
PS : Question susidiaire : j'ai remarqué que si je mettais un "set" devant "Ingredient1 = Sheets("Europe").Range("Tableau1[ingrédients]").Find(what:=Ingredient_EU, lookat:=xlWhole).Address", ça faisiait bugger la macro.
Sauriez vous me dire pk il faut en mettre un devant "Ingredient_EU = Sheets("adding new ingredients").Range("C9")" et non devant "Ingredient1 = Sheets("Europe").Range("Tableau1[ingrédients]").Find(what:=Ingredient_EU, lookat:=xlWhole).Address"?
Un essai en "passant"
If Not Ingredient1 is nothing Then
Msgbox("Existe")
else
'ce que l'on fait s'il n'existe pas
' pour sélectionner la ligne de la cellule trouvée il suffit de prendre le Row du range
Ingredient1.row
endif@ bientôt
LouReeD
Re merci :-)
Heu je ne suis pas sur d'avoir compris ce dernier message et ce qu'il faut adapter
J'ai corrigé comme ceci, mais ça bug toujours au même niveau. Je me suis dit que le if dans le else était de trop et je l'ai supprimer mis peut être ai-je eu tort.
Else
MsgBox ("Deja existant")
'Afficher un Message "Deja existant" si Ingredient1>0
Set Exist_EU = Ingredient1.Row
Exist_EU.Resize(, 26).Value = Sheets("adding new ingredients").Range("Exist_EU")
'selectioner la ligne du tableau correspondant a l'ingrédient recherché sur la page Europe et coller seulement les 26 première cases
'Reporter la sélection sur la plage Exist_EU dans la page adding new ingredients
End IfSi je me suis pas trop planté dans mon code, la macro fait al chose suivante:
- si Ingredient 1 est vide alors on ajoute les données (après le if)
-Sinon (après le Else si j'ai bien compris), message "déjà existant" et report des donnés de l'ingrédient trouvé dans la BD (les 26 premières colonnes, correspondant aux données nutri de l'ingrédient, d'où le resize) dans la plage de cellule nommée Exist_EU sur la feuille adding new ingredients.
A priori, ça bug toujours sur la sélection de la ligne correspondant a la cellule trouvée :-(
Set Exist_EU = Ingredient1.RowMerci par avance pour votre aide et votre patience.
Bastien
Ingredient1.Row = un numéro entier correspondant à un numéro de ligne de la feuille Excel
Il y a donc incompatibilité de type
Votre code retouché :
Sub recherche_ingredient_deja_existant_EU()
Dim Ingredient_list As Range ' cellule
Dim Ingredient1 As Range ' cellule
Dim Exist_EU As Range ' cellule
'Dim Ingredient_EU As Range ' cellule ce n'est pas bon au vu du code qui suit
Dim Ingredient_EU As String ' c'ets mieux
Dim RgnEurope As Range 'cellule
' ici vous récupérez une donnée alphanumérique que vous "donnez" à un objet range, ce n'est pas bon
' d'où la définition en String vu dessus
'Nom de l'ingrédient qui sera recherché dans la liste Europe
Ingredient_EU = Sheets("adding new ingredients").Range("C9")
' si la cellule C9 (par l'intermédiaire de la variable Ingredient_EU) est différent de rien alors il y a une recherche à faire
If Ingredient_EU <> "" Then
' si vous faite une recherche de donnée pour retourner l'adresse de la cellule trouvée
' alors il faut que Ingredient1 soit en string, car le retour de Address est du type "$A$1"
' Ingredient1 = Sheets("Europe").Range("Tableau1[ingrédients]").Find(what:=Ingredient_EU, lookat:=xlWhole).Address
' donc on va plutôt attribue à Ingredient1 l'objet range du résultat de la recherche
Set Ingredient1 = Sheets("Europe").Range("Tableau1[ingrédients]").Find(what:=Ingredient_EU, lookat:=xlWhole)
' s'il n'y a rien à chercher alors on quite, non ?
Else
Exit Sub
End If
' si le résultat de la recherche"Non" rien, c'est à dire qu'on l'a trouvé dans le tableau
If Not Ingredient1 Is Nothing Then
MsgBox ("Deja existant")
' sinon on l'ajoute
Else
Sheets("Adding new ingredients").Range("europe").Copy
Set RngEurope = Sheets("Europe").ListObjects("Tableau1").ListRows.Add.Range
RngEurope.Resize(, 26).Value = Sheets("Adding new ingredients").Range("europe").Value
Sheets("Adding new ingredients").Range("europe").FormulaR1C1 = ""
'si Ingredient1 est vide, alors copie des donnée dans le tableau sur Europe.
End If
End SubEt regardez le votre, il y a des erreur de frappe au niveau des variables !
Afin d'éviter ce genre d'erreur je vous conseil de mettre en haut de vos page de code : Option explicit
comme cela s'il y a une faute de frappe, la variable ne sera pas explicitée dans les Dim et du coup VBA vous le dira lors du contrôle du code.
Regardez bien vous avez : Dim Ingrdeient1 As Range et plus loin : Ingredient1 = Sheets("Europe").Rang...
Ca n'a rien à voir...
@ bientôt
LouReeD
Hello
Merci beaucoup pour tout ces détails qui me font énormement progresser :-)
J'ai encore du mal avec la logique "If Not XXXX Is Nothing Then" mais ça va venir.
Puis-je vous demander une dernière fois un coup de main sur ce sujet s'il vous plait. Y a un petit truc qui manque encore mais je ne sais pas si c'est possible.
Le code tel qu'il est ci-dessus affiche un messagebox si l'ingredient existe deja.
Cela serait super de pouvoir "rapatrier" dans le tableau B13:AB15 de la feuille "adding new ingredient", dans le range C14:AB15 (je l'ai nommé Exist_EU) les données nutritionelles de l'ingredient trouvé dans le tableau de la feuille Europe. Dans le tableau sur le feuille Europe, les données nutrionelles sont contenue dans les 26 premières colonnes du tableau.
Donc, si j'ai bien compris, il va falloir ajouter du code a ce niveau la, entre le If not et le ELse. Avant le MsBox je dirait.
' si le résultat de la recherche"Non" rien, c'est à dire qu'on l'a trouvé dans le tableau
If Not Ingredient1 Is Nothing Then
MsgBox ("Deja existant")
' sinon on l'ajoute
ElseJ'avoue ne pas trop savoir comment faire. Je me suis basé sur l'un des messages précédents pour mettre toute la ligne de la cellule trouvé dans un variable (en esperant avoir bien compris) et j'ai essayer de la redimentionner ce range aux 26 premières cellules puis de l'applique sur le Range Exist-EU de la page Adding new ingredients.
' pour sélectionner la ligne de la cellule trouvée il suffit de prendre le Row du range
Ingredient1.row
Et du coup, j'ai tenté le code suivant mais ça ne passe pas. J'ai toujours ce message erreur de compilation comme décrit precedement.
Set Exist_EU = Ingredient1.Row
'selectioner la ligne du tableau correspondant au range ingredient1 recherché sur la page Europe
Exist_EU.Resize(, 26).Value = Sheets("adding new ingredients").Range("Exist_EU")
'Reporter dans le range "Exist_EU" les 26 première cases du range Exist_EUMerci par avance pour votre aide
Bastien