Microsoft 365 Ecrire une formule de calcul en Vba Excel

NONO14

XLDnaute Impliqué
Bonjour à toutes et à tous,

Comment pourrait-on écrire cette formule de calcul en Vba, s'il vous plaît ? Pour le moment elle est écrite en dur dans des cellules Excel de mon tableau.
Cependant, il m'est demandé de l'écrire dans du code afin que personne ne puisse y accéder. Cette formule se trouve dans la colonne J du tableau de la feuille "Recap", il y en d'autres du même genre dans les colonnes K et L et un peu plus simples dans les colonnes M, N, O.
Bien sûr je pourrais protéger ces colonnes mais ce n'est pas ce qui m'est demandé, j'ai proposé cette solution, mais elle ne garantie pas une sécurité suffisante en cas d'effacement malencontreux par la personne qui va gérer ce fichier.
MAX_MAT et autres sont des Noms donnés à des cellules de la feuille "Données", soit les cellules L3 à O5.
Mot de passe de la feuille "falaise"
Merci par avance pour vos idées.
VB:
=SI(A2="";"";SI(A2<>"";SI(ET(D2<>"";E2<>"");E2-D2;SI(ET(D2<>"";E2="";F2<>"");MAX_MAT-D2;SI(ET(D2<>"";E2="";ET(F2<>"";G2=""));"";SI(ET(D2<>"";E2="";F2="";G2="";H2="";I2<>"");MAX_MAT-D2;SI(ET(D2<>"";E2="";F2="";G2<>"");MAX_MAT-D2;SI(ET(D2<>"";E2="";ET(F2="";G2="");ET(H2="";I2<>""));I2-D2;SI(ET(D2<>"";E2="";F2="";G2="");MAX_MAT-D2;SI(D2="";""))))))))))
 

Pièces jointes

  • Tablo_Heures.xlsm
    282.8 KB · Affichages: 16
Dernière édition:
Solution
Bonjour le Fil
juste pour signaler qu'a ce Niveau il y a un problème !
VB:
Private Sub TextCode_Change()
Dim Ctrl As Control
Dim Ctrl2 As Control
Dim Trouvé As Boolean
 Dim Trouve As Range

    Me.TextCode.Text = UCase(Me.TextCode) 'On met en Majuscule tout le Contenu du TextBox
    If Not EnableEvents Then Exit Sub
    Sheets("Liste_agents").Unprotect "falaise"
    'on cherche le nom associé au code dans la TS "t_Noms"
    With Sheets("Liste_agents").ListObjects("t_Noms")
    'ci-dessous on recherche dans une colonne ou se trouvent des Minuscules
    Set Trouve = .ListColumns(1).Range.Find(Me.TextCode, lookat:=xlWhol
Tu peux si la case n'a pas d'importance mettre Option Compare Text en tête de Module.
et supprimer ...

NONO14

XLDnaute Impliqué
C'est parfait ça.
Merci beaucoup, je vais pouvoir passer à autre chose, notamment la sauvegarde du tableau de la feuille "Saisie" et récupérer les plannings pour les transformer en tableau afin que chaque employé(e) ait un exemplaire papier. Il y a encore du boulot sur la planche.
Et puis, quelques bricoles dont je devrais pouvoir m'en sortir.
Encore mille mercis ainsi qu'à TootFatBoy
 

vgendron

XLDnaute Barbatruc
me suis permis de corriger ta macro quand tu selectionnes une élément dans le combobx de la feuille saisie
et mis une partie du code (pour la sauvegarde) dans une sub séparée (que j'ai corrigé aussi)
 

Pièces jointes

  • PointHeure7.xlsm
    683 KB · Affichages: 2

TooFatBoy

XLDnaute Barbatruc
et pourquoi des noms de control avec t_bx_. au lieu de Tbx_ ??
Parce que, comme je te disais précédemment il a changé des Label en TextBox, donc pour simplifier le code, qui du coup ne fonctionnait plus, j'ai gardé le préfixe "Tbx_" uniquement pour les TextBox correspondant aux cases à cocher.


Trop de versions en très peu de temps ! 🤪 🤯
Va falloir les nommer en aaaammjjhhmmss pour s'y retrouver si ça continue comme ça... 😅
 
Dernière édition:

NONO14

XLDnaute Impliqué
Bonjour à toutes et à tous,
Je reviens vers vous afin de vous demander de l'aide car je ne comprends pas le code ci-dessous.
Pourriez-vous me donner quelques explications s'il vous plaît ?
Je vous en remercie par avance et je me coucherai moins idiot ce soir...

VB:
For Each Ctrl In Me.Frame2.Controls
            If TypeName(Ctrl) = "TextBox" Then
                If Left(Ctrl.Name, 4) = "Tbx_" Then
                    Nom = Replace(Ctrl.Name, "Tbx_", "")
                    Ctrl.Enabled = (Ctrl.Value = "")
                    Me.Frame2.Controls("Chk_" & Nom).Enabled = (Ctrl.Value = "")
                    Me.Frame2.Controls("Chk_" & Nom).Visible = (Ctrl.Value = "")
                End If
            End If
        Next Ctrl
 

vgendron

XLDnaute Barbatruc
Héhé.. comme c'est moi qui l'a fait.. j'explique

VB:
For Each Ctrl In Me.Frame2.Controls 'pour chaque control de la frame2
    If TypeName(Ctrl) = "TextBox" Then 's'il s'agit d'un textbox
        If Left(Ctrl.Name, 4) = "Tbx_" Then 'si le nom du control commence par "Tbx_
            Nom = Replace(Ctrl.Name, "Tbx_", "") 'on récupère le nom SANS le préfixe Tbx_'
            Ctrl.Enabled = (Ctrl.Value = "") 'le control est enable si sa valeur est vide, sinon, il est disable'
            Me.Frame2.Controls("Chk_" & Nom).Enabled = (Ctrl.Value = "") 'le checkbox est rendu enable ou disable selon la valeur du ctrl'
            Me.Frame2.Controls("Chk_" & Nom).Visible = (Ctrl.Value = "") 'le checkbox est rendu visible ou pas selon la valeur du control'
        End If
    End If
Next Ctrl

Code:
Ctrl.Enabled = (Ctrl.Value = "")  est équivalent à un
if Ctrl.value="" then
    ctrl.enable=true
else 'il y a une valeur dans le ctrl
   ctrl.enable=false
end if
 

NONO14

XLDnaute Impliqué
Héhé.. comme c'est moi qui l'a fait.. j'explique

VB:
For Each Ctrl In Me.Frame2.Controls 'pour chaque control de la frame2
    If TypeName(Ctrl) = "TextBox" Then 's'il s'agit d'un textbox
        If Left(Ctrl.Name, 4) = "Tbx_" Then 'si le nom du control commence par "Tbx_
            Nom = Replace(Ctrl.Name, "Tbx_", "") 'on récupère le nom SANS le préfixe Tbx_'
            Ctrl.Enabled = (Ctrl.Value = "") 'le control est enable si sa valeur est vide, sinon, il est disable'
            Me.Frame2.Controls("Chk_" & Nom).Enabled = (Ctrl.Value = "") 'le checkbox est rendu enable ou disable selon la valeur du ctrl'
            Me.Frame2.Controls("Chk_" & Nom).Visible = (Ctrl.Value = "") 'le checkbox est rendu visible ou pas selon la valeur du control'
        End If
    End If
Next Ctrl

Code:
Ctrl.Enabled = (Ctrl.Value = "")  est équivalent à un
if Ctrl.value="" then
    ctrl.enable=true
else 'il y a une valeur dans le ctrl
   ctrl.enable=false
end if
Bonjour à vous deux,
Merci beaucoup pour ces explications, c'est beaucoup plus clair dans ma tête à présent.
Je vais m'en inspirer pour une autre partie du code, parce que j'ai fait une usine à gaz !!!!
 

NONO14

XLDnaute Impliqué
Voici mon fichier.
J'ai apporté les modifications suivantes :
- Terminé les tableaux de la feuille type
- Inséré la création d'un(e) employé(e) dans le formulaire UfGestTemps (cela fait un UF de moins)
- Modifié les codes dans le formulaire UfPointage au niveau de TextCode_Change. Pour le moment c'est l'usine à gaz. J'ai dû procéder de cette façon afin d'aborder le maximum de possibilités et de comprendre ce que je faisais.
- Supprimé le formulaire UfSauvTab qui ne servait à rien.

Je vous accorde le fait que ce que j'ai fait n'est pas très joli, mais je vais arranger ça, au moins je vais essayer.
 

Pièces jointes

  • PointHeure9.xlsm
    678.7 KB · Affichages: 2

vgendron

XLDnaute Barbatruc
Hello

dans le code du TexCode_Change,
il y a des redondances ==> tu refais ce qui a été fait juste avant..

1) la boucle que je t'ai expliquée, affiche ou masque les CheckBox si il y a une saisie ou pas dans le textbox associé

2) ensuite, il y a une serie de test "if..... then" pour chaque checkbox ==> ca refait la meme chose ==> inutile

3) après tu as toute la série des if pour afficher ou pas, et mettre le message d'autorisation de badger
l'usine à gaz est peut etre la...
mais encore une fois.. ca refait ce qui a déjà été fait dans la boucle..
==> comme il semble y avoir pas mal de conditions dans ces if, peut etre que c'est la boucle qui est inutile...?

Dans le code de "CalculerTotalJournée"
il faut revoir, parce que tu y a fait des modifs par rapport à mon original qui n'ont pas de sens..
exemple
Total=cdate(Total=0)

(Total=0)==> retourne Vrai ou faux
cdate( vrai ou faux)==> ca ne donnera jamais une date
enfin.. si.; mais pas du tout ce que tu penses
Vrai = 1==> Cdate(1) = 01/01/1900 00:00
Faux=0 ==>Cdate(0) = 00/01/1900 00:00
 

NONO14

XLDnaute Impliqué
Hello

dans le code du TexCode_Change,
il y a des redondances ==> tu refais ce qui a été fait juste avant..

1) la boucle que je t'ai expliquée, affiche ou masque les CheckBox si il y a une saisie ou pas dans le textbox associé

2) ensuite, il y a une serie de test "if..... then" pour chaque checkbox ==> ca refait la meme chose ==> inutile

3) après tu as toute la série des if pour afficher ou pas, et mettre le message d'autorisation de badger
l'usine à gaz est peut etre la...
mais encore une fois.. ca refait ce qui a déjà été fait dans la boucle..
==> comme il semble y avoir pas mal de conditions dans ces if, peut etre que c'est la boucle qui est inutile...?

Dans le code de "CalculerTotalJournée"
il faut revoir, parce que tu y a fait des modifs par rapport à mon original qui n'ont pas de sens..
exemple
Total=cdate(Total=0)

(Total=0)==> retourne Vrai ou faux
cdate( vrai ou faux)==> ca ne donnera jamais une date
enfin.. si.; mais pas du tout ce que tu penses
Vrai = 1==> Cdate(1) = 01/01/1900 00:00
Faux=0 ==>Cdate(0) = 00/01/1900 00:00
Bonjour vgendron,
Merci pour ta réponse et tes bons conseils. Je suis entrain de revoir tous ça afin que ce soit propre.
Je vais regarder pour les redondances, je n'y ais pas prêter attention, j'ai imaginé les différents scénarios et taper le code en la circonstances. Allez, je m'y mets...
Encore merci pour ta précieuse aide. Je m'aperçois qu'il n'est pas si facile de se mettre dans la peau d'un utilisateur et d'imaginer ce qu'il pourrait faire à tel ou tel moment.
 

vgendron

XLDnaute Barbatruc
il y a un pb dans ton code associé au bouton annuler

teste la séquence suivante
FAL465==> la ligne est chargée
tu pointes.. ou pas..
Annuler
FAL465 ==> la ligne n'est plus chargée... parce que la date a aussi été effacée

modifier le code comme suit:
VB:
Private Sub Btx_Annul_Click()
Dim Ctrl As Control

    EnableEvents = False
    Me.TextCode.Value = ""
    Me.T_bx_Noms.Value = ""
    Me.Lbx_Information.Caption = "Veuillez saisir votre code employé(e)"
    
    For Each Ctrl In Frame2.Controls
        Me.Chk_DebMat.BackColor = RGB(160, 255, 255)
        Me.Chk_DebAPM.BackColor = RGB(160, 255, 255)
        Me.Chk_DebSoir.BackColor = RGB(160, 255, 255)
        
        Select Case TypeName(Ctrl)
            Case "CheckBox"
                Ctrl.Value = False
                Ctrl.Enabled = True
                Ctrl.Visible = True
            Case "TextBox"
                Ctrl.Value = ""
        End Select
    Next Ctrl
    Me.T_bx_DateJour.Value = Format(Now, "dddd dd mmm yyyy") 'remettre la date, sinon le prochain TextCode_Change ne trouvera pas la ligne
    EnableEvents = True
End Sub
 

vgendron

XLDnaute Barbatruc
pour les différents tests if que tu as faits
la question est: tu vérifies quoi? = tu autorises quoi?

ce que je pense:
on ne peut pas pointer un horaire (début ou fin) entre deux pointages déjà faits... correct?
ex:
Début matin pointé
Fin Matin "oublié
Début APM pointé

==> nouveau pointage: ne peut pas être fin matin, mais uniquement tout ce qui est après le dernier pointage (Début APM)

dans ce cas.. il "suffirait" de trouver le dernier pointage effectué puis laisser enable les pointages suivants et désactiver les précédents
 

Discussions similaires

Réponses
9
Affichages
436
Réponses
5
Affichages
406
Réponses
3
Affichages
224