XL 2016 Additionner des heures - multi-critères

  • Initiateur de la discussion Initiateur de la discussion halecs93
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

halecs93

XLDnaute Impliqué
Bonjour,

Je cherche à additionner des heures selon plusieurs critères :

Le contenu de L2 et une période définie par un formulaire.

Une âme charitable, ou plusieurs même 😉, aurait une solution ?

Un grand grand merci.

1744203954234.png
 

Pièces jointes

Solution
Bonjour halecs93, le forum,

Pour renseigner les cellules J3, J34... et K3 il suffit d'utiliser la fonction SOMME.SI.

J'ai aussi revu en plus simple la macro Worksheet_Change :
VB:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim c As Range, s
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    On Error Resume Next 'si les heures ne sont pas correctes
    For Each c In [C2:G152]
        s = Split(c.Text, "-")
        If UBound(s) = 1 Then c(2) = "": c(2) = CDate(s(1)) - CDate(s(0)): If c(2) < 0 Then c(2) = CDate(s(1)) + 1 - CDate(s(0))
    Next c
    Application.EnableEvents = True
    If Not Intersect([L2], Target) Is Nothing And [L2] <> "" Then UserForm1.Show
End Sub
A+
Hi,


Euh... et qu'y sont lesdits critères ??? 🤔

"contenu de L2"... soit, mais y a-t-il une fourchette de valeurs qui implique quelque chose dans l'addition à effectuer, etc.
Bonjour

Simplement, si je retrouve le même contenu que L2 dans le tableau.... et entre les deux dates définies par le formulaire, alors je prends la valeur au dessus, qui apparait entre parenthèses), et ainsi de suite jusqu'à la dernière date définie .

Par exemple, L2 apparait plusieurs fois entre le 3/3/2025 et le 31/3/2025.... je peux facilement additionner les heures qui y sont associées.... mais je veux aussi pouvoir définir la même chose entre le 7/3/2025 et le 15/03205....
 
Bonjour halecs93, TooFatBoy,

Le code de l'UserForm :
VB:
Private Sub CommandButton1_Click()
    Dim ref$, date1 As Date, date2 As Date, i&, j%, k&, resu#
    ref = [L2]
    If Not IsDate(TextBox1) Then TextBox1 = "": TextBox1.SetFocus: Exit Sub
    If Not IsDate(TextBox2) Then TextBox2 = "": TextBox2.SetFocus: Exit Sub
    date1 = CLng(Application.Min(CDate(TextBox1), CDate(TextBox2)))
    date2 = CLng(Application.Max(CDate(TextBox1), CDate(TextBox2)))
    For i = 1 To 125 Step 31
        For j = 3 To 7
            If Cells(i, j) >= date1 And Cells(i, j) <= date2 Then
                For k = i + 3 To i + 29
                    If Cells(k, j) = ref Then
                        If IsNumeric(Cells(k - 1, j)) Then resu = resu + CDbl(Cells(k - 1, j))
                    End If
                Next k
            End If
    Next j, i
    [L3] = resu
End Sub
   
Private Sub UserForm_Initialize()
If [L2] = "" Then [L3] = "": End 'l'UserForm ne s'ouvre pas
End Sub
Il ne faut pas modifier la position des lignes et colonnes du tableau.

A+
 

Pièces jointes

Bonjour halecs93, TooFatBoy,

Le code de l'UserForm :
VB:
Private Sub CommandButton1_Click()
    Dim ref$, date1 As Date, date2 As Date, i&, j%, k&, resu#
    ref = [L2]
    If Not IsDate(TextBox1) Then TextBox1 = "": TextBox1.SetFocus: Exit Sub
    If Not IsDate(TextBox2) Then TextBox2 = "": TextBox2.SetFocus: Exit Sub
    date1 = CLng(Application.Min(CDate(TextBox1), CDate(TextBox2)))
    date2 = CLng(Application.Max(CDate(TextBox1), CDate(TextBox2)))
    For i = 1 To 125 Step 31
        For j = 3 To 7
            If Cells(i, j) >= date1 And Cells(i, j) <= date2 Then
                For k = i + 3 To i + 29
                    If Cells(k, j) = ref Then
                        If IsNumeric(Cells(k - 1, j)) Then resu = resu + CDbl(Cells(k - 1, j))
                    End If
                Next k
            End If
    Next j, i
    [L3] = resu
End Sub
  
Private Sub UserForm_Initialize()
If [L2] = "" Then [L3] = "": End 'l'UserForm ne s'ouvre pas
End Sub
Il ne faut pas modifier la position des lignes et colonnes du tableau.

A+
Que répondre....? Waou....? Je le fais. Merci !!!!
 
Bonjour halecs93, TooFatBoy,

Le code de l'UserForm :
VB:
Private Sub CommandButton1_Click()
    Dim ref$, date1 As Date, date2 As Date, i&, j%, k&, resu#
    ref = [L2]
    If Not IsDate(TextBox1) Then TextBox1 = "": TextBox1.SetFocus: Exit Sub
    If Not IsDate(TextBox2) Then TextBox2 = "": TextBox2.SetFocus: Exit Sub
    date1 = CLng(Application.Min(CDate(TextBox1), CDate(TextBox2)))
    date2 = CLng(Application.Max(CDate(TextBox1), CDate(TextBox2)))
    For i = 1 To 125 Step 31
        For j = 3 To 7
            If Cells(i, j) >= date1 And Cells(i, j) <= date2 Then
                For k = i + 3 To i + 29
                    If Cells(k, j) = ref Then
                        If IsNumeric(Cells(k - 1, j)) Then resu = resu + CDbl(Cells(k - 1, j))
                    End If
                Next k
            End If
    Next j, i
    [L3] = resu
End Sub
  
Private Sub UserForm_Initialize()
If [L2] = "" Then [L3] = "": End 'l'UserForm ne s'ouvre pas
End Sub
Il ne faut pas modifier la position des lignes et colonnes du tableau.

A+
Encore un grand merci.... quelques lignes et ça semble tout simple.... peut-être serait-il possible de choisir le lieu directement dans le formulaire ?
 
Bonjour halecs93, le forum,

Pour renseigner les cellules J3, J34... et K3 il suffit d'utiliser la fonction SOMME.SI.

J'ai aussi revu en plus simple la macro Worksheet_Change :
VB:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim c As Range, s
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    On Error Resume Next 'si les heures ne sont pas correctes
    For Each c In [C2:G152]
        s = Split(c.Text, "-")
        If UBound(s) = 1 Then c(2) = "": c(2) = CDate(s(1)) - CDate(s(0)): If c(2) < 0 Then c(2) = CDate(s(1)) + 1 - CDate(s(0))
    Next c
    Application.EnableEvents = True
    If Not Intersect([L2], Target) Is Nothing And [L2] <> "" Then UserForm1.Show
End Sub
A+
 

Pièces jointes

Bonjour halecs93, le forum,

Pour renseigner les cellules J3, J34... et K3 il suffit d'utiliser la fonction SOMME.SI.

J'ai aussi revu en plus simple la macro Worksheet_Change :
VB:
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim c As Range, s
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    On Error Resume Next 'si les heures ne sont pas correctes
    For Each c In [C2:G152]
        s = Split(c.Text, "-")
        If UBound(s) = 1 Then c(2) = "": c(2) = CDate(s(1)) - CDate(s(0)): If c(2) < 0 Then c(2) = CDate(s(1)) + 1 - CDate(s(0))
    Next c
    Application.EnableEvents = True
    If Not Intersect([L2], Target) Is Nothing And [L2] <> "" Then UserForm1.Show
End Sub
A+
Hello.... et encore merci pour cette fulgurante amélioration.
 
Bonjour halecs93, le forum,

Avez vous bien compris pourquoi j'utilise s = Split(c.Text, "-") et non pas s = Split(c.Value, "-") ?

Parce qu'en C3 par exemple c.Value a la valeur 7,29166666666667E-02 et que donc cette cellule serait traitée.

.Text renvoie ce qui est affiché.

A+
 
En fait on peut se passer de VBA et utiliser uniquement des formules.

Formule en C3 à copier vers la droite et dans les lignes concernées :
Code:
=SIERREUR(SUPPRESPACE(STXT(C2;TROUVE("-";C2)+1;9))-GAUCHE(C2;TROUVE("-";C2)-1);"")
Formule en M3, assez difficile à bien comprendre :
Code:
=SOMMEPROD((Date1>=L2)*(Date1<=L3)*(C4:G30=M2);C3:G29)+SOMMEPROD((Date2>=L2)*(Date2<=L3)*(C35:G61=M2);C34:G60)+SOMMEPROD((Date3>=L2)*(Date3<=L3)*(C66:G92=M2);C65:G91)+SOMMEPROD((Date4>=L2)*(Date4<=L3)*(C97:G123=M2);C96:G122)+SOMMEPROD((Date5>=L2)*(Date5<=L3)*(C128:G154=M2);C127:G153)
Voyez les noms définis Date1 Date2 Date3 Date4 Date5.

Les cellules contenant des formules sont verrouillées et la feuille est protégée (sans mot de passe).

Bonne nuit.
 

Pièces jointes

Bonjour halecs93, JM, le forum,

Je découvre que Date1... Date5 ne sont pas du tout nécessaires, formule en M3 :
Code:
=SOMMEPROD((C1:G1>=L2)*(C1:G1<=L3)*(C4:G30=M2);C3:G29)+SOMMEPROD((C32:G32>=L2)*(C32:G32<=L3)*(C35:G61=M2);C34:G60)+SOMMEPROD((C63:G63>=L2)*(C63:G63<=L3)*(C66:G92=M2);C65:G91)+SOMMEPROD((C94:G94>=L2)*(C94:G94<=L3)*(C97:G123=M2);C96:G122)+SOMMEPROD((C125:G125>=L2)*(C125:G125<=L3)*(C128:G154=M2);C127:G153)
Je croyais que dans SOMMEPROD les plages devaient toujours avoir mêmes dimensions, on voit ici que ce n'est pas vrai..

A+
 

Pièces jointes

- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
3
Affichages
92
Retour