Résolu Help macro Excel2k3

fully

Nouveau membre
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
 

zeb

Modérateur
Bonjour et bienvenu
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.

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/tutoriel-excel-macro-trucs-astuces-sujet-4953-1.htm

Tu patines toujours ?
 

fully

Nouveau membre
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
 

fully

Nouveau membre
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.



 

fully

Nouveau membre
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.

[cpp]
Sub clear()
Do
If Worksheets("Lot").Range("C9") <> Worksheets("Data").Range("C3") Then

With Sheets("Lot")
.Range("C17:C200").ClearContents
.Range("G26").ClearContents
.Range("F32:G200").ClearContents
End With

With Sheets("Data")
.Range("A4:D200").ClearContents
End With

With Sheets("Data")
.Range("A3").QueryTable.Refresh BackgroundQuery:=False
End With

With Sheets("Lot")
.Range("C17").QueryTable.Refresh BackgroundQuery:=False
.Range("h27").QueryTable.Refresh BackgroundQuery:=False
.Range("F32").QueryTable.Refresh BackgroundQuery:=False
.Range("C9").Select

End With

Else
Attente (1)
End If

Loop
End Sub
--------------------------------------------------------------------------------------------
Sub Attente(seconde As Integer)
Dim Start, PauseTime
PauseTime = seconde
Start = Timer
Do While Timer < Start + PauseTime
DoEvents
Loop

End Sub
[/cpp]
---------------------------------------------------------------------------------------------
 

zeb

Modérateur
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 :
Code:
' // Bof, pas terrible :
With Sheets("Data" )
    .Range("A4:D200" ).ClearContents
End With

' // Plus simple, plus lisible, donc forcément mieux :
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' est une institution sacro-sainte en programmation. Si tu devais devenir un développeur, je t'inviterais à observer ce précepte. :ange:
 

fully

Nouveau membre
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?
 

zeb

Modérateur
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 :
Code:
Worksheets("feuille_cachée").Activate
ActiveSheet.Range("A1").Select
Selection.Formula = "X"
Bon et bien ça tombe bien, parce que la façon de faire correcte est celle-ci :
Code:
Worksheets("feuille_cachée").Range("A1").Formula = "X"

Une rapide recherche avec 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 :
Code:
Sub auto_refresh_n_clear()
  Dim s As Long
  Dim ws_lot As Worksheet
  Dim ws_dat As Worksheet

  ' // nombre de secondes
  s = 12

  Set ws_lot = Worksheets("Lot" )
  Set ws_dat = Worksheets("Data" )

  If ws_lot.Range("C9" ).Value <> ws_dat.Range("C3" ).Value Then
    ws_lot.Range("C17:C200" ).ClearContents
    ws_lot.Range("G26"      ).ClearContents
    ws_lot.Range("F32:G200" ).ClearContents
    ws_dat.Range("A4:D200"  ).ClearContents
    ws_dat.Range("A3"       ).QueryTable.Refresh BackgroundQuery:=False
    ws_lot.Range("C17"      ).QueryTable.Refresh BackgroundQuery:=False
    ws_lot.Range("h27"      ).QueryTable.Refresh BackgroundQuery:=False
    ws_lot.Range("F32"      ).QueryTable.Refresh BackgroundQuery:=False
  End If

  Application.OnTime Now + TimeSerial(s\3600, (s\60) Mod 60, s Mod 60), "auto_refresh_n_clear"
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à !
 

fully

Nouveau membre
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
[cpp]Application.OnTime TimeSerial(s \ 3600, (s \ 60) Mod 60, s Mod 60), "auto_refresh_n_clear"
End Sub[/cpp]
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 :)
 

zeb

Modérateur
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 :
Code:
m = s \ 60
s = s Mod 60
h = m \ 60
m = m Mod 60

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 :
Code:
Application.OnTime Now + TimeSerial(0, 0, s), "auto_refresh_n_clear"

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

Moi, j'aime pas les Select
¯¯¯¯¯¯¯¯\¯¯¯¯¯¯¯¯¯¯¯¯
Vous devez être connecté pour voir les images.
 

fully

Nouveau membre
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...

[cpp]Private Sub Worksheet_Change(ByVal Target As Range)

If Target.Count > 1 Then Exit Sub

GoTo Clear
Clear:
If Worksheets("Lot").Range("B9") <> Worksheets("Data").Range("C3") Then
With Sheets("Lot")
Application.EnableEvents = False
.Range("C17:C200").ClearContents
.Range("G26").ClearContents
.Range("F32:G200").ClearContents
End With

With Sheets("Data")
.Range("A4:D200").ClearContents
.Range("A3").QueryTable.Refresh BackgroundQuery:=False
End With
With Sheets("Lot")
.Range("C17").QueryTable.Refresh BackgroundQuery:=False
.Range("G26").QueryTable.Refresh BackgroundQuery:=False
.Range("F32").QueryTable.Refresh BackgroundQuery:=False
.Range("C9").Select
Application.EnableEvents = True
End With


End If

End Sub
[/cpp]

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

zeb

Modérateur
Meilleure réponse
... Worksheet_Change ...
Eh, mais ça c'est de la triche ! Je croyais que tu avais vraiment besoin d'un timer ! :ouch: :ouch:

Code:
.
.
.
.
GoTo Clear
Clear:
.
.
:??: 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.

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:
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 128
Messages
6 717 842
Membres
1 586 372
Dernier membre
Meeithot
Partager cette page
Haut