[vba/excel] aide fonction goto
RésoluBarahaoua Messages postés 89 Date d'inscription Statut Membre Dernière intervention -
j'aimerais avoir la syntaxe de la commande goto pour me déplacer a un certains endroit du code
merci
Configuration: Windows XP Internet Explorer 6.0
8 réponses
La problématique centrale est la syntaxe de la commande GoTo dans Visual Basic et son utilisation pour déplacer le flux d'exécution vers une étiquette dans le code. Des réponses permettent d'observer la syntaxe exacte, telle que GoTo NomEtiquette, suivie d'une dénomination NomEtiquette: et d'une étiquette correspondante dans le code, avec des exemples concrets illustrant son usage dans des procédures VBA. D'autres réponses avertissent que GoTo peut compliquer la lisibilité et la maintenance et proposent des conseils pour les cas d'erreur et pour éviter les boucles inefficaces. En parallèle, des échanges soulignent des alternatives comme Exit For, Exit Sub ou On Error GoTo, et ajoutent qu'il est parfois utile, mais rarement recommandé, d'utiliser GoTo pour limiter les répétitions.
-
Bien que Michel ait ABSOLUMENT raison, je te donne la syntaxe:
Goto NomEtiquette
---
---
---
NomEtiquette: -
Les mecs, je me permet d'intervenir un peu pour vous rappeler deux, trois trucs :
1- vous êtes en train de vous prendre le chou alors que la question initiale n'était pas "est-ce bien ou non d'utiliser GoTo?" mais plutôt "comment l'utilise-t-on?".
Ca serait pas mal de se focaliser un peu plus surtout quand on veut vraiment répondre à ceux qui cherchent des infos UTILES.
2- ensuite je veux bien que vous déconseillez à qqn d'utiliser une fonction mais du moment où elle a une utilité (par exemple c'est très utile pour rendre PROPRE un code et gérer les erreurs en évitant les petits messages intenpestifs parce que l'utilisateur a laissé la touche majuscule activée ou autre...) ce serait bien d'être un peu plus pertinent.
3- pour finir je pense que tous essayez d'aider donc ça serait bien de ne pas passer son temps à se créper le chignon, surtout que je voudrais vous montrer le résultat de vos petites disputes : le résultat n°1 sur Google lorsqu'on recherche comment utiliser GoTo est devenu votre petite gueguerre... je trouve ça dommage.
Sinon désolé pour le petit coup de gueule mais bon c'est dommage d'en arriver à s'engueuler et ça emm....bête tout le monde.-
Bonjour,
1) comment l'utilise-t-on?
tu as la réponse au post 2...
2) c'est très utile pour rendre PROPRE un code
c'est l'inverse
3) Il s'agit d'un conseil fort de ne pas l'utiliser, je ne vois pas pourquoi il n'aurait pas sa place dans ce topic.
Maintenant chacun fait comme il veut. Tu peux très bien tondre ta pelouse aux ciseaux même si tout le monde te dit qu'il y a mieux.
Et si le 1er lien retourné par google ne te convient pas, tu as le 2nd qui pointe chez microsoft (une référence).
Au passage tu peux y lire : Les instructions GoTo peuvent rendre le code difficile à lire et à gérer. Si possible, utilisez à la place une structure de contrôle.
eric -
Bonjour eric,
En effet, il y a d'autres possibilités mais bon il ne me semble pas avoir écrit "on ne peut pas faire autrement" ou "c'est le mieux" (de toute manière en programmation il n'y a que rarement UNE bonne solution).
Je dis simplement que pour des usages spécifiques c'est plus PROPRE en effet. A condition évidemment d'en avoir l'utilité.
Après j'étais au courant que "si le 1er lien retourné par google ne te convient pas, tu as le 2nd qui pointe chez microsoft (une référence)" et que "Les instructions GoTo peuvent rendre le code difficile à lire et à gérer" en tout cas si on les utilise mal ou à mauvais escient. Ce n'était pas mon message de dire le contraire. Donc toutes mes excuses si je n'ai pas été assez clair.
En fait j'étais surtout scandalisé par le fait que le topic se nomme "aide fonction goto" et qu'on n'y voit surtout des commentaires du style "cet individu nivelle par le bas par sa suffisance" -
Au passage, les structures de contrôles peuvent être lourdes et pour une instruction récurrente (ex: message "le champ n'est pas correctement rempli") ou même juste pour arrêter la procédure et réinitialiser en cas d'erreur il vaut PEUT-ÊTRE mieux utiliser un simple GoTo que d'appeler une procédure à chaque fois ou de faire 36 copier-coller; encore une fois ce n'est qu'un avis mais qui vient du vécu.
D'ailleurs si tu prends le temps de lire les exemples donnés par Microsoft, tu t'appercevras qu'ils le déconseillent dans le cadre d'un moyen de substitution des chaînes conditionnelles (If, ElsIf,...GoTo). Mais pour des besoins un peu plus complexes, comme ce qui touche aux erreurs d'utilisateurs, eh bien je déconseillerais à quiconque d'utiliser des boucles conditionnelles en cascade ou des boucles for pour par exemple arrêter la procédure et donner un message d'alerte en cas de couac.
Un exemple où GoTo peut avoir son utilité (à mon sens) :
>Private Sub Bouton_Click()
> On Error GoTo erreur
....
> erreur:
> Msgbox("erreur - le programme va se réinitialiser")
> Object1.Clear
> Object2.Clear
.....
>End Sub -
-
-
-
Bonjour,
B-A-BA visual basic: Il est fortement déconseillé d'utiliser GOTO dans une procédure!, c'est de la programmation "spaghetti"...
Le seul cas où on l'utilise est la gestion des erreurs.
maintenant si tu y tiens, tu peux lire l'aide en ligne.
Désolé (j'ai commencé basic il ya 20 ans avec des goto)
Cordialement,
Michel -
Bonsoir,
J'en rajoute une couche que tu ne prenne pas de mauvaises habitudes :
on peut toujours se passer d'un goto !!!
Par exemple
If test = "ok" then goto suite
...
...
suite:
peut être remplacé par:
if test <> "ok" then
...
...
endif
' la suite ici
...
Reste seulement comme l'a dit michel
on error goto etiquette
eric-
-
Bonjour le fil,
"on peut toujours se passer d'un goto !!! " !!!!! (j'ai ajouté exprès des !)
Bien sur! Je l'ai appris récemment, mais bien entendu que l'on peux toujours (mis à part On Error) se passer de goto.
Même pour "revenir en arrière".
Miaou, donne nous un exercice à ce sujet, tu verras que bien évidemment michel et ériiic auront la réponse.
Moi non, parce que là je goto wc d'urgence...
Je plaisante, mais reste persuadé que goto n'est plus du tout d'actualité!
Bonne journée -
-
-
-
-
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -
Bonjour,
Quelqu'un pourrait il profiter que ce sujet sorte un peu prendre l'air pour expliquer POURQUOI est-ce une si grosse erreur ?J'aime bien comprendre :-P
Bonne journee-
-
Bonjour,
Le goto est à banir pour éviter ce qu'on appelle un code spaghetti.
Cette facilité donne un code qui part dans tous les sens, pas du tout structuré, très dur à lire, à déboguer, et à maintenir ensuite.
Déjà qu'un code très bien écrit n'est pas toujours facile à comprendre, inutile d'y ajouter de la difficulté si on peut d'en passer.
Bien sûr c'est au prix d'un petit effort... mais qui se rentabilise très vite
eric -
Il y aussi que les boucles (while/wend for/next do/loop until ....) sont plus rapides que le goto (ce qui est paradoxal vu que une boucle est une multitude d'utilisation d'un goto caché ^^ (voir l'assembleur))
Et puis il y a très longtemps on codais en assembleur, c'était chiant parce qu'il n'y a aucune boucle, que les goto (jmp en assembleur) et les tests.
Et un jour l'homme inventa les boucles par la création d'autre langage.
Donc pourquoi vouloir se faire du mal en revenant à cette archaïque goto ???
-
-
Bonsoir,
je viens de débuter en vba et j'ai bien vu que dans les procédures il sert à la gestion d'erreur, sauf que dans mon cas je l'ai utilisé afin d'éviter de répéter un code se trouvant à la fin :Sub toto()
Choix 1/Choix 2 -> oui/non
Non -> code choix 1
le code
GoTo Fin
Oui -> code choix 2
le code
Fin:
code de fin
End sub</code>
Donc choix 1 et 2 utilise le même "code de fin"
A moins que je me trompe-
-
Bonjour Pijaku j'ai besoin de ton aide stp
j'ai mon code au quel j'ai mis un goto recomencer a la fin du code
et j'ai mis recomencer au debut de mon code ce qui me fait une boucle infénie alors que moi je veux lui fixé une condition je veux que lorsque j'atteint un nombre de boucle donnée par exemple 3 que mon programme s'arréte
voila mon code
merci<code>Sub Plaque5_Cliquer()
</code>
Dim UniteLavage As Long
Dim d As Object
Dim i As Integer, j As Integer, c As Variant
Dim Nbre_Total_Boucl As Integer
Dim Rng1, Rng2 As Range
Dim Nb_Boucle As Integer
Dim Arret As Boolean
'Dim compt As Integer
'compt = 1
recomencer:
Satisfait = False
With Sheets("Interface")
'On vérifie s'il existe une valeur en B1
If .[b1] = "" Then MsgBox "Insérer une valeur en B1", 16: Exit Sub
'On enregistre la variable UniteLavage
UniteLavage = .[b1]
'On applique la valeur à la ligne 7
'code pour le lancement des passe dans le tunel
Arret = False: Nb_Boucle = 0
'Do Until compt = 2
If Range("B1").Value <> "" Then 'vérifie que B1 n'est pas vide
Nbre_Total_Boucl = Columns(3).Find("*", , , , , xlPrevious).Row - 12
Do While Arret = False
DoEvents
'Range("B7:T7").Value = "" 'réinitialise ton "tableau"
i = 2 'valEUr de Ma première colonne du tableau
Application.Wait Time + TimeSerial(0, 0, 2) 'attends 10 sec
Do Until Range("T7") <> "" Or Arret = True 'conditionne la boucle jusqu'à la dernière colonne de ton tableau
If i > 2 Then Cells(7, i - 1).Value = Range("B1") 'mettre la valeur de B1 dans les cellule precedente
Cells(7, i).Value = Range("B1").Value 'mets ta valeurs dans la cellule de ton tableau
i = i + 1 'prochaine colonne
Application.Wait Time + TimeSerial(0, 0, 2) 'attends 10 sec
DoEvents
Loop
Range("B3") = Range("B3") + Range("T7")
'If Range("B7") <> "" Then
'boucle sur la colonne X
Set Rng1 = Columns(24).Cells.Find(Range("C13").Offset(Nb_Boucle, 0).Value)
If Rng1 Is Nothing Then
MsgBox Range("C13").Offset(Nb_Boucle, 0).Value & " non trouvé en colonne X"
Else
Rng1.Offset(1, 0).Value = Rng1.Offset(1, 0).Value + Range("B7").Value
'End If
End If
Nb_Boucle = Nb_Boucle + 1
If Nb_Boucle = Nbre_Total_Boucl Then Exit Do
Loop
Else
MsgBox "B1 est vide !"
End If
'.Range("b7:t7").Value = UniteLavage
'On démarre la procédure de choix aléatoire
Choix_Aleatoire
'Si Satisfait n'est pas atteint on quitte
If Not Satisfait Then Exit Sub
'On détermine la quantité de chaque Plat
i = .[c65000].End(xlUp).Row
Set d = CreateObject("scripting.dictionary")
'On boucle la colonne C
For j = 13 To i
'On incrémente chaque Plat pour déterminer le nombre de chaque
d(.Cells(j, 3).Value) = d(.Cells(j, 3).Value) + 1
Next j
For Each c In d.keys: d(c) = d(c) * UniteLavage: Next c
'On boucle la colonne X
'For j = 2 To 13 Step 2
'If d.exists(.Cells(j, "x").Value) Then .Cells(j, "x").Offset(1).Value = d(.Cells(j, "x").Value)
' Next j
'On ajoute la valeur à B1
.[B3] = WorksheetFunction.Sum([x2:x13])
GoTo recomencer
End With
'compt = compt + 1
End Sub
-
-
kikoo à tous, je viens mettre mon petit grain de sel :)
je viens ici juste pour spécifier que je vois qu'un seul cas ou on peut utiliser les goto :
mais pour cela il faut être dans une optique d'optimisation pur et dur et tel le warior que je suis (j'utilise des fichiers de plus de 20000 lignes et un bon paquet de colonne) je me dois d'avoir cet objectif en tête
De par ma propre expérience et avec le pc que j'ai au boulot le for est plus rapide que le while et est très propre pour le parcours de tableau.
Néanmoins il peut arriver qu'il y est une autre condition de sortie que "j'ai fini de parcourir le tableau" et dans ce cas je fais ceci :
Dim i As Integer, j As Integer Dim tabData() As Variant tabData = Range("...").Value For i = LBound(tabData, 1) To UBound(tabData, 1) For i = LBound(tabData, 1) To UBound(tabData, 1) traitement If condition_de_sortie Then Goto fin_traiter_tabData Next j Next i fin_traiter_tabData: Range("...").Value = tabData
Voila ! Et perso je trouve ca très propre, très lisible et je le conseille à quiconque désire otpimiser au mieux son code
NB: le fait de travailler sur un tableau plutôt que directement sur le classeur, le fait d'utiliser le if inline plutot que le if bloc pour la condition de sortie et le fait de prendre un integer pour les i et j (du moment que je ne fais pas plus de ~37600 incrémentation ca passe) sont du à l'optimisation.
sur ce au revoir tout le monde
-
Salut,
Dans ce sujet, il n'a jamais été question de bannir à tous prix le Goto. Effectivement, dans certains cas, il s'avère très utile. D'ailleurs, dans ce sujet, est abordé à plusieurs reprises le traitement d'erreur, où le goto est indispensable.
L'utilisation de goto dans ton code, me fait penser fortement à un traitement d'erreur. Tu utilises en effet exactement le même principe qu'un On error Goto, sauf que, dans ton cas, c'est plus un On PasD'erreur Goto... -
ne t'inquiète pas pijaku, j'ai bien lu tout vos messages avant de poster.
C'est juste que je passer par là et j'ai eu une soudaine envie d'embêter un peu les anti-goto ^^
même si en dehors de l'utilisation que j'ai montré, je suis d'accord avec vous et je ne l'utilise jamais (on n'est pas la pour faire de l'assembleur XD ) -
je ne m'inquiète pas OkidOki. Juste que cette discussion est ancienne mais toujours pas résolue pour tous. De toutes façons, il est toujours agréable de discuter, en argumentant bien sur, autour de ce genre de sujet.
D'autant que grâce à toi et à goto, je viens de découvrir un raccourci.
Pour faire ceci :For i = LBound(tabData, 1) To UBound(tabData, 1) For i = LBound(tabData, 1) To UBound(tabData, 1) traitement If condition_de_sortie Then Goto fin_traiter_tabData Next j Next i fin_traiter_tabData: Range("...").Value = tabData
avant la lecture de ton message, j'aurais écrit ce genre de code :Dim flag As Boolean flag = False For i = LBound(tabData, 1) To UBound(tabData, 1) For i = LBound(tabData, 1) To UBound(tabData, 1) traitement If condition_de_sortie Then flag = True: Exit For Next j If flag then Exit For Next i Range("...").Value = tabData
Ce qui est tout de même vachement plus long en exécution. 1 test If supplémentaire sur 30 000 lignes.....
Comme quoi, nous ne dénigrons pas le goto.
Si d'ailleurs quelqu'un passant par ici proposait une autre solution de sortie de double boucle, ça peut être très intéressant.... -
-
Bonjour à tous,
Ce qui est tout de même vachement plus long en exécution. 1 test If supplémentaire sur 30 000 lignes.....
Heuuu comment doit-on le comprendre ?
Le Comme quoi, nous ne dénigrons pas le goto a failli me faire douter :-)
C'est bien un seul test supplémentaire en tout et pour tout quelque soit le nombre de boucles...
Un pouième non mesurable d'ailleurs car le processeur aura eu bien des interruptions pour aller faire autre chose et ça sera noyé dans le "bruit".
Bon c'est un peu plus court et ça reste lisible.
Reste à se poser la question des For qui s'empilent et ne sont jamais désempilés. Pas de quoi saturer la pile si c'est peu utilisé mais...
Sinon pas d'autre idée de sortie d'une double boucle.
eric
PS: arrête-toi à 32700 pour les integer, c'est plus raisonnable ;-)
-
-
Y'a des moments ou un goto est nécessaire, sinon cette fonction n'existerait pas
-_- elle simplifie le programme a fond et permet des déplacements facile sans que les boucles conditionnelles s'enmele :)
Je suis le cours du Visual Basic sur le site du zéro, je suis donc qu'un débutant mais je donne mon avis quand même : le goto est bien utile :)-
-
-
-
Pas de problème. Ce qui prouve la pertinence de mon message #17.
Maintenant, posez-vous la question suivante : pourquoi ne trouve t'on pas de goto dans des lignes de codes vba écrites par des pros ou des amateurs éclairés ? Tout simplement parce qu'ils sont inutiles. Mais rien ne l'interdit, de même que vous pouvez toujours utiliser une carriole et 2 chevaux comme moyen de locomotion ! -
Primo, je trouve que c'est débile de répondre à quelqu'un par un air supérieur d'intelligence en disant : pourquoi tu veux un GoTo?... il veut savoir comment l'utiliser en VBA, pas pourquoi!
Secondo le goto est la base de toute les boucles itératives dans tous les langages !
Et pour terminer, voici un exemple simple :
nbcycle = 1
rewind:
nbdate = .Range("A" & Rows.Count).End(xlUp).Row - 1
.... (blabla)
If nbcycle < 2 Then
nbcycle = nbcycle + 1
GoTo rewind
End If
ici on exécute le code deux fois avec un GoTo (c'est à dire on reboucle une fois)
@+
-