La semaine recommence avec son lot de casses-tête, entre autre:
j'ai un fichier excel avec une macro relativement simple qui récupère les données du feuillet 1, pour les copier dans les feuillets 2 et 3. Le truc le + complexe, c'est que j'ai une fonction. Bref, quelque chose de simple. Cela fonctionne parfaitement sur un paquet de PC, mais pas sur d'autres. Et ce qui se passe est étrange: il ouvre le fichier, on voit la page mais sans le bouton qui permet d'exécuter la macro, puis il mouline, il mouline, il mouline... et il mouline à l'infini jusqu'à écrire "Excel ne répond plus"... :-( Ctrl Alt Supp et c'est reparti.
Les 2 PC sont sous Office 2003, la petite différence est que l'un deux est dans une version Pack Basic.
J'ai déjà exploité d'autres fichiers sur ce PC avec macros, et cela fonctionnait sans pb.
Si vous avez déjà eu ce problème, je vous serais très reconnaissante de m'aider. ;-)) J'ai vu dans un autre forum que quelqu'un avait eu ce pb à cause d'arguments dans une fonction, mais je ne vois pas ce que je peux changer. Je débute en VBA, pas facile!
Voici la fonction qui pourrait poser pb:
Function SheetExist(ByRef Name As String) As Boolean
Dim i As Integer
For i = 1 To Worksheets.Count
If StrComp(Worksheets(i).Name, Name, vbTextCompare) = 0 Then
SheetExist = True
Exit Function
End If
Next i
End Function
Tu utilises un mot réservé pour déclarer une variable argument !
Comment cela a-t-il fonctionner ? Je donne ma langue au chat !
Function SheetExist(ByRef Name As String) As Boolean
Le mot [ Name ] est un mot réservé servant de propriété pour
nommer un objet.
Utilise plutôt :
Function SheetExist(ByRef MyName As String) As Boolean
Second point :
Il n'est pas nécessaire de passer l'argument [ ByRef ],
tu n'as pas à modifier ce nom il me semble, le paramètre
peut-être passer avec le paramètre [ ByVal ].
Et voici ma façon de procéder :
Option Explicit
Function SheetsExists(ByVal MyName As String) As Boolean
Dim MySheet As Worksheet
SheetsExists = False
For Each MySheet In ThisWorkbook.Worksheets
If (MySheet.Name = MyName) Then
SheetsExists = True
Exit For
End If
Next
End Function
'
Merci pour ta réponse, tu me sors de bien des galères!
Au niveau des fonctions, comme tu peux le voir, je commence à m'en servir, et ça donne des codes assez folkloriques! ;-) Je teste avec le code que tu m'as proposé demain.
Merci et bonne soirée! A demain
Bien que j'ai une critique sévère sur le code, ne t'en fait pas,
car moi aussi, j'ai été débutant et j'ai eu aussi, en mon temps
des personnes qui m'ont aidé et expliqué les choses !
Ceci dit, excuse mon texte si celui-ci est parfois trop critique !
Oh non, ça ne me gêne pas du tout! Je ne le prend pas mal... surtout que tu as raison! Je suis très contente que des gens tels que toi prennent le temps d'apprendre aux p'tits débutants (surtout que ça doit être exaspérant parfois ;-) ) En plus tu expliques très bien, et ça c'est pas toujours gagné! Merci, bonne soirée
Bonjour Lupin, test effectué et... réussi!
C'était assez traitre le fait que mon code foireux fonctionne sur certains PC et pas d'autres! Au premier abord, je pensais que c'était un problème d'options ou de références... Comme quoi il ne faut pas se fier aux apparences. Merci encore pour ton aide précieuse, tu es plus efficace que l'aspirine!
Function SheetsExists(ByVal MyName As String) As Boolean
Dim MySheet As Worksheet
SheetsExists = False
For Each MySheet In ThisWorkbook.Worksheets
'For Each MySheet In ActiveWorkbook.Worksheets
'For Each MySheet In Workbooks("MonFichier.xls").Worksheets
If (MySheet.Name = MyName) Then
SheetsExists = True
Exit For
End If
Next
End Function
'
Bonjour Lupin
je reviens te voir à propos de cette fonction SheetsExist.
J'ai un nouveau PC, et elle ne fonctionne plus sur ce PC. Je ne trouve pas le problème, j'ai essayé le mode pas à pas, j'ai essayé d'ajouter des références. Mais rien n'y fait.
Il exécute la fonction mais lors de la comparaison, à chaque fois, il considère que la feuille n'existe pas alors que si.
Function SheetsExists(ByVal MyName As String) As Boolean
Dim MySheet As Worksheet
SheetsExists = False
For Each MySheet In ActiveWorkbook.Worksheets
If (MySheet.Name = MyName) Then
SheetsExists = True
Exit For
End If
Next
End Function
Sub test()
If SheetsExists("test") Then
MsgBox ("ok")
Else
MsgBox ("faux")
End If
End Sub
En espérant que tu auras une idée du problème,
Ludivine
D'un premier coup d'oeil, je dirais
que la fonction ne cherche pas dans
le bon classeur.
L'instruction suivante s'applique
au classeur actif.
For Each MySheet In ActiveWorkbook.Worksheets
La solution est de passer le classeur en paramètre :
Function SheetsExists(ByVal MonClasseur As Workbook, _
ByVal MyName As String) As Boolean
Dim MySheet As Worksheet, Classeur As String
Classeur = ActiveWorkbook.Name
MonClasseur.Activate
SheetsExists = False
For Each MySheet In MonClasseur.Worksheets
If (MySheet.Name = MyName) Then
SheetsExists = True
Exit For
End If
Next
Workbooks(Classeur).Activate
End Function
'
Je n'arrive pas à faire fonctionner la fonction.
Je ne la comprends pas non plus car tu n'actives le fichier que après l'exécution de la fonction.
Et comment je peux l'appeler? J'ai essayé cela: mais ça ne fonctionne pas:
Sub test()
If SheetsExists("fichiertest.xls","test") Then
MsgBox ("ok")
Else
MsgBox ("faux")
End If
End Sub
D'autre part, j'ai testé d'afficher une boîte de dialogue avec le nom du fichier dans la fonction, et il m'affiche bien le bon fichier.
Function SheetsExists(ByVal MyName As String) As Boolean
Dim MySheet As Worksheet
MonClasseur = ActiveWorkbook.Name
MsgBox (MonClasseur)
SheetsExists = False
For Each MySheet In ThisWorkbook.Worksheets
'For Each MySheet In ActiveWorkbook.Worksheets
'For Each MySheet In Workbooks("MonFichier.xls").Worksheets
If (MySheet.Name = MyName) Then
SheetsExists = True
Exit For
End If
Next
End Function
n.b. J'ai ajouté l'instruction [ Ucase ], au cas ou il y aurait un problème de majuscule/miniscule.
Option Explicit
Sub Test()
If SheetsExists(Workbooks("fichiertest.xls"), "test") Then
MsgBox ("ok")
Else
MsgBox ("faux")
End If
End Sub
'
Function SheetsExists(ByVal MonClasseur As Workbook, _
ByVal MyName As String) As Boolean
Dim MySheet As Worksheet
MsgBox (MonClasseur.Name)
SheetsExists = False
For Each MySheet In MonClasseur.Worksheets
If (UCase(MySheet.Name) = UCase(MyName)) Then
SheetsExists = True
Exit For
End If
Next
End Function
'
Avec cette méthode, le programme fonctionne à nouveau.
C'est un peu bête car du coup, je suis obligée de récupérer le nom du fichier dans une variable (macro qui fonctionne sur plusieurs fichiers) pour l'utiliser ensuite quand j'appelle la fonction SheetsExists.
Or, quand il récupère le nom du fichier actif, il reprend bien le bon fichier... Donc c'est bizarre qu'après dans la fonction SheetsExist, il soit un peu perdu... Au moins ça fonctionne, mais je n'ai pas compris le problème du code initial.
' Récupération du nom du fichier pour pouvoir exécuter la fonction SheetsExist
Dim NomFichierNew As String
NomFichierNew = ActiveWorkbook.Name
' vérification de l'existence de la feuille
If SheetsExists(Workbooks(NomFichierNew), "test") Then...
J'en conviens c'est assez nébuleux et je ne connais pas l'historique des postes,
le type d'installation, etc ...
En fait, lorsque je t'ai proposé de passer le nom du classeur en paramêtres
j'avais une idée derrière la tête bien sur.
Je ne connais que très peu l'utilisation d'un fichier du type [ *.xlb ], les barres
d'outils si je ne m'abuse, je connais très bien les [ *.xla ] et [ *.xlt ].
Et je n'utilise pas non plus les fichier [ perso.xls ] placé dans le répertoire
XLStart du système.
Donc, quand to ouvre Excel, tous les XLA chargés peuvent être adressé
comme des "workbooks" sous VBA.
D'un poste à l'autre, beaucoup de chose peuvent influencer,
différentes macros complémentaires ou références VBA
supplémentaires demanderont d'être plus explicite dans le code pour ne pas
confondre les "espaces de noms", plusieurs classeurs peuvent aussi
être ouvert au moment de faire appel à la fonction, le niveau de sécurité
pourrait aussi être en cause.
Si tu souhaite creusé la question, voici une suggestion :
En passant une troisième variable passer par [ Référence ] [ ByRef ].
À noter que l'on place toujours le paramêtre [ ByRef ] en fin de liste de déclaration :
Mauvaise syntaxe :
Function SheetsExists(ByRef Liste As String, _
ByVal MyName As Workbook) As Boolean
Bonne syntaxe :
Function SheetsExists(ByVal MyName As String, _
ByRef Liste As String) As Boolean
Dim MySheet As Worksheet
SheetsExists = False
For Each MySheet In ActiveWorkbook.Worksheets
Liste = Liste & MySheets.Name & vbLf
Ainsi, au retour de l'appel, il suffit de lancer un
MsgBox Liste
Merci pour ta réponse, tu me sors de bien des galères!
Au niveau des fonctions, comme tu peux le voir, je commence à m'en servir, et ça donne des codes assez folkloriques! ;-) Je teste avec le code que tu m'as proposé demain.
Merci et bonne soirée! A demain