Définir une range d'un autre fichier Excel que celui actif
Bonjour à tous,
J'ai un souci en apparence pas très complexe, mais qui me donne du fil à retordre. Je souhaite tout simplement définir dans mon VBA une "RANGE" venant d'un autre fichier Excel que celui actif.
Je déclare bien les variables pour pouvoir gérer d'autres classeurs que celui actif :
Dim appExcel As Excel.Application 'Application Excel
Dim wbExcel As Excel.Workbook 'Classeur Excel
Dim wsExcel As Excel.Worksheet 'Feuille Excel
Jusque là, aucun souci, si je fais un MsgBox de wsExcel.Name il me trouve bien le nom de la feuille du fichier cible. (les "..." signifie qu'il y a du code qui s'exécute entre ses instructions) :
Set appExcel = CreateObject("Excel.Application")
.
.
.
Set wbExcel = appExcel.Workbooks.Open("...")
.
.
.
Set wsExcel = wbExcel.Worksheets("...")
Cependant, arrivé au moment de définir ma "RANGE" j'ai une erreur 400 sur la ligne du Set. (Les cellules dans la range sont un exemple du pattern que j'utilise vraiment dans mon code) :
Dim rangePannes As Range
Set rangePannes = wsExcel.Range("A1:A2,A3:A4,A5:A6")
Je pense qu'il n'apprécie pas le fait que je Set une variable de type "Range" avec l'objet wsExcel, car si je l'enlève tout roule, mais il ne parcours pas le bon fichier.
Aucun des 2 fichiers n'est protégé par mot de passe. J'ai testé de mon côté de faire un Foreach en définissant directement la range dans l'en-tête de mon Foreach pour m'éviter de passer par une variable et un Set, mais même erreur. J'ai essayé aussi des wsExcel.Activate, wsExcel.Select pour éviter de Set ma variable avec le wsExcel devant mais rien de tout ça ne fonctionne.
J'ai bien trouvé sur internet des "solutions" mais c'était des bouts de codes archaïques incompréhensible qui n'avait pas l'air de + fonctionner que ça, avez-vous une piste pour régler ou contourner mon problème ?
Cordialement.
Bonjour,
Pour moi le fait de créer un objet excel.application
Ouvre une autre instance Excel et le VBA ne communique pas entre deux instance différente ou trés mal. Enfin suivant les version peut être.
Sinon j'ai mis ce code la et il est fonctionnel chez moi.
Sub TEST()
Dim ThisWb As Workbook
Dim ThisWs As Worksheet
Dim OtherWb As Workbook
Dim OtherWs As Worksheet
Dim LeRange As Range
Set ThisWb = ActiveWorkbook
Set ThisWs = ActiveSheet
Set OtherWb = Workbooks.Open(ThisWb.Path & "\Fichier2.xlsm")
Set OtherWs = OtherWb.ActiveSheet
Set LeRange = OtherWs.Range("A1:A2,A3:A4")
For Each cell In LeRange
cell.Value = cell.Address
Next
End Sub
Bonjour,
Merci pour votre réponse, votre code fonctionne, mais à chaque ouverture de fichier, Excel vient se remettre en tâche prioritaire et me demande d'autoriser les macros sur les fichiers que j'ouvre. En effet je n'ai pas précisé, mais la macro à pour but de synthétiser des valeurs présentes dans + de 3000 fichiers Excel à parcourir.
Cependant, votre réponse m'a donné une autre idée, j'ai placé la macro sur un fichier neutre et cette fois-ci je viens créer 2 instances de Excel :
'Declaration des variables
Dim appFichierSynthese As Excel.Application 'Application Excel fichier de Synthese
Dim appFichierTRG As Excel.Application 'Application Excel fichier TRG
Dim wbFichierSynthese As Excel.Workbook 'Fichier Excel fichier de Synthese
Dim wbFichierTRG As Excel.Workbook 'Fichier Excel fichier TRG
Dim wsFichierSynthese As Excel.Worksheet 'Feuille Excel fichier de Synthese
Dim wsFichierTRG As Excel.Worksheet 'Feuille Excel fichier TRG
Pour parcourir la range de cellule qui m'intéresse j'ai réalisé une autre méthode (ci-dessous la méthode précédente) :
Dim rangePannes As Range
Set rangePannes = wsExcel.Range("A1:A2,A3:A4,A5:A6")
'Compte le nombre de pannes (si cellule > ? 0)
Dim nbPannes As Integer
nbPannes = 0
wsExcel.Activate
For Each Cell In rangePannes
If Cell.Value > 0 Then
nbPannes = nbPannes + 1
End If
Next
Au lieu de définir une range et d'essayer de la stocker puis de la parcourir (c'est ici que l'erreur 400 apparaissait) j'ai opté pour un switch case :
'Compte le num?ro du jour
nbDay = 0
'Compte le nombre de pannes arr?t programm? (si cellule > ? 0)
Dim nbPannesArretProg As Integer
nbPannesArretProg = 0
While nbDay <= 6
Select Case nbDay
Case 0
For Each Cell In wsExcel.Range("A1:A2")
If Cell.Value > 0 Then
nbPannesArretProg = nbPannesArretProg + 1
End If
Next
Case 1
For Each Cell In wsExcel.Range("A3:A4")
If Cell.Value > 0 Then
nbPannesArretProg = nbPannesArretProg + 1
End If
Next
.
.
.
Case Else
End Select
nbDay = nbDay + 1
Wend
Ce n'est pas très propre, mais ça fonctionne (OU PRESQUE), plus d'erreur 400 mais un "Overflow", je pense que ça doit venir de la fermeture des fichiers que je parcours (les 3000 et quelques fichiers) qui doivent mal se fermer et entrainer un overflow. Si vous avez d'autres pistes si non je reviens ici dès que j'ai + d'informations !
Cordialement.