Création message erreur pour mauvais chemin référé à une cel
je vais m'efforcer d'être clair pour vous présenter ma question.
Ci-joint trois fichiers d'exemple. Le but:
Un fichier Maître (MASTER), utilisé par la direction d'une association, récupère des données de ses employés (ici Gédéon et Léonie) dans des classeurs fermés.
Pour cela, la direction ouvre le fichier MASTER et procède en deux étapes:
- Au début de chaque année, elle clique sur le bouton"Choisir fichier x" et "sélectionne" tout d'abord le fichier de chaque employé: en réalité, une macro fait seulement apparaitre le chemin d'accès dans les cellules D2(pour le fichier de Gédéon) et D22 (pour celui de Léonnie).
- Elle clique ensuite (dès que besoin d'importer des données d'un employé), sur le bouton importer les données. La macro associée vient alors copier-coller les données des employés grâce au chemin d'accès apparaissant dans D2 ou D22.
NOTE IMPORTANTE: je souhaite que la macro une fois terminée continue à se référer aux cellules D2 et D22 pour trouver le chemin d'accès plutôt que d'écrire dans la macro des chemins d'accès qui resteraient figés année après année: tout simplement parce que chaque nouvelle année la direction va dupliquer le dossier de base ASSO2017 pour créer un ASSO2018, et attribueront tout simplement les nouveaux chemins d'accès (car ils auront changé avec le duplicata de dossier). C'est plus simple pour eux....
Mes questions sont les suivantes:
1/ Pour l'instant, lorsque aucun fichier n'a été "sélectionné" préalablement[/b], un message d'erreur Microsoft apparait lorsqu'on clique sur le bouton "importer données" [b]. Pouvez vous m'aider à inclure dans mon code, un message d'erreur qui apparait si la cellule D2 (ou D22 pour l'autre fichier) est vide ou qu'il s'agit d'un document non-formaté .xls lorsqu'on presse le bouton "Importer données". Du type: "Fichier absent ou non reconnu: sélectionnez un fichier valide".
2/ Moins important mais si vous savez...Je souhaiterai à terme que les fichiers employés ait un mot de passe (ce qui reste simple). Mais, pouvez vous m'aider à faire en sorte que la macro de MASTER accède tout de même aux fichiers s'ils ont un mot de passe, sans l'écrire à la main, en allant chercher le mot de passe écrit dans le fichier Master en cellule C6 (ou C26 pour Léonie)? (je sais ça parait bizarre d'avoir les mots de passe dans le fichier général mais c'est une stratégie pour rassurer les collègues
Je place mon code si dessous au besoin et vous remercie d'avance pour votre aide
Remerciements.
Théophile
Sub ChercherfichierP1()
myFile1 = Application.GetOpenFilename(, , "Chercher fichier")
ThisWorkbook.Sheets("COCO").Range("d2") = myFile1
End Sub
Sub PullClosedDataP1()
Dim filePath1 As String
Dim SourceWb1 As Workbook
Dim TargetWb As Workbook
Set TargetWb = ActiveWorkbook
filePath1 = TargetWb.Sheets("COCO").Range("D2").Value
Set SourceWb1 = Workbooks.Open(filePath1)
SourceWb1.Sheets("NUNU").Range("A1:J14").Copy Destination:=TargetWb.Sheets("COCO").Range("D4:M17")
SourceWb1.Close
MsgBox "Données mises à jour!"
End Sub
Bonsoir,
Il faut apprendre à mettre le code que tu cites dans un post sous balises Code (bouton Code au-dessus de la fenêtre de rédaction).
Et aussi le cas échéant à l'indenter, de façon qu'il soit parfaitement lisible et interprétable sans perte de temps.
filePath1 = TargetWb.Sheets("COCO").Range("D2").ValueCeci me choque ! Tu ne vas pas me dire que tu fais une macro pour chaque cellule de ta liste !!!
Set TargetWb = ActiveWorkbookCeci est complètement inutile !
Pour ton message tu places une instruction conditionnelle avant d'ouvrir ton classeur :
If filePath1 = "" then
MsgBox "Nom et chemin de fichier manquant !", vbCritical, "Erreur"
Exit Sub
End IfCeci :
Set SourceWb1 = Workbooks.Open(filePath1)
SourceWb1.Sheets("NUNU").Range("A1:J14").Copy Destination:=TargetWb.Sheets("COCO").Range("D4:M17")
SourceWb1.Closeserait efficacement remplacé par :
With Workbooks.Open(filePath1)
ThisWorkbook.Sheets("COCO").Range("D4:M17").Value = .Sheets("NUNU").Range("A1:J14").Value
.Close False
End WithTu économises ainsi une seconde variable : le With a autant d'efficacité, sinon plus, qu'un variable, d'une part. Et d'autre part tu économises un copier-coller au profit d'une affectation directe, plus rapide !
Si un mot de passe est requis à l'ouverture du classeur, tu l'indiqueras dans ta commande d'ouverture :
........Open(filePath1, Password:= mdp)mdp étant la variable contenant le mot de passe.
Cordialement.
Merci beaucoup MFerrant.
Grace à vous j'ai trouvé les réponses à mes questions.
Rebonjour MFerrand,
J’essaie d'intégrer l'action suivante dans la procédure que vous m'avez conseillé, mais je sèche misérablement.
OBJECTIF: Une cellule du présent classeur, donne une donnée qui sera recherchée dans le classeur qu'on ouvre en arrière plan, de sorte à obtenir les coordonnées de la cellule qui la contient là bas et de pouvoir aller chercher là bas et assigner ici tout ce qui est sur le même numéro de ligne là bas). La procédure fonctionne lorsqu'elle est isolée mais je n'arrive pas à l'intégrer avec le With que vous m'avez suggérer de placer (comme si je n'arrivais pas à placer le SET dans le WITH)
Voici la procédure isolée:
'Ouverture GESTION ASSOCIATIVE puis attribution aux cellules du fichier PRO des valeurs du fichier ASSO
With Workbooks.Open(Chemin)
'Importation tarifs associatifs
ThisWorkbook.Sheets("SYSTEM").Range("C23:M23").Value = .Sheets("ConfigurationGénérale").Range("D17:N17").Value
'Importation pourcentage de prélévements associatifs sur action
ThisWorkbook.Sheets("SYSTEM").Range("B10:M10").Value = .Sheets("SYSTEMG").Range("C22:N22").Value
'Localisation d'une cellule (définie dans ThisWorkbookà à l'intérieur de SourceWb et copies des varibales accolées
Set LOCATE = .Sheets("SYSTEMG").Range("A26:A40").FIND.ActiveWorkbook.Sheets("Configuration").Range("G2"))
Linenumber = LOCATE.Row
ThisWorkbook.Sheets("SYSTEM").Range("B11:M11").Value = .Sheets("SYSTEMG").Range("C" & Linenumber, "G" & Linenumber).Value
.Close False
End WithVoici comme j'ai tenté de l'inclure dans ce que vous m'avez conseillé:
'Ouverture GESTION ASSOCIATIVE puis attribution aux cellules du fichier PRO des valeurs du fichier ASSO
With Workbooks.Open(Chemin)
'Importation tarifs associatifs
ThisWorkbook.Sheets("SYSTEM").Range("C23:M23").Value = .Sheets("ConfigurationGénérale").Range("D17:N17").Value
'Importation pourcentage de prélévements associatifs sur action
ThisWorkbook.Sheets("SYSTEM").Range("B10:M10").Value = .Sheets("SYSTEMG").Range("C22:N22").Value
'Localisation d'une cellule (définie dans ThisWorkbookà à l'intérieur de SourceWb et copies des varibales accolées
Set LOCATE = .Sheets("SYSTEMG").Range("A26:A40").FIND.ActiveWorkbook.Sheets("Configuration").Range("G2"))
Linenumber = LOCATE.Row
ThisWorkbook.Sheets("SYSTEM").Range("B11:M11").Value = .Sheets("SYSTEMG").Range("C" & Linenumber, "G" & Linenumber).Value
.Close False
End WithAuriez vous quelques indices?
Merci.
Bonjour,
Ceci :
Set LOCATE = .Sheets("SYSTEMG").Range("A26:A40").FIND.ActiveWorkbook.Sheets("Configuration").Range("G2"))a une syntaxe incorrecte ! Revoir syntaxe de la méthode Find...
- le code est-il bien copié d'un module ? On ne voit pas pourquoi FIND et non Find ! ?
- le classeur actif est celui qui vient d'être ouvert, ce qui paraît contradictoire avec l'objectif... ?
Linenumber = LOCATE.RowIl est toujours judicieux de tester préalablement si la recherche a abouti [If Not LOCATE Is Nothing Then...]
- par ailleurs, les colonnes étant connues on pouvait opérer directement à partir de LOCATE (avec .Offset...)
[Mais si tu me dis que la méthode Find aboutit avec la syntaxe utilisée, j'en serais particulièrement surpris !
ThisWorkbook.Sheets("SYSTEM").Range("B11:M11").Value = .Sheets("SYSTEMG").Range("C" & Linenumber, "G" & Linenumber).ValueTu affectes les valeurs d'une plage de 5 cellules en ligne à une plage à une plage de 12 cellules, ce n'est pas cohérent !
Cordialement.
J'ai donc fait les corrections, mais rien n'y fait.
Ma Msgbox m'annonce bien que la variable est vide.
'Ouverture GESTION ASSOCIATIVE puis attribution aux cellules du fichier PRO des valeurs du fichier ASSO
With Workbooks.Open(Chemin)
'Importation tarifs associatifs
ThisWorkbook.Sheets("SYSTEM").Range("C23:M23").Value = .Sheets("ConfigurationGénérale").Range("D17:N17").Value
'Importation pourcentage de prélévements associatifs sur action
ThisWorkbook.Sheets("SYSTEM").Range("B10:M10").Value = .Sheets("SYSTEMG").Range("C22:N22").Value
'Localisation d'une cellule (définie dans ThisWorkbookà à l'intérieur de SourceWb et copies des varibales accolées
Set LOCATED = .Sheets("SYSTEMG").Range("A26:A40").FIND(CIBLE)
If LOCATED Is Nothing Then
MsgBox "Problème de programmation: variable vide"
End If
NB = LOCATED.Row
MsgBox NB
.Close False
End With
Pourtant mon code de référence qui fonctionne est le suivant:
Sub TEST4()
'Variables de recherche dans le documents cible
Dim LOCATE As Range
Dim NB As Integer
Dim CIBLE As String
'Attribution de valeur
CIBLE = Range("F6")
'Attribution numéro de ligne
With Workbooks("TEST.xlsm")
Set LOCATE = .Sheets("Feuil1").Range("A1:A25").Find(CIBLE)
NB = LOCATE.Row
MsgBox NB
'Copy
ThisWorkbook.Sheets("CUCU").Range("F10:J20").Value = Workbooks("TEST.xlsm").Sheets("Feuil1").Range("C" & NB, "G" & NB).Value
End With
End SubJe suis perdu là...
Explique-moi une bonne fois comment il se fait que FIND se trouve en majuscules ! alors que VBA le reduit automatiquement à Find ?
Ta proc. étant incomplète, on ne voit pas les déclarations de variables, ni leur initialisation !
Eh bien écoute je ne comprends pas non plus pourquoi FIND se met en majuscule et n'attribue aucune valeur à la variable.Je te mets le code complet...(C'est sympa de regarder en tout cas merci. J'espsère que je pourrais bientôt en faire de même pour les novices
Function TestClasseurOuvert(strClass As String) As Boolean
' Tester si le classeur est ouvert ou pas
Dim intX As Integer
TestClasseurOuvert = False
On Error Resume Next
intX = FreeFile()
Open strClass For Input Lock Read As #intX
Close intX
If Err.Number = 0 Then TestClasseurOuvert = False
If Err.Number = 70 Then TestClasseurOuvert = True
On Error GoTo 0
End Function
Sub Importerparamètres()
'Déclaration des variables
Dim TargetWb As Workbook
Dim SourceWb As Workbook
Dim Chemin As String
'Variables de recherche dans le documents cible
Dim LOCATED As Object
Dim NB As Integer
Dim CIBLE As String
'Attribution de valeurs: ici pour les changer!
Set TargetWb = ThisWorkbook
Chemin = TargetWb.Sheets("SYSTEM").Range("E5").Value
CIBLE = ThisWorkbook.Sheets("Configuration").Range("G2")
Debug.Print CIBLE
'Désactivation rafraichissement écran
Application.ScreenUpdating = False
'Véricifcation classeur déjà ouvert"
If TestClasseurOuvert(Chemin) = True Then
MsgBox "Veuillez d'abord enregistrer puis fermer le fichier GESTION ASSOCIATIVE" & " " & ActiveWorkbook.Sheets("Configuration").Range("C2")
Exit Sub
End If
'Ouverture GESTION ASSOCIATIVE puis attribution aux cellules du fichier PRO des valeurs du fichier ASSO
With Workbooks.Open(Chemin)
'Importation tarifs associatifs
ThisWorkbook.Sheets("SYSTEM").Range("C23:M23").Value = .Sheets("ConfigurationGénérale").Range("D17:N17").Value
'Importation pourcentage de prélévements associatifs sur action
ThisWorkbook.Sheets("SYSTEM").Range("B10:M10").Value = .Sheets("SYSTEMG").Range("C22:N22").Value
'Localisation d'une cellule (définie dans ThisWorkbookà à l'intérieur de SourceWb et copies des varibales accolées
SetLOCATED = .Sheets("SYSTEMG").Range("A26:A40").FIND(CIBLE)
If LOCATED Is Nothing Then
MsgBox "Problème de programmation: variable vide"
End If
NB = LOCATED.Row
MsgBox NB
.Close SaveChanges:=False
End With
'Message final et rafraichissement d'écran
MsgBox "Données mises à jour!"
Application.ScreenUpdating = True
End Sub.Je te mets le code complet...
Tu es sûr !
Bon ! la méthode me paraît curieuse ! Pas tant la fonction assez inhabituelle... mais je suppose que celui qui l'a établie savait ce qu'il faisait (je ne suis pas coutumier de ce type de manip. et vérifier qu'ouvrir ainsi un fichier déjà ouvert dans son application déclenche une erreur en le fermant me prendra un peu trop de temps, mais comme ce n'est pas sur ce point que porte le problème, cela doit donc fonctionner). Ce qui est curieux c'est de tester si le fichier est ouvert afin de le faire fermer manuellement dans ce cas. Et s'il n'est pas ouvert, on l'ouvre...
Je voudrais bien qu'on m'explique le pourquoi de la chose
Le problème porte sur FIND... En passant si je copie ton code dans un module le FIND devient immédiatement Find, ce qui ne m'explique toujours pas pourquoi chez toi ce serait FIND !
Il faut donc savoir ce que contient la plage de recherche (A26:A40) et quelle est la valeur cherchée, soit CIBLE, soit ce que contient la cellule Configuration!G2 ?
Salut MFerrand,
eh bien j'ai trouvé.
Figure toi que la fonction find buguait lorsqu'elle allait chercher la valeur recherchée (ici ALP) parmi une plage de cellule contenant en fait des résultats de formule.
Soit dans une colonne contenant TMM, ALP et LD par exemple, chacune était copié d'un endroit où sont définis ces termes, et cela donne en fait sur la feuille:
TMM (qui vient en fait de =feuil1!A1)
ALP (qui vient en fait de =feuil1!A2)
LD (qui vient en fait de =feuil1!A3)
Sais tu au passage comment j pourrais dire à la fonction find de chercher que dans les valeurs du range???
J'ai essayé:
Range("A1:A3").value.Find(ALP) mais ça ne fonctionne pas.
Enfin, le FIND en majuscule était tout simplement l'écriture affichée sur mon mac
Merci profondément pour ton aide!
J'avais déjà conseillé, je crois, de revoir la syntaxe de Find !
Il te faut utiliser les 3e (et le cas échéant 4e) arguments de la méthode :
.......Find(CIBLE, , xlValues, xlWhole)Le 3e argument peut prendre les valeurs : xlValues, xlFormulas ou xlComments.
Tu essaies avec xlValues, si ça ne fonctionne pas tu essaies avec xlFormulas...
En 4e, c'est xlWhole (ta recherche concerne le contenu total de la cellule), ou xlPart (ta recherche concerne une partie du contenu...)
Cordialement.
J'ai trouvé!
(lookin:= xlValues)