Se connecter avec
S'enregistrer | Connectez-vous
Votre question
Résolu

Help macro Excel2k3

Tags :
  • Programmation
  • VB
Dernière réponse : dans Programmation
Partagez
7 Avril 2010 10:15:17

Bonjour,
Je suis debutant en macro VB et la je vous avoue que je patine

Voici mon probleme

Depuis quelques jours, je tente de créer une macro qui effacerait une cellule en fonction d'une egalité dans deux autres.

je m'explique:

j'ai une data sur la cellule C12 ( c'est une donné tirée d'une requete SQL) d'une feuille nommé "Data"

J'ai une donnée en E6 sur une autre feuille nommé "Lot"

La feuille data est "masqué" donc je ne peut utiliser de select

Dans ma macro je cherche a créer une condition du type :

[MACRO]

Sub Macro()

Sheets("Lot").Select
Range("E6").Select
If ActiveCell = "C12" Then GoTo Clear
Exit Sub
Clear:
With Sheets("Lot")
.Range("E10").Clear
End With

End Sub

Donc en regroupant tout sur une feuille ma macro ne marche deja pas :??:  et la en plus, il manque le nom de la feuille Data!C12


En francais sa donnerais: Si data!C12=Lot!E6 alors j'efface la cellule Lot!E10 sinon je ne fait rien

A savoir que ma cellule Lot!E10 est aussi une requete SQL donc je ne peut pas mettre de condition directement avec les formule Excel

Pouvez vous me filer un coup de pouce car malgres beaucoup de recherche sur le web je ne trouve pas de solution

Existe il une fonction similaire a .Clear mais qui ne detruit pas le formatage des cellules?
Merci d'avance a tous

Autres pages sur : help macro excel2k3

a b L Programmation
7 Avril 2010 10:46:11

Bonjour et bienvenu
fully a dit :
Je suis debutant en macro VB
Oui, ben t'es débutant en forum aussi :o 
Va lire le règlement de programmation pour voir comment on publie proprement un bout de code.

fully a dit :
La feuille data est "masqué" donc je ne peut utiliser de select
C'est très bien comme ça. (Cela dit pour la mise au point avec l'enregistreur de macro, tu peux temporairement désactiver le masquage).

Jette un oeil sur ces deux topics (surtout le second) :
http://www.presence-pc.com/forum/ppc/Programmation/vous...
http://www.presence-pc.com/forum/ppc/Programmation/tuto...

Tu patines toujours ?
m
0
l
7 Avril 2010 10:47:44

Oui aussi en forum j'avoue, je vais lire les liens que tu m'a donnés et je reviens
EDIT: Bon voila j'ai lu tes deux psot et cela ma permis d'avancer pas mal( voir edition du 1er message), mais pas de finaliser mon idée.
je crois que deja ma question a plus de sens et est poster a peu près correctement
m
0
l
Contenus similaires
7 Avril 2010 11:55:40

j'ai essayé l'enregistreur de macro mais je galere encore plus, pour crée une condition avec je vois pas comment faire...

Sinon, je progresse a pas de minipouce lol

j'ai deja trouver ce qui bugger dans ma macro:

[MACRO]

Sub Macro()

Sheets("Lot" ).Select
Range("E6" ).Select
If ActiveCell = "C12" Then GoTo Clear
Exit Sub
Clear:
With Sheets("Lot" )
.Range("E10" ).Clear
End With

End Sub

C'est la cellule "C12", il ne vois visiblement pas a quoi sa fait reference car lorsque je met une valeur a la place de la cellule, cela fonctionne.



m
0
l
a b L Programmation
7 Avril 2010 16:14:30

m
0
l
8 Avril 2010 09:03:54

Merci pour tes eclaircissement sur la maniere de "coller" une macro sur votre forum, dsl d'avoir omis ce detail,
De toutes façon j'ai crée la macro et cela fonctionne.
La voici, cela pourra peut etre aider un autre debutant.

  1. Sub clear()
  2. Do
  3. If Worksheets("Lot").Range("C9") <> Worksheets("Data").Range("C3") Then
  4.  
  5. With Sheets("Lot")
  6. .Range("C17:C200").ClearContents
  7. .Range("G26").ClearContents
  8. .Range("F32:G200").ClearContents
  9. End With
  10.  
  11. With Sheets("Data")
  12. .Range("A4:D200").ClearContents
  13. End With
  14.  
  15. With Sheets("Data")
  16. .Range("A3").QueryTable.Refresh BackgroundQuery:=False
  17. End With
  18.  
  19. With Sheets("Lot")
  20. .Range("C17").QueryTable.Refresh BackgroundQuery:=False
  21. .Range("h27").QueryTable.Refresh BackgroundQuery:=False
  22. .Range("F32").QueryTable.Refresh BackgroundQuery:=False
  23. .Range("C9").Select
  24.  
  25. End With
  26.  
  27. Else
  28. Attente (1)
  29. End If
  30.  
  31. Loop
  32. End Sub
  33. --------------------------------------------------------------------------------------------
  34. Sub Attente(seconde As Integer)
  35. Dim Start, PauseTime
  36. PauseTime = seconde
  37. Start = Timer
  38. Do While Timer < Start + PauseTime
  39. DoEvents
  40. Loop
  41.  
  42. End Sub

---------------------------------------------------------------------------------------------
m
0
l
a b L Programmation
8 Avril 2010 11:55:49

Pas mal. C'est donc résolu :) 

------------------------------------

Quelques compléments, si tu veux bien. :o 

Tu t'embêtes avec des With/End With. Vire-les :
  1. ' // Bof, pas terrible :
  2. With Sheets("Data" )
  3. .Range("A4:D200" ).ClearContents
  4. End With
  5.  
  6. ' // Plus simple, plus lisible, donc forcément mieux :
  7. Worksheets("Data" ).Range("A4:D200" ).ClearContents


J'utilise Worksheets plutôt que Sheets. C'est juste une question d'être plus précis. :spamafote: 

L'indentation est une institution sacro-sainte en programmation. Si tu devais devenir un développeur, je t'inviterais à observer ce précepte. :ange: 
m
0
l
8 Avril 2010 13:47:32

Merci pour les conseils,

Je vais testé de virer les "with/EndWith" comme tu me l'as conseillé.

je suppose que sa fonctionne même si la feuille est masquée.

Pour l'indentation, je le fait peu vu que je code rarement, mais au boulot des que tu t'y connais un peu en info on te demande tout et n'importe quoi... d'où un système d'actualisation automatique de carte de contrôle.

Une derniere chose, vu que ma macro tourne en boucle donc 24/24, j'ai remarqué qu'elle consomme 50% des ressource CPU soit 15% du CPU1 et 85% du CPU2 ( C2D6550) est il possible de reduire cette charge?
m
0
l
a b L Programmation
8 Avril 2010 15:05:52

A propos des feuilles cachées : Impossible de les activer ou de les sélectionner, puisse qu'elles doivent rester cachées. Donc un code stupide comme celui-là est impossible :
  1. Worksheets("feuille_cachée").Activate
  2. ActiveSheet.Range("A1").Select
  3. Selection.Formula = "X"
Bon et bien ça tombe bien, parce que la façon de faire correcte est celle-ci :
  1. Worksheets("feuille_cachée").Range("A1").Formula = "X"


Une rapide recherche avec google te fera observer que je suis en guerre contre les ActiveTruc ou Machin.Select, justement. [:patch]

VB est un langage gourmand, VBA encore plus, donc deux boucles imbriquées dont l'une infinie et l'autre vide, c'est pas terrible. En plus tu gères toi même le timer, c'est nul - excuse-moi, mais c'est comme ça. En plus, je reconnais dans ton code, un algo bien connu, mais vraiment moche.

Supprime la boucle infinie Do .. Loop (lignes 2 et 31). Supprime la fonction Attente.

Et utilise OnTime

Etudie-moi ça :
  1. Sub auto_refresh_n_clear()
  2. Dim s As Long
  3. Dim ws_lot As Worksheet
  4. Dim ws_dat As Worksheet
  5.  
  6. ' // nombre de secondes
  7. s = 12
  8.  
  9. Set ws_lot = Worksheets("Lot" )
  10. Set ws_dat = Worksheets("Data" )
  11.  
  12. If ws_lot.Range("C9" ).Value <> ws_dat.Range("C3" ).Value Then
  13. ws_lot.Range("C17:C200" ).ClearContents
  14. ws_lot.Range("G26" ).ClearContents
  15. ws_lot.Range("F32:G200" ).ClearContents
  16. ws_dat.Range("A4:D200" ).ClearContents
  17. ws_dat.Range("A3" ).QueryTable.Refresh BackgroundQuery:=False
  18. ws_lot.Range("C17" ).QueryTable.Refresh BackgroundQuery:=False
  19. ws_lot.Range("h27" ).QueryTable.Refresh BackgroundQuery:=False
  20. ws_lot.Range("F32" ).QueryTable.Refresh BackgroundQuery:=False
  21. End If
  22.  
  23. Application.OnTime Now + TimeSerial(s\3600, (s\60) Mod 60, s Mod 60), "auto_refresh_n_clear"
  24. End Sub


J'ai mis des variables pour les feuilles. Pas la peine de tout recalculer à chaque fois. Et puis j'ai viré le [C9].Select à la fin, qui ne sert à rien. Voilà !
m
0
l
9 Avril 2010 10:05:22

Bonjour Zeb,
J'etais partie pour me faire une macro evenementielle, mais j'ai tester ta macro aussi et la tu m'as largué

sur ta ligne
  1. Application.OnTime TimeSerial(s \ 3600, (s \ 60) Mod 60, s Mod 60), "auto_refresh_n_clear"
  2. End Sub

je ne comprend pas bien ce que tu as fait, tu a definit le temps comme etant "S/3600" bon oki sa me fais des secondes pour "s"
Alors apres par contre avec le "Mod" je ne vois pas ce que tu as voulu faire sachant que l'explication du ontime que j'ai trouvé se resume a:
Application.OnTime(EarliestTime, Procedure, [LatestTime], [Schedule])

Dans tout les cas la macro n'a pas l'air de tourner en boucle, enfin de se relancer toutes les 12s...



je continu de chercher

PS: Le select C9 a sont importance a la fin, il sert a quelque chose :) 
m
0
l
a b L Programmation
9 Avril 2010 11:22:45

Rhoooo! Ce n'est pas de la programmation, ce sont des maths !
TimeSerials attend des heures, des minutes et des secondes.

L'opérateur \ divise dans l'ensemble des entiers. Pour les réels, c'est /.
L'opérateur Mod (modulo) renvoie le reste d'une division entière.

Soit maintenant s une grosse quantité de secondes.

s \ 60, ce sont les minutes contenues dans s.
s Mod 60, c'est le reste. Ce sont les secondes qui restent.

Maintenant que nous avons des minutes, celles-ci peuvent contenir des heures !
Donc au cran suivant, on recommence.

J'aurais pu écrire :
  1. m = s \ 60
  2. s = s Mod 60
  3. h = m \ 60
  4. m = m Mod 60
  5.  
  6. Application.OnTime Now + TimeSerial(h, m, s), "auto_refresh_n_clear"


(Tu as remarqué, j'ai ajouté le Now qui manquait :whistle:  )

Si on est sûr que s est toujours inférieur à 60, on peut écrire :
  1. Application.OnTime Now + TimeSerial(0, 0, s), "auto_refresh_n_clear"


-------------

Moi, j'aime pas les Select
¯¯¯¯¯¯¯¯\¯¯¯¯¯¯¯¯¯¯¯¯
m
0
l
9 Avril 2010 13:59:10

ouuuki, la je comprend beaucoup mieux :) 

Et oui j'ai constaté qu'il devait manquer un truc ( comme le now) pour que sa boucle^^
Mais j'ai trouvé encore mieux :sol: 
La macro evenementielle consomme 0 ressource et fonctionne a merveille pour mon application.

Par contre je ne sais pas comment lancer le tous directement dans le module et non dans le feuille ciblée... :??: 

En faisant comme cité plus haut je pourrais virer le "GOTO" que j'ai mis et mettre en place ta synthaxe sans mes "select", "with" et compagnie...

  1. Private Sub Worksheet_Change(ByVal Target As Range)
  2.  
  3. If Target.Count > 1 Then Exit Sub
  4.  
  5. GoTo Clear
  6. Clear:
  7. If Worksheets("Lot").Range("B9") <> Worksheets("Data").Range("C3") Then
  8. With Sheets("Lot")
  9. Application.EnableEvents = False
  10. .Range("C17:C200").ClearContents
  11. .Range("G26").ClearContents
  12. .Range("F32:G200").ClearContents
  13. End With
  14.  
  15. With Sheets("Data")
  16. .Range("A4:D200").ClearContents
  17. .Range("A3").QueryTable.Refresh BackgroundQuery:=False
  18. End With
  19. With Sheets("Lot")
  20. .Range("C17").QueryTable.Refresh BackgroundQuery:=False
  21. .Range("G26").QueryTable.Refresh BackgroundQuery:=False
  22. .Range("F32").QueryTable.Refresh BackgroundQuery:=False
  23. .Range("C9").Select
  24. Application.EnableEvents = True
  25. End With
  26.  
  27.  
  28. End If
  29.  
  30. End Sub


Bon je sais, j'ai encore mis plein de chose "moche" :na: 
m
0
l

Meilleure solution

a b L Programmation
9 Avril 2010 16:45:09

Citation :
... Worksheet_Change ...
Eh, mais ça c'est de la triche ! Je croyais que tu avais vraiment besoin d'un timer ! :ouch:  :ouch: 

  1. .
  2. .
  3. .
  4. .
  5. GoTo Clear
  6. Clear:
  7. .
  8. .
:??:  Non mais tu vas me virer ça !? [:zeb:4]

Et pour les With, c'est juste moche. Inspire-toi du joli code que je te proposais.

Citation :
Par contre je ne sais pas comment lancer le tous directement dans le module et non dans le feuille ciblée... :??: 
Ben au lieu de jouer avec Worksheet_Change, regarde du côté de Workbook_SheetChange :spamafote: 
partage
19 Avril 2010 08:31:18

Meilleure réponse sélectionnée par Fully.
m
0
l