perte de variable dans une macro

perte de variable dans une macro - VB/VBA/VBS - Programmation

Marsh Posté le 26-10-2007 à 18:16:18    

Bonjour à tous,
Je débute en VBA, et Je souhaiterais avoir de l'aide sur la macro
ci-dessous:
Je me propose, à partir d'une liste Excel de noms
(récupérée depuis une requête brute depuis internet)
de sélectionner les lignes qui appartiennent à un critère donné.
Ces lignes seront stockées dans un onglet de sélection
On va réitérer cette recherche
jusqu'à temps qu'on ait tapé '*' pour tout arrêter.
Mais au deuxième critère rentré
la macro s'arrête:

Citation :

« Erreur d'exécution '91':
Variable objet ou variable de bloc With non définie »


et je ne vois vraiment pas pourquoi.
Voici ma macro:

Code :
  1. Sub Recherche()
  2. Dim Recherche As String
  3. Dim LBas As Integer
  4. Dim Ligne As Integer
  5. Dim LigneSel As Integer
  6. '
  7. ' Recherche Macro
  8. '
  9. ActiveSheet.Name = "Feuil1"
  10. ActiveCell.SpecialCells(xlLastCell).Select 'on va en fin de fichier
  11. LBas = ActiveCell.Row                      ' récupérer son N° de ligne
  12. Sheets.Add
  13. Sheets("Feuil2" ).Select
  14. Sheets("Feuil2" ).Name = "Selection"
  15. Range("a1" ).Select
  16. On Error GoTo erreur
  17. Sheets("Feuil1" ).Select
  18. LigneSel = 1
  19. Recherche = "XX"
  20. Do While Recherche <> "*"
  21. Recherche = Application.InputBox(Prompt:="Tapez votre recherche," & vbCrLf & "puis cliquez sur Ok." & vbCrLf & "Le curseur déplacera la ligne dans l'onglet 'Selection'" & vbCrLf & "Faire * pour arrêter", Title:="Recherche", Default:="Tapez votre recherche", Type:=2)
  22. If Recherche <> "*" Then
  23. Range("a1" ).Select
  24.     Do
  25. On Error GoTo erreur
  26. Cells.Find(What:=Recherche, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
  27.       xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False) _
  28.      .Activate
  29. ActiveCell.EntireRow.Select
  30. Selection.Cut
  31. Ligne = ActiveCell.Row
  32. Sheets("Selection" ).Select
  33. ActiveSheet.Paste
  34. LigneSel = LigneSel + 1
  35. Cells(LigneSel, 1).Select
  36. Sheets("Feuil1" ).Select
  37. Ligne = Ligne + 1
  38. Cells(Ligne, 1).Select
  39. Loop Until Ligne > LBas
  40. End If
  41.      GoTo Boucle
  42. erreur:
  43.     Sheets("Feuil1" ).Select
  44.     Range("A1" ).Select
  45. Boucle:
  46. Loop
  47. Fin:
  48. End Sub


 
qui peut m'aider ?
D'avance merci

Reply

Marsh Posté le 26-10-2007 à 18:16:18   

Reply

Marsh Posté le 26-10-2007 à 19:30:35    

Ton message d'erreur, généralement c'est quand t'as une variable objet qui n'est plus assignée, ce qui pourrait être utile, c'est de dire sur quelle ligne ça plante
A mon avis, ça ne serait pas impossible que ça plante dès la première fois, mais que tu ne le vois pas à cause du "on error goto..." (J'ai déjà eu des soucis avec ma gestion d'erreur et une boucle perso)

Reply

Marsh Posté le 26-10-2007 à 19:42:32    

D'accord avec le diable.
si tu ne mets pas de "resume" dans ta gestion d'erreur, ca plante à la seconde fois.

Reply

Marsh Posté le 26-10-2007 à 19:48:00    

par ailleurs je suppose que ca plante en 30 vu que ta cells n'est pas affectée à une feuille d'aucun classseur...

Reply

Marsh Posté le 29-10-2007 à 11:20:32    

juste autre petit point, je suis pas sur qu'avoir une variable du nom de la procédure soit très pratique...

Reply

Marsh Posté le 29-10-2007 à 14:11:50    

Plutôt d'accord, autant dans un autre langage, pourquoi pas, autant en VBA, je le tenterais pas

Reply

Marsh Posté le 29-10-2007 à 16:14:56    

Merci pour vos réponses
J'ai donc changé le nom de la variable de recherche,
mais pour l'instant c'est toujours la même chose.
Je suppose qu'il faut utiliser un With / End With
sauf que que je ne vois pas très bien comment l'utiliser:
30. with cells.find(what:= ...
37. activeSheet.paste
38. end.With
c'est ça ?
hum! je ne sais pas.
--
d'avance merci ...

Reply

Marsh Posté le 29-10-2007 à 16:22:07    

bon alors j'ai fait tourner ton code chez moi, j'ai quelques questions :
- ne confonds-tu pas  

Code :
  1. Activesheet.Name = "Feuil1"

et

Code :
  1. Sheets("Feuil1" ).Activate

?
la gestion des boucles est une chose que tu n'as pas l'air de maîtriser bcp dans la mesure où je vois plusieurs goto dans tous les sens, c'est mauvais, car une fois sorti par l'exception, tu ne sais pas pkoi ton code a planté...
 
Tiens nous au courant :)

Reply

Marsh Posté le 29-10-2007 à 17:36:37    

J'ai pas tout compris à ce que tu voulais faire
ça plante au deuxième coup quand tu n'a pas de valeur sur ton Cells.find
Et puis les goto partout, je suis d'accord, c'est un peu dégueu
Du coup, je te propose une façon plus propre de faire tes tests...
la méthode find te renvoie un Range, du coup, tu déclare un objet Range (parceque pareil, les codes sans déclaration de variable, c'est le mal !), par exemple ra
tu affectes ton Cells.fin(blablabla...) à ton Range
Puis tu testes si l'objet est "Nothing" ou non  
Je pense que ton code ne plantera plus...
Mais j'ai pas exactement compris ce que tu voulais faire, et je ne comprends pas les tenants et aboutissants de chaque ligne de code

Reply

Marsh Posté le 30-10-2007 à 11:39:25    

Bonjour,
et merci de vos réponses.
Pour mieux faire comprendre mon but,
Je renvoie le code que j'ai un peu nettoyé:

Code :
  1. Sub Recherche()
  2. Dim Trouve As String
  3. Dim LBas As Integer
  4. Dim Ligne As Integer
  5. Dim LigneSel As Integer
  6. '
  7. ' Recherche Macro
  8. '
  9. ActiveSheet.Name = "Feuil1"
  10. ActiveCell.SpecialCells(xlLastCell).Select 'on va en fin de fichier
  11. LBas = ActiveCell.Row                      ' récupérer son N° de ligne
  12. Sheets.Add
  13. Sheets("Feuil2" ).Select
  14. Sheets("Feuil2" ).Name = "Selection" 'je renomme cette nouvelle feuille "Selection"
  15. Range("a1" ).Select                  'et je me positionne sur la 1ère cellule
  16. Sheets("Feuil1" ).Select             'je retourne à ma feuille Origine
  17. LigneSel = 1
  18. Trouve = "XX"
  19. Do While Trouve <> "*"
  20. Trouve = Application.InputBox(Prompt:="Tapez votre recherche," & vbCrLf & "puis cliquez sur Ok." & vbCrLf & "Le curseur déplacera la ligne dans l'onglet 'Selection'" & vbCrLf & "Faire * pour arrêter", Title:="Recherche", Default:="Tapez votre recherche", Type:=2)
  21. If Trouve <> "*" Then
  22. Range("a1" ).Select
  23.     Do
  24. On Error GoTo erreur       ' si je n'ai pas trouvé
  25. Cells.Find(What:=Trouve, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
  26.       xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False) _
  27.      .Activate
  28. ActiveCell.EntireRow.Select  'alors je récupère toute la ligne
  29. Selection.Cut                'je la supprime de ma feuille de travail
  30. Ligne = ActiveCell.Row
  31. Sheets("Selection" ).Select   'et je la colle dans ma feuille de sélection
  32. ActiveSheet.Paste
  33. LigneSel = LigneSel + 1
  34. Cells(LigneSel, 1).Select    'à la ligne suivante dans l'onglet de sélection
  35. Sheets("Feuil1" ).Select
  36. Ligne = Ligne + 1
  37. Cells(Ligne, 1).Select
  38. Loop Until Ligne > LBas
  39. End If
  40.      GoTo Boucle
  41. erreur:                       'je ne peux pas sortir la gestion des erreurs de la boucle
  42.     Sheets("Feuil1" ).Select
  43.     Range("A1" ).Select
  44. Boucle:
  45. Loop
  46. Fin:
  47. End Sub


J'appelle le 1er feuillet 'Feuil1' pour ne pas être embarrassé dans les appels de feuillets.
Donc ma feuille Origine s'appelle toujours 'Feuil1'
de même ma feuille de sélection
s'appellera toujours 'Selection'
-
Non je ne connais pas les différences entre:
sheets(« feuill1 »).activate
et sheets(« feuil1 »).select
mais je suis venu ici pour apprendre, étant auto-didacte
-
je ne sais pas comment éviter un  
« on error goto... »
car si j'ai épuisé ma recherche,
je tombe en erreur.
Donc, dans ce cas, je réinitialise
ma cellule active en début de feuillet,
prêt à reprendre une nouvelle recherche.
-
Pour la gestion du 'Range',
comment puis-je faire ?

Code :
  1. Dim Position as Range
  2. ...
  3. Position=Cells.Find(What:=Trouve, After:=...
  4. if Position is not null then ...


ce qui m'éviterait le « on error.. »
mais je ne connais pas la propriété d'un objet 'Range'
les aides VBA sont vraiment très succinctes,
il faut avoir la science infuse!
Sans vous demander la réponse toute faite,
ce que  je ne veux pas,
pourriez-vous cependant me mettre sur la voie ?
D'avance merci!
--
Adept, paumé!

Reply

Marsh Posté le 30-10-2007 à 11:39:25   

Reply

Marsh Posté le 30-10-2007 à 11:52:28    

adept a écrit :

Bonjour,
et merci de vos réponses.
Pour mieux faire comprendre mon but,
Je renvoie le code que j'ai un peu nettoyé:

Code :
  1. Sub Recherche()
  2. Dim Trouve As String
  3. Dim LBas As Integer
  4. Dim Ligne As Integer
  5. Dim LigneSel As Integer
  6. '
  7. ' Recherche Macro
  8. '
  9. ActiveSheet.Name = "Feuil1" toujours pas d'accord avec ceci, si je lance la macro avec la feuil2 activée, ca plante
  10. ActiveCell.SpecialCells(xlLastCell).Select 'on va en fin de fichier
  11. LBas = ActiveCell.Row                      ' récupérer son N° de ligne
  12. Sheets.Add
  13. Sheets("Feuil2" ).Select
  14. Sheets("Feuil2" ).Name = "Selection" 'je renomme cette nouvelle feuille "Selection"
  15. Range("a1" ).Select                  'et je me positionne sur la 1ère cellule
  16. Sheets("Feuil1" ).Select             'je retourne à ma feuille Origine
  17. LigneSel = 1
  18. Trouve = "XX"
  19. Do While Trouve <> "*"
  20. Trouve = Application.InputBox(Prompt:="Tapez votre recherche," & vbCrLf & "puis cliquez sur Ok." & vbCrLf & "Le curseur déplacera la ligne dans l'onglet 'Selection'" & vbCrLf & "Faire * pour arrêter", Title:="Recherche", Default:="Tapez votre recherche", Type:=2)
  21. If Trouve <> "*" Then
  22. Range("a1" ).Select
  23.     Do
  24. On Error GoTo erreur       ' si je n'ai pas trouvé
  25. Cells.Find(What:=Trouve, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
  26.       xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False) _
  27.      .Activate
  28. ActiveCell.EntireRow.Select  'alors je récupère toute la ligne
  29. Selection.Cut                'je la supprime de ma feuille de travail
  30. Ligne = ActiveCell.Row
  31. Sheets("Selection" ).Select   'et je la colle dans ma feuille de sélection
  32. ActiveSheet.Paste
  33. LigneSel = LigneSel + 1
  34. Cells(LigneSel, 1).Select    'à la ligne suivante dans l'onglet de sélection
  35. Sheets("Feuil1" ).Select
  36. Ligne = Ligne + 1
  37. Cells(Ligne, 1).Select
  38. Loop Until Ligne > LBas
  39. End If
  40.      GoTo Boucle
  41. erreur:                       'je ne peux pas sortir la gestion des erreurs de la boucle
  42.     Sheets("Feuil1" ).Select
  43.     Range("A1" ).Select
  44. Boucle:
  45. Loop
  46. Fin:
  47. End Sub


J'appelle le 1er feuillet 'Feuil1' pour ne pas être embarrassé dans les appels de feuillets. ca c'est de la feignantise mal placée
Donc ma feuille Origine s'appelle toujours 'Feuil1'
de même ma feuille de sélection
s'appellera toujours 'Selection'
-
Non je ne connais pas les différences entre:
sheets(« feuill1 »).activate activate sert a mettre en premier plan la sheet en question
et sheets(« feuil1 »).select select fais comme si tu cliquais en haut  à gauche de ta feuille> selection de toutes les cellules
mais je suis venu ici pour apprendre, étant auto-didacte
-
je ne sais pas comment éviter un  
« on error goto... »
car si j'ai épuisé ma recherche,
je tombe en erreur.il faut donc revoir cette recherche ;)
Donc, dans ce cas, je réinitialise
ma cellule active en début de feuillet,
prêt à reprendre une nouvelle recherche.
-
Pour la gestion du 'Range',
comment puis-je faire ?

Code :
  1. Dim Position as Range
  2. ...
  3. Position=Cells.Find(What:=Trouve, After:=...
  4. if Position is not null then ...


ce qui m'éviterait le « on error.. »
mais je ne connais pas la propriété d'un objet 'Range'
les aides VBA sont vraiment très succinctes,
il faut avoir la science infuse!
Sans vous demander la réponse toute faite,
ce que  je ne veux pas,
pourriez-vous cependant me mettre sur la voie ?
D'avance merci!
--
Adept, paumé!


voila de quoi commencer ;)

Reply

Marsh Posté le 30-10-2007 à 12:20:09    

Perso, je ne vois AUCUNE différence entre sheets("truc" ).select et sheets("truc" ).activate
 
D'ailleurs, il y a plusieurs façons d'appeller une feuille, soit pas son nom comme tu le fais, soit par son index, du coup, par défaut, sheets("Feuil1" ) = sheets(1)
 
En effet, ton code plante si on se met sur la feuille 2 pour la simple et bonne raison qu'il tente de la renommer en "Feuil1" et qu'elle est déjà existante dans le classeur
 
un Range, c'est un objet, tu coup, ton affectation, tu la fais en faisant un "set"
ex : set position = Cells.find(...)
 
T'es sur la bonne voie :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed