Vous utilisez un navigateur obsolète. Il se peut que ce site ou d'autres sites Web ne s'affichent pas correctement. Vous devez le mettre à jour ou utiliser un navigateur alternatif.
J’ai quelques soucis avec des macros que je tente de mettre en place dans un fichier Excel (que je joins à ce message).
1er problème : lors du double clic dans la colonne H, j’active une première macro (nommée « Indicateur ») qui pose un problème, car je veux ensuite qu’une deuxième macro s’active (macro « Calendar ») dans cette cellule et au niveau du code je n’arrive pas à coder pour qu’à la fin de la macro indicateur la sélection revienne sur la cellule où j’avais cliqué.
2ème problème : il concerne ma macro Calendar, lorsque je clique sur une date dans le calendrier qui s’affiche, si le chiffre que j’ai sélectionné se situe entre 1 et 12, le code me met ce chiffre en mois alors que je le veux en jour. Par contre cela marche comme je veux à partir du 13 du mois…
3ème problème : je souhaiterais faire une macro conditionnelle entre la feuille « Planning général » et « Planning de sortie ». Je voudrais que cette macro recherche dans la feuille « Planning général », colonne G, toutes les dates qui se situent entre celles définies dans la feuille « Planning de sortie » (cellule B2 et D2), et qu’à chaque fois qu’il trouve une date dans la feuille « Planning général », il copie la ligne entière de cette cellule trouvée dans la feuille « Planning de sortie ».
Pour qu'on puisse t'aider, il ne suffit pas de donner un code "faux" ! Il faut aussi expliquer ce qu'il est censé devoir faire... sinon, on interprète, avec une chance qu'on réponde juste, mais il y a la Loi de Murphy qui rôde...
1er problème : lors du double clic dans la colonne H, j’active une première macro (nommée « Indicateur ») qui pose un problème, car je veux ensuite qu’une deuxième macro s’active (macro « Calendar ») dans cette cellule et au niveau du code je n’arrive pas à coder pour qu’à la fin de la macro indicateur la sélection revienne sur la cellule où j’avais cliqué.
Solution simple : ne pas utiliser les Select/Activate, qui ne servent qu'à ralentir le code.
2ème problème : il concerne ma macro Calendar, lorsque je clique sur une date dans le calendrier qui s’affiche, si le chiffre que j’ai sélectionné se situe entre 1 et 12, le code me met ce chiffre en mois alors que je le veux en jour. Par contre cela marche comme je veux à partir du 13 du mois…
J'ai retravaillé tes macros de la feuille "Planning Général". N'ayant qu'une version 2003, je n'ai touché qu'au code, sans le tester : la conversion me fait des misères et je ne connais pas le but réel des macros
Code:
Sub Date_prévisionnelle()
Dim i As Long
Dim Nb_Lignes As Long
Nb_Lignes = Range("F" & Rows.Count).End(xlUp).Row
i = 6
Range("G6:G500").ClearContents
For i = 6 To Nb_Lignes
Select Case Range("F" & i)
Case "Hebdomadaire"
Range("G" & i) = Range("H" & i) + 7
Case "Bimensuel"
Range("G" & i) = Range("H" & i) + 15
Case "Mensuel"
'Range("G" & i) = Range("H" & i) + 30
Range("G" & i) = DateSerial(Year(Range("H" & i)), Month(Range("H" & i)) + 1, Day(Range("H" & i)))
Case "Trimestriel"
'Range("G" & i) = Range("H" & i) + 91
Range("G" & i) = DateSerial(Year(Range("H" & i)), Month(Range("H" & i)) + 3, Day(Range("H" & i)))
Case "Quadrimestriel"
'Range("G" & i) = Range("H" & i) + 122
Range("G" & i) = DateSerial(Year(Range("H" & i)), Month(Range("H" & i)) + 4, Day(Range("H" & i)))
Case "Semestriel"
'Range("G" & i) = Range("H" & i) + 182
Range("G" & i) = DateSerial(Year(Range("H" & i)), Month(Range("H" & i)) + 6, Day(Range("H" & i)))
Case "Annuel"
'Range("G" & i) = Range("H" & i) + 365
Range("G" & i) = DateSerial(Year(Range("H" & i)) + 1, Month(Range("H" & i)), Day(Range("H" & i)))
Case "Biennal"
'Range("G" & i) = Range("H" & i) + 730
Range("G" & i) = DateSerial(Year(Range("H" & i)) + 2, Month(Range("H" & i)), Day(Range("H" & i)))
Case "Quinquénal"
'Range("G" & i) = Range("H" & i) + 1827
Range("G" & i) = DateSerial(Year(Range("H" & i)) + 5, Month(Range("H" & i)), Day(Range("H" & i)))
End Select
Next
End Sub
Il faut être le plus logique possible : si la variable "i" va de 6 à NB_Lignes, il doit être du même type que NB_Lignes, pour être sûr de ne pas créer un dépassement valeur. Vu que c'est une variable ligne, je la déclare toujours en long.
Se limiter à 65536 lignes, alors que c'est une version Excel supérieure à 2003, c'est se créer des problèmes dans le futur => mieux vaut laisser excel choisir.
Ajouter des nombres de jours quand on parle de mois, années risque des décalages dans le temps(10/01/2011=> on finit au 5/12/2011 et au 29/01/2013, en ajoutant 30 jours chaque mois). Il vaut mieux demander à excel d'ajouter le type de donnée voulue.
Faire une succession de If concernant la même donnée n'est pas la meilleure façon de régler le problème. Je préfère utiliser dans ce cas "Select Case".
Code:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.Column = 8 Then
Cancel = True
Indicateur
Calendar
ElseIf Target.Column = 9 Then
Cancel = True
Calendar
End If
End Sub
Mettre Cancel à Vrai annule ce qui se passe en double-cliquant (entrée dans la cellule).
Un exemple de traitement multiple d'une donnée, autre que Select Case. N'aimant pas utiliser ActiveCel, je l'ai remplacée par target.
Code:
Sub Indicateur()
Dim Cel As Range
Set Cel = ActiveCell
Rows(Cel).Copy Sheets("Indicateur").Cells(Sheets("Indicateur").Cells.Find("*", , , , , xlPrevious).Row + 1, "A")
Application.CutCopyMode = False
End Sub
Pas sûr de moi sur ce coup, à cause de la méthode Find, mais le principe reste le même : il n'est nul besoin de sélectionner pour copier (à condition que la feuille soit bien spécifiée, si c'est nécessaire).
Code:
Sub Calendar()
Dim Réponse As Integer
Userform1.Show
Réponse = MsgBox(msg, vbYesNo, "La date est-elle correcte ?")
If Réponse = vbNo Then
MsgBox "Entrer une nouvelle date"
Userform1.Show
End If
End Sub
Je ne suis pas sûr du but de cette macro : on donne une seconde chance ? Pas très logique, parce que si on se trompe, on n'a pas de troisième possibilité prise en compte. Soit on teste la validité de la date à chaque fois (en sortie de l'USF, ça me semblerai le mieux, avant d'inscrire, ou à chaque inscription), soit on ne teste pas, et on suppose que la personne sera assez intelligente pour vérifier.
3ème problème : je souhaiterais faire une macro conditionnelle entre la feuille « Planning général » et « Planning de sortie ». Je voudrais que cette macro recherche dans la feuille « Planning général », colonne G, toutes les dates qui se situent entre celles définies dans la feuille « Planning de sortie » (cellule B2 et D2), et qu’à chaque fois qu’il trouve une date dans la feuille « Planning général », il copie la ligne entière de cette cellule trouvée dans la feuille « Planning de sortie ».
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.address(0, 0) = "B2" Or Target.address(0, 0) = "D2" Then
Cancel = True
Userform1.Show
End If
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo Err_Worksheet_Change
' en cas d'erreur excel, aller à l'adresse Err_Worksheet_Change
Dim X As Long, Y As Long
If Target.address(0, 0) <> "B2" Or Target.address(0, 0) <> "D2" Then GoTo Sortie_Worksheet_Change
'si l'adresse relative de target différente de B2 et de D2, aller à la sortie
If [B2] <> "" And [D2] <> "" Then
'Si B2 et D2 sont remplies, alors
If [B2] > [D2] Then
'si B2 spérieure à D2 (fin avant début de période)
Application.EnableEvents = False
'on bloque la gestion des évènements
MsgBox "La date en D2 doit être supérieure ou égale à celle de B2 !", vbCritical + vbOKOnly, _
"Erreur de date"
'message d'erreur
[D2] = ""
'remise à vide de D2
GoTo Sortie_Worksheet_Change
'on va directement à la sortie
End If
'sinon, si B2 et D2 sont correctes (sous-entendu, puisqu'on est arrivé à cette ligne)
Y = Range("A1").SpecialCells(xlCellTypeLastCell).Row
'y=dernière ligne de la feuille
X = IIf(Y < 8, 8, Y)
'x= dernière ligne de la feuille si elle est supérieur à 8, sinon 8
Range("A8:I" & X).Clear
'on efface de A8:Ix (ancien résultat)
Y = 8
With Sheets("Planning général")
'Feuille en préfixe pour les instruction commençant par "."
For X = 6 To .Cells(Rows.Count, "G").End(xlUp).Row
'Pour X=6 à dernière non vide de G de la feuille "Planning général" (mise en préfixe)
If [B2] <= .Cells(X, "G") And .Cells(X, "G") <= [D2] Then
'si B2=<Gx=<D2, alors
.Rows(X).Copy Rows(Y)
'Copier la ligne sur la ligne Y
Y = Y + 1
'augmenter de 1 Y
End If
Next X
End With
End If
Sortie_Worksheet_Change: 'Adresse de sortie
Application.EnableEvents = True 'Rétablir gestion évènements
Exit Sub 'sortir
Err_Worksheet_Change: 'adresse de gestion d'erreur
MsgBox Err.Description, , "Erreur Excel n°" & Err.Number 'message (descrpition+numéro d'erreur)
Resume Sortie_Worksheet_Change 'continuer à l'adesse de sortie
End Sub
J'utilise deux macros automatiques : la première, tu connais
la seconde se lance quand on modifie la feuille (quand on passe la feuille en mode Édition)
-On vérifie qu'on a changé soit B2, soit D2 => si aucun n'est vide, on vérifie que la période commence avant de finir => si ce n'est pas le cas, on efface D2 et on sort
- on efface les anciennes lignes
- on copie les lignes de la feuille "Planning général" sur la feuille active (Planning de sortie)
Comme j'ai renseigné la macro, le code devrait être suffisamment explicite.
Attention toutefois, je ne l'ai pas testé (code simple, et problèmes venant du passage de 2007/2010 à 2003 fréquents). Mais une erreur esr si vite arrivée...
A+
Edit : adresse relative s'écrit .address(0,0)
Gorfael,
Je me suis penchée sur ce que tu m'as donné. Merci pour les corrections concernant le calcul des dates, c'est très utile.
Ensuite, pour la macro "Indicateur", j'ai essayé la tienne, les cellules que je voulais ne sont pas copiées.. En fait le code que l'on m'avait donné était bien, sauf ce que j'ai mis en rouge :
A la place de ce 6 ( qui était un test), il me faudrait mettre un code du genre "coordonnées de ligne de la cellule double cliquée"
Enfin, j'ai essayé ta macro pour la page "planning de sortie". En fait je voudrais qu'elle s'active lors du clic sur mon bouton "actualiser", je n'ai pas réussi à modifier ton code pour ça...
Salut Moonshine et le forum
Application directe de la Loi de Murphy
si c'est bien de la macro Worksheet_Change que tu parles :
Code:
Sub Test()
Dim X As Long, Y As Long
If [B2] <> "" And [D2] <> "" Then
'Si B2 et D2 sont remplies, alors
If [B2] > [D2] Then
'si B2 spérieure à D2 (fin avant début de période)
MsgBox "La date en D2 doit être supérieure ou égale à celle de B2 !", vbCritical + vbOKOnly, _
"Erreur de date"
'message d'erreur
[D2] = ""
'remise à vide de D2
Exit Sub
'on va directement à la sortie
End If
'sinon, si B2 et D2 sont correctes (sous-entendu, puisqu'on est arrivé à cette ligne)
Y = Range("A1").SpecialCells(xlCellTypeLastCell).Row
'y=dernière ligne de la feuille
X = IIf(Y < 8, 8, Y)
'x= dernière ligne de la feuille si elle est supérieur à 8, sinon 8
Range("A8:I" & X).Clear
'on efface de A8:Ix (ancien résultat)
Y = 8
With Sheets("Planning général")
'Feuille en préfixe pour les instruction commençant par "."
For X = 6 To .Cells(Rows.Count, "G").End(xlUp).Row
'Pour X=6 à dernière non vide de G de la feuille "Planning général" (mise en préfixe)
If [B2] <= .Cells(X, "G") And .Cells(X, "G") <= [D2] Then
'si B2=<Gx=<D2, alors
.Rows(X).Copy Rows(Y)
'Copier la ligne sur la ligne Y
Y = Y + 1
'augmenter de 1 Y
End If
Next X
End With
Else
MsgBox "vous n'avez pas rempli B2 ou D2"
End If
End Sub
N'ayant plus de lancement automatique, je peux supprimer la gestion des erreurs.
Il me semble préférable que ton bouton lance une macro qui lancera les autres, une par une.
A+
parfait c'est exactement ça! merci beaucoup. désolée de ne pas avoir été assez explicite la première fois! Sinon pas d'idées pour coder qqch qui trouve le numéro de la ligne de la cellule sur laquelle j'ai cliqué ?
Bonne soirée !
Ce site utilise des cookies pour personnaliser le contenu, adapter votre expérience et vous garder connecté si vous vous enregistrez.
En continuant à utiliser ce site, vous consentez à notre utilisation de cookies.