Problème de liaison entre workbooks dans une macro
Résolu
timgvz
Messages postés
14
Date d'inscription
Statut
Membre
Dernière intervention
-
timgvz Messages postés 14 Date d'inscription Statut Membre Dernière intervention -
timgvz Messages postés 14 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
J’aimerais créer un tableau qui se constitue au fur et à mesure du temps à partir de certaines informations énoncées dans différents formulaires (qui sont sous formes de tableaux excel , cependant il n’y a que 2 ébauches de document-type, seules les valeurs diffèrent dans les formulaires).
Pour cela j’ai pensé à faire un code VBA avec un bouton clic qui, me remplirait mon tableau en fonction du formulaire que je souhaite retranscrire. En revanche, même si le tableau et les formulaires sont dans le même répertoire, je n’arrive pas à faire le lien entre le tableau et le formulaire un des formulaires. En effet, comme il faut que je sois capable de changer facilement de formulaire, je veux passer par une variable qui soit le nom du formulaire, mais cela ne marche pas.
Voilà une partie de mon code (attention, mon faible niveau de débutant pique les yeux) :
C'est le type de ligne Range("blabla" & no_ligne) = [Source]Sheet1!Bblabla qui me renvoie une erreur.
Nb : Il y a certainement beaucoup d’autres problèmes, n’hésitez pas à me les expliciter (et à me casser les dents).
Merci d’avance.
J’aimerais créer un tableau qui se constitue au fur et à mesure du temps à partir de certaines informations énoncées dans différents formulaires (qui sont sous formes de tableaux excel , cependant il n’y a que 2 ébauches de document-type, seules les valeurs diffèrent dans les formulaires).
Pour cela j’ai pensé à faire un code VBA avec un bouton clic qui, me remplirait mon tableau en fonction du formulaire que je souhaite retranscrire. En revanche, même si le tableau et les formulaires sont dans le même répertoire, je n’arrive pas à faire le lien entre le tableau et le formulaire un des formulaires. En effet, comme il faut que je sois capable de changer facilement de formulaire, je veux passer par une variable qui soit le nom du formulaire, mais cela ne marche pas.
Voilà une partie de mon code (attention, mon faible niveau de débutant pique les yeux) :
Sub Transcription() Dim Source As Workbook, no_ligne As Integer Set Source = Range("T2") If Source.Sheets("Sheet1").Range("A8") = "Currency" Then no_ligne = 1 If IsEmpty(Cells(no_ligne, 1)) Then Range("A" & no_ligne) = [Source]Sheet1!B6 Range("C" & no_ligne) = [Source]Sheet1!B4 End If Else no_ligne = no_ligne + 1 Else If IsEmpty(Cells(no_ligne, 1)) Then Range("A" & no_ligne) = [Source]Sheet1!B4 Range("D" & no_ligne) = [Source]Sheet1!B2 Range("E" & no_ligne) = "ESC" Range("G" & no_ligne) = [Source]Sheet1!B5 Range("H" & no_ligne) = [Source]Sheet1!B6 Range("I" & no_ligne) = [Source]Sheet1!B13 If IsEmpty(Cells(no_ligne, 2)) Then Range("K" & no_ligne) = [Source]Sheet1!B17 Else Range("K" & no_ligne) = [Source]Sheet1!B16 End If End If Else no_ligne = no_ligne + 1 End If End Sub
C'est le type de ligne Range("blabla" & no_ligne) = [Source]Sheet1!Bblabla qui me renvoie une erreur.
Nb : Il y a certainement beaucoup d’autres problèmes, n’hésitez pas à me les expliciter (et à me casser les dents).
Merci d’avance.
A voir également:
- Problème de liaison entre workbooks dans une macro
- Telecharger macro convertir chiffre en lettre excel - Télécharger - Tableur
- Jitbit macro recorder - Télécharger - Confidentialité
- Télécharger macro convertir chiffre en lettre excel - Télécharger - Tableur
- Excel récupérer couleur cellule sans macro ✓ - Forum Bureautique
- Acheminé sur une liaison internationale - Forum Réseau
3 réponses
Bonjour Tim, bonjour le forum,
En effet ça pique un peu... Le plus dur c'est de t'expliquer des choses que je ne suis pas sûr d'avoir comprises...
• Tu déclares la variable Source comme un classeur.
Tu la définis avec Set Source = Range("T2") . C'est pas correct !
- déjà il te faut spécifier l'onglet pour éviter toute confusion :
Set Source = Sheets("Feuil1").Range("T2") à adapter...
- Ensuite il faut que T2 contienne :
- soit le nom complet (avec le chemin et l'extension) si le classeur source n'est pas ouvert avec le code :
Set Source = Workbooks.Open(Sheets("Feuil1").Range("T2").Value)
- soit uniquement le nom avec l'extension si le classeur est déjà ouvert et le code :
Set Source = Workbooks(Sheets("Feuil1").Range("T2").Value)
• Pourquoi d'un coté Range("A" & no_ligne) et de l'autre [Source]Sheet1!B6 ? C'est pas correct
D'abord spécifier l'onglet (tu adapteras)
Sheets("Feuil1").Range("A" & no_ligne) = Source.Sheets("Sheet1").Range("B6")
• Pour moi tes If, End If, Else ne sont pas correct. Tu as des Else qui se suivent !?
La syntaxe correcte est du type :
ou
Essaie de revoir ton code ...
À plus,
ThauTheme
En effet ça pique un peu... Le plus dur c'est de t'expliquer des choses que je ne suis pas sûr d'avoir comprises...
• Tu déclares la variable Source comme un classeur.
Tu la définis avec Set Source = Range("T2") . C'est pas correct !
- déjà il te faut spécifier l'onglet pour éviter toute confusion :
Set Source = Sheets("Feuil1").Range("T2") à adapter...
- Ensuite il faut que T2 contienne :
- soit le nom complet (avec le chemin et l'extension) si le classeur source n'est pas ouvert avec le code :
Set Source = Workbooks.Open(Sheets("Feuil1").Range("T2").Value)
- soit uniquement le nom avec l'extension si le classeur est déjà ouvert et le code :
Set Source = Workbooks(Sheets("Feuil1").Range("T2").Value)
• Pourquoi d'un coté Range("A" & no_ligne) et de l'autre [Source]Sheet1!B6 ? C'est pas correct
D'abord spécifier l'onglet (tu adapteras)
Sheets("Feuil1").Range("A" & no_ligne) = Source.Sheets("Sheet1").Range("B6")
• Pour moi tes If, End If, Else ne sont pas correct. Tu as des Else qui se suivent !?
La syntaxe correcte est du type :
If .... Then 'code si condition est [Vrai] Else 'code si condition est [Faux] End If
ou
If .... Then 'code si condition 1 est [Vrai] ElseIf .... Then 'code si condition 2 est [Vrai] ElseIf .... Then 'code si condition 3 est [Vrai] End If
Essaie de revoir ton code ...
À plus,
ThauTheme
Bonjour Tim, bonjour le forum,
J'ai téléchargé les trois fichiers et les ai sauvés sur mon disques dur.
Tout ça manque beaucoup trop de rigueur !... Le langage VBA, comme n'importe quel autre d'ailleurs, est précis et plante à la moindre erreur.
• la ligne :
va planter puisque l'onglet (dans la pièce jointe fournie : test Tableau.xlsm) ne se nomme pas tab1 mais Sheet1...
• Une fois cette modification faite, le fichier source s'ouvre. Il est donc actif.
La ligne :
manque de précision puisqu'elle ne fait pas référence au classeur actif mais au fichier : test Tableau.xlsm ! Il faut le spécifier
• Visiblement le même code va ouvrir différents fichiers. Il faut qu'ils aient tous la même structure sinon il va planter. Le premier onglet du fichier Doc-type-Escompte.xlsx s'appelle : Sheet1 alors que celui du fichier : Doc-type-Confirmation.xlsx s'appelle : Feuil1. J'ai donc fait en sorte, dans le code ci-dessous, d'utiliser le premier onglet de chaque fichier. Ça t'évite d'avoir à les renommer de manière uniforme mais ça risque de planter si dans un fichier l'onglet à traiter n'est pas le premier !...
• Pour le reste j'ai refait le code, ça récupère bien des données du classeur source et les colle dans la première ligne vide du classeur destination mais elles n'ont rien à voir avec les lignes au dessus !... Revoie tout ça avec plus de rigueur !
Le code :
J'ai téléchargé les trois fichiers et les ai sauvés sur mon disques dur.
Tout ça manque beaucoup trop de rigueur !... Le langage VBA, comme n'importe quel autre d'ailleurs, est précis et plante à la moindre erreur.
• la ligne :
Set Source = Workbooks.Open(Sheets("tab1").Range("U6").Value)
va planter puisque l'onglet (dans la pièce jointe fournie : test Tableau.xlsm) ne se nomme pas tab1 mais Sheet1...
• Une fois cette modification faite, le fichier source s'ouvre. Il est donc actif.
La ligne :
no_ligne = Sheets("tab1").Range("A" & Application.Rows.Count).End(xlUp).Row + 1
manque de précision puisqu'elle ne fait pas référence au classeur actif mais au fichier : test Tableau.xlsm ! Il faut le spécifier
• Visiblement le même code va ouvrir différents fichiers. Il faut qu'ils aient tous la même structure sinon il va planter. Le premier onglet du fichier Doc-type-Escompte.xlsx s'appelle : Sheet1 alors que celui du fichier : Doc-type-Confirmation.xlsx s'appelle : Feuil1. J'ai donc fait en sorte, dans le code ci-dessous, d'utiliser le premier onglet de chaque fichier. Ça t'évite d'avoir à les renommer de manière uniforme mais ça risque de planter si dans un fichier l'onglet à traiter n'est pas le premier !...
• Pour le reste j'ai refait le code, ça récupère bien des données du classeur source et les colle dans la première ligne vide du classeur destination mais elles n'ont rien à voir avec les lignes au dessus !... Revoie tout ça avec plus de rigueur !
Le code :
Sub Transcription() Dim CD As Workbook 'déclare la variable CD (Classeur Destination) Dim OD As Worksheet 'déclare la variable OD (Onglet Destination) Dim CS As Workbook 'déclare la variable CS (Classeur Source) Dim OS As Worksheet 'déclare la variable OS (Onglet Source) Dim no_ligne As Integer 'déclare la variable no_ligne Set CD = ThisWorkbook 'définit le classeur destination CD Set OD = CD.Worksheets("Sheet1") 'définit l'onglet destination CD (à adapter éventuellement0 Set CS = Workbooks.Open(OD.Range("U6").Value) 'ouvre le classeur source et le définit (à condition que U6 contienne le nom complet avecchemin d'accès et extention !) Set OS = CS.Worksheets(1) 'définit l'onglet source (le premier onglet du classeur source quel que soit son nom) no_ligne = OD.Range("A" & Application.Rows.Count).End(xlUp).Row + 1 'définit la variale no_ligne (première ligne vide dela colonne A de l'onget OD) If OS.Range("A5") = "Transaction Number" Then 'condition 1 : si la cellule A5 de l'onglet source est égale à "Transaction Number" OD.Range("A" & no_ligne) = OS.Range("B4") 'récupère dans la cellule ligne no_ligne colonne A de l'onglet destination, la valeur de la cellule B4 de l'ongelt source OD.Range("B" & no_ligne) = OS.Range("B4") 'récupère dans la cellule ligne no_ligne colonne B de l'onglet destination, la valeur de la cellule B4 de l'ongelt source OD.Range("E" & no_ligne) = OS.Range("B5") 'récupère dans la cellule ligne no_ligne colonne E de l'onglet destination, la valeur de la cellule B5 de l'ongelt source OD.Range("F" & no_ligne) = OS.Range("B2") 'récupère dans la cellule ligne no_ligne colonne F de l'onglet destination, la valeur de la cellule B2 de l'ongelt source OD.Range("G" & no_ligne) = "LCD" 'écrit "LCD" dans la cellule ligne no_ligne colonne G de l'onglet destination OD.Range("I" & no_ligne) = OS.Range("B8") 'récupère dans la cellule ligne no_ligne colonne I de l'onglet destination, la valeur de la cellule B8 de l'ongelt source OD.Range("J" & no_ligne) = OS.Range("B7") 'récupère dans la cellule ligne no_ligne colonne J de l'onglet destination, la valeur de la cellule B7 de l'ongelt source OD.Range("K" & no_ligne) = OS.Range("B9") 'récupère dans la cellule ligne no_ligne colonne K de l'onglet destination, la valeur de la cellule B9 de l'ongelt source OD.Range("L" & no_ligne) = OS.Range("B20") 'récupère dans la cellule ligne no_ligne colonne L de l'onglet destination, la valeur de la cellule B20 de l'ongelt source OD.Range("O" & no_ligne) = OS.Range("B3") 'récupère dans la cellule ligne no_ligne colonne O de l'onglet destination, la valeur de la cellule B3 de l'ongelt source OD.Range("Q" & no_ligne) = OS.Range("B6") 'récupère dans la cellule ligne no_ligne colonne Q de l'onglet destination, la valeur de la cellule B6 de l'ongelt source OD.Range("R" & no_ligne) = OS.Range("B10") 'récupère dans la cellule ligne no_ligne colonne R de l'onglet destination, la valeur de la cellule B10 de l'ongelt source Else 'sinon OD.Range("A" & no_ligne) = OS.Range("B4") 'récupère dans la cellule ligne no_ligne colonne A de l'onglet destination, la valeur de la cellule B4 de l'ongelt source OD.Range("F" & no_ligne) = OS.Range("B2") 'récupère dans la cellule ligne no_ligne colonne F de l'onglet destination, la valeur de la cellule B2 de l'ongelt source OD.Range("G" & no_ligne) = "ESC" 'écrit "LCD" dans la cellule ligne no_ligne colonne G de l'onglet destination OD.Range("I" & no_ligne) = OS.Range("B5") 'récupère dans la cellule ligne no_ligne colonne I de l'onglet destination, la valeur de la cellule B5 de l'ongelt source OD.Range("J" & no_ligne) = OS.Range("B6") 'récupère dans la cellule ligne no_ligne colonne J de l'onglet destination, la valeur de la cellule B6 de l'ongelt source If IsEmpty(OS.Cells(no_ligne, 2)) Then 'condition 2 : là je ne sais pas si tu fait référence à l'onglet source ou destination ? OD.Range("M" & no_ligne) = OS.Range("B10") 'récupère dans la cellule ligne no_ligne colonne M de l'onglet destination, la valeur de la cellule B10 de l'ongelt source Else 'sinon OD.Range("M" & no_ligne) = OS.Range("B9") 'récupère dans la cellule ligne no_ligne colonne M de l'onglet destination, la valeur de la cellule BP de l'ongelt source End If 'fin de la condition 2 OD.Range("N" & no_ligne) = OS.Range("B11") 'récupère dans la cellule ligne no_ligne colonne N de l'onglet destination, la valeur de la cellule B11 de l'ongelt source OD.Range("O" & no_ligne) = OS.Range("B3") 'récupère dans la cellule ligne no_ligne colonne O de l'onglet destination, la valeur de la cellule B3 de l'ongelt source OD.Range("Q" & no_ligne) = OS.Range("B8") 'récupère dans la cellule ligne no_ligne colonne Q de l'onglet destination, la valeur de la cellule B8 de l'ongelt source OD.Range("R" & no_ligne) = OS.Range("B12") 'récupère dans la cellule ligne no_ligne colonne R de l'onglet destination, la valeur de la cellule B12 de l'ongelt source End If 'fin de la condition 1 End Sub
Re,
Malheureusement, sans le fichier, je ne peux rien faire de mieux... Voir https://www.cjoint.com/ (ou autre) pour mettre un fichier en pièce jointe...
Malheureusement, sans le fichier, je ne peux rien faire de mieux... Voir https://www.cjoint.com/ (ou autre) pour mettre un fichier en pièce jointe...
En effet par inadvertance j'ai fait de grossières erreurs par rapport aux Else et End If, que j'avais juste inversés de place.
En ce qui concerne les liaisons, cela marche mieux, ou du moins le programme ne plante pas.
En revanche, même s'il ne m'affiche pas d'erreur, les valeurs ne s'incorporent pas dans mon tableau. Je remarque au'elle ouver le formulaire demandé, mais après je ne vois rien d'autre.
J'ai donc pené que cela venait de ma programmation pour trouver la bonne ligne, du coup j'ai essayé de changer cette partie du programme.
Mais rien n'a changé, je me retrouve maintenant avec une erreur 'Subscript out of range'.
Une idée?
Voilà mon programme:
Sub Transcription()
Dim Source As Workbook, no_ligne As Integer
Set Source = Workbooks.Open(Sheets("tab1").Range("S2").Value)
no_ligne = 1
If Source.Sheets("Sheet1").Range("A8") = "Currency" Then
While Not IsEmpty(Cells(no_ligne, 1))
no_ligne = no_ligne + 1
Wend
Sheets("tab1").Range("A" & no_ligne) = Source.Sheets("Sheet1").Range("B6")
Sheets("tab1").Range("C" & no_ligne) = Source.Sheets("Sheet1").Range("B4")
Sheets("tab1").Range("D" & no_ligne) = Source.Sheets("Sheet1").Range("B2")
Range("E" & no_ligne) = "LCD"
Sheets("tab1").Range("G" & no_ligne) = Source.Sheets("Sheet1").Range("B8")
Sheets("tab1").Range("H" & no_ligne) = Source.Sheets("Sheet1").Range("B7")
Sheets("tab1").Range("I" & no_ligne) = Source.Sheets("Sheet1").Range("B21")
Sheets("tab1").Range("J" & no_ligne) = Source.Sheets("Sheet1").Range("B27")
Sheets("tab1").Range("M" & no_ligne) = Source.Sheets("Sheet1").Range("B3")
Sheets("tab1").Range("O" & no_ligne) = Source.Sheets("Sheet1").Range("B18")
Sheets("tab1").Range("P" & no_ligne) = Source.Sheets("Sheet1").Range("B22")
Else
While Not IsEmpty(Cells(no_ligne, 1))
no_ligne = no_ligne + 1
Wend
Sheets("tab1").Range("A" & no_ligne) = Source.Sheets("Sheet1").Range("B4")
Sheets("tab1").Range("D" & no_ligne) = Source.Sheets("Sheet1").Range("B2")
Range("E" & no_ligne) = "ESC"
Sheets("tab1").Range("G" & no_ligne) = Source.Sheets("Sheet1").Range("B5")
Sheets("tab1").Range("H" & no_ligne) = Source.Sheets("Sheet1").Range("B6")
Sheets("tab1").Range("I" & no_ligne) = Source.Sheets("Sheet1").Range("B13")
If IsEmpty(Cells(no_ligne, 2)) Then
Sheets("tab1").Range("K" & no_ligne) = Source.Sheets("Sheet1").Range("B17")
Else
Sheets("tab1").Range("K" & no_ligne) = Source.Sheets("Sheet1").Range("B16")
End If
Sheets("tab1").Range("L" & no_ligne) = Source.Sheets("Sheet1").Range("B18")
Sheets("tab1").Range("M" & no_ligne) = Source.Sheets("Sheet1").Range("B3")
Sheets("tab1").Range("P" & no_ligne) = Source.Sheets("Sheet1").Range("B19")
End If
End Sub
Voilà, si j'ai bien compris, comment je verrais les choses :
Le 'Subscript out of range' persiste et je n'en ai aucune idée de pourauoi... D'autant plus qu'il ne m'indique pas d'où vient l'erreur...