Macro Excel > Besoin d'aide !

Sork

Nouveau membre
Bonjour à tous,


J'ai créé un document Excel assez imposant, sur lequel j'aimerai effectuer une macro. Le problème c'est que je ne m'y connais pas trop en Visual Basic, et que c'est assez compliqué...

Je vous expose le problème :
voici ma feuille : ex :
C D E
Jour | Heure début | Heure fin |
-----|------------|----------|
3 01 | 2:30 | 2:40 |
4 01 | 5:40 | 6:05 |
5 02 | 3:10 | 3:50 |
6 02 | 19:25 | 19:35 |
...
(ça peut aller jusqu'à plusieurs centaines de lignes de problèmes)

Ensuite j'ai à côté une colonnes avec toutes les heures de la journée, par tranche de 5 minutes (ex: 00:05, 00:10...).

Ce que je veux faire : les heures écrites sont les heures où il y a un problème (ex: le premier jour, de 2h30 à 2h40). Je veux que pour une journée ça me mette un "1" ou un "0" ("1" signifie qu'il y a un problème) à côté de l'heure de la journée correspondante (ex: 2h30, 2h35 et 2h40 pour le premier problème), dans le but de réaliser un graphe.
Pour cela, j'ai déjà écris une formule qui me le fait. Par contre elle ne marche que pour une journée.

C'est pour cela que je veux faire une macro (s'activant en cliquant sur un bouton (il y aura 1 bouton pour chaque jour du mois)). Cette macro devra permettre de :

- sélectionner que les heures correspondant à une journée choisie
(ex: pour la 01:
2:30 | 2:40
5:40 | 6:05 )

- repérer la zone correspondante (ici $D$3:$E$4)

- remplacer les zones dans la formule par cette zone-ci


Voilà, je ne sais pas du tout si c'est facile ou non à faire !
Merci d'avance !!

Sork
 

zeb

Modérateur
Mais oui, c'est facile...
Où est ta macro pour une ligne ?
On va l'adapter si tu veux bien.
 

Sork

Nouveau membre
Mais oui, c'est facile...
Où est ta macro pour une ligne ?
On va l'adapter si tu veux bien.
Où est la macro ?

Et bien à l'idéal, il y aurait une cellule, dans laquelle on inscrirait le jour à traiter (disons le jour 01).
A côté de cette cellule, il y aurait un bouton (déclencheur de la macro).

Lorsque l'on clique sur ce bouton : il faudrait que la plage (en colonne D et E), correspondante/adjacente à toutes les lignes où le jour (ici 01) apparait dans la colonne C, soit sélectionnée (ou du moins que ses coordonnées soient enregistrées).

En gros, si 46 problèmes appraissent le jour 01, la plage qui devra être prise comportera 46 lignes...

(Note: les jours et horaires sont obligatoirement dans l'ordre chronologique par défaut)
 

zeb

Modérateur
Ah, bas en te relisant, c'est pas une macro, c'est une formule.
Au temps pour moi...

Sinon, j'ai bien compris la problématique.

Bon, va relire les règles et tu y découvriras que tu ne trouveras personne ici pour te faire ton programme (sauf si tu me contactes en message privé, mais sache que mes honoraires sont hors de prix :D )

Donc propose-nous pour commencer un point particulier de ton problème, avec un bout de code et on va regarder ça...
 

Sork

Nouveau membre
Une formule ? Je ne vois pas comment... Enfin je reste sur ma macro.

On entre donc 01, et on clique sur le bouton.

Alors j'y ai réfléchi, tenté de me renseigner, et voici à mon idée ce que la macro doit faire :

- chercher la première occurrence du jour (qui est 01) > on obtient $C$3
- chercher la dernière occurrence > on obtient $C$4
- on a donc ici la possibilité de créer une plage contenant toutes les cellules "01" : $C$3:$C$4
- on remplace le premier "C" par un "D", et le deuxième par un "E" > On a alors : $D$3:$E$4
- on remplace les plages concernées dans la formule
- on recopie la formule vers le bas pour l'appliquer à toutes les tranches horaires : c'est gagné !


Là il est un peu tard pour que je m'y mettes, mais les 2 premiers points ne devraient pas poser de problème (à part peut être pour récuppérer les coordonnées de la cellule ?).
Par contre je sais pas comment on fait avec VBA pour lui faire écrire "$C$3:$C$4" à partir de 2 variables égales à $C$3 et $C$4... De même, je ne sais pas comment faire remplacer le premier "C" par "D" et l'autre par "E"...
La fin devrait être simple : il suffit d'enregistrer !


Ainsi toutes mes données seront modifiées, et le graphe se modifiera en conséquence, selon le jour choisi.
 

Sork

Nouveau membre
Bon bah... j'y arrive pas ! :pfff:


J'ai fait des bouts de code (j'ai d'ailleurs un peu changé les étapes en passant...) :

- chercher la première occurrence du jour (qui est 01) > on obtient $C$3 > on se décale d'un vers la droite et on obtient $D$3
- chercher la première occurrence du jour (qui est 01) > on obtient $C$3 > on se décale de deux vers la droite et on obtient $E$3
- chercher la dernière occurrence > on obtient $C$4 > on se décale d'un vers la droite et on obtient $D$4
- chercher la dernière occurrence > on obtient $C$4 > on se décale de deux vers la droite et on obtient $E$4

ça donne :
[cpp] JourPremier = Range("B15").Value
Premier = Cells.Find(What:=JourPremier, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=True).Offset(0, 1)
' Premier est la cellule située à droite de la cellule trouvée par le biais d'une recherche (ex: D3)

JourPremier2 = Range("B15").Value
Premier2 = Cells.Find(What:=JourPremier2, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=True).Offset(0, 2)
' Premier2 est la cellule située à la 2e colonne à droite de la cellule trouvée par le biais d'une recherche (ex: E3)


JourDernier = Range("B15").Value + 1 ' marche seulement si les jours se suivent et si ce n'est pas le dernier !
Dernier = Cells.Find(What:=JourDernier, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=True).Offset(-1, 1)
' Dernier est la cellule située à droite de la cellule trouvée par le biais d'une recherche (ex: D6)

JourDernier2 = Range("B15").Value + 1 ' marche seulement si les jours se suivent et si ce n'est pas le dernier !
Dernier2 = Cells.Find(What:=JourDernier2, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=True).Offset(-1, 2)
' Dernier2 est la cellule située à la 2e colonne à droite de la cellule trouvée par le biais d'une recherche (ex: E6)[/cpp]
Déjà j'ai un premier problème : comment prendre la dernière occurence de la valeur cherchée ? J'ai une solution mais qui ne fonctionne que dans certains cas...



Bon la suite :
- on a donc ici la possibilité de créer deux plages contenant toutes les cellules nous intéressant : $D$3:$D$4 et $E$3:$E$4

Ca j'y arrive pas du tout. Je sais pas comment passer les cellules trouvées en plages...




Et enfin :
- on remplace les plages concernées dans la formule
- on recopie la formule vers le bas pour l'appliquer à toutes les tranches horaires : c'est gagné ! (en théorie !)


J'ai fait un truc (en partant de plages données) mais ça marche pas :

[cpp] Modific = "R14C4:R16C4" '$D$14:$D$16
Modific2 = "R14C5:R16C5" '$E$14:$E$16
Range("H3").Select
ActiveCell.FormulaR1C1 = _
"=IF(IF(ISNA(MATCH(RC6," & Modific & ",1))=FALSE,MATCH(RC6," & Modific & ",1),0)=IF(ISNA(MATCH(RC6," & Modific2 & ",1))=FALSE,MATCH(RC6," & Modific2 & ",1),0)+1,1,0)"
Range("H3").Select
Selection.AutoFill Destination:=Range("H3:H10"), Type:=xlFillDefault
Range("H3:H10").Select[/cpp]
Il me dit qu'il y une erreur à la ligne 5 mais je vois pas comment l'écrire autrement.

Merci de m'aider !!!!

 

zeb

Modérateur
Oh, la la !

Faire simple ;)
Tu cherches une plage. Mais en fait, les colonnes sont connues, donc en fait, tu cherches deux lignes. Je propose :
Code:
Option Explicit

Sub AfficheLaPlage()
     Dim l, l1, lN As Integer
     Dim j, j0 As Integer
          
     l = 3
     l1 = 0
     j0 = Range("B15").Value
     Do
        j = Cells(l, 3).Value
        If j = j0 Then
            If l1 = 0 Then l1 = l
            lN = l
        End If
        l = l + 1
     Loop While l < 65536 And j <= j0
   
     MsgBox Range(Cells(l1, 4), Cells(lN, 5)).Address
End Sub

La dernière ligne affiche l'adresse de la plage. Plutot que de l'afficher, autant la mettre dans ta formule.

Quant à ton dernier "truc", utilise Formula au lieu de FormulaR1C1 si tu ne veux pas te prendre la tête avec des conversions. Tu ne nous dit pas ce qu'il y a dans ta colonne F (RC6).
 

Sork

Nouveau membre
J'étais parti en vacances, et j'avais pas vu ton dernier message.

Ben j'y suis arrivé tout seul ! :D

J'ai sûrement fait compliqué pour pas grand chose, mais bon ça marche, c'est le principal.

Voilà ce que j'ai fait :

[cpp]Sub Modif_formule2()

JourPremier = Range("Graphiques!F4").Value
Range("C3:C900").Select
Set Premier = Selection.Find(What:=JourPremier, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=True).Offset(0, 1)
' Premier est la cellule située à droite de la cellule trouvée par le biais d'une recherche (ex: D3)

JourPremier2 = Range("Graphiques!F4").Value
Set Premier2 = Selection.Find(What:=JourPremier2, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=True).Offset(0, 2)
' Premier2 est la cellule située à la 2e colonne à droite de la cellule trouvée par le biais d'une recherche (ex: E3)

JourDernier = Range("Graphiques!F4").Value
Set Dernier = Selection.Find(What:=JourDernier, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False _
, SearchFormat:=False).Offset(0, 1)
' Dernier est la cellule située à droite de la cellule trouvée par le biais d'une recherche (ex: D6)

JourDernier2 = Range("Graphiques!F4").Value
Set Dernier2 = Selection.Find(What:=JourDernier2, After:=ActiveCell, LookIn:=xlValues, LookAt:= _
xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False _
, SearchFormat:=False).Offset(0, 2)
' Dernier2 est la cellule située à la 2e colonne à droite de la cellule trouvée par le biais d'une recherche (ex: E6)

Range("G4").Select
ActiveCell.Formula = _
"=IF(IF(ISNA(MATCH($F4," & Premier.Address() & ":" & Dernier.Address() & ",1))=FALSE,MATCH($F4," & Premier.Address() & ":" & Dernier.Address() & ",1),0)=IF(ISNA(MATCH($F4," & Premier2.Address() & ":" & Dernier2.Address() & ",1))=FALSE,MATCH($F4," & Premier2.Address() & ":" & Dernier2.Address() & ",1),0)+1,1,0)"
Selection.AutoFill Destination:=Range("G4:G291"), Type:=xlFillDefault
Range("G4").Select

End Sub[/cpp]



Pour répondre à ta question, la colonne F contient toutes les heures de la journée, par tranche de 5 minutes (ex: 00:00, 00:05, 00:10...), et la colonne G contient la formule qui affiche soit 0 soit 1 s'il y a un problème dans la tranche horaire.
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 132
Messages
6 717 999
Membres
1 586 386
Dernier membre
aviateurdesairs
Partager cette page
Haut