Optimisation du code VBA redondant

Bonjour à tous !

Ca faisait un bail !

Je me suis remis à coder en VBA sur excel pour le plaisir (et un peu sur autocad mais c'est pas le sujet)

Je viens vers vous car j'ai codé un fichier et vous regardez mon code , pour chaque spinbutton j'ai presque exactement la même chose en terme de code (je met des [...] pour passer les passages inutiles)

Lien du fichier :

6pour-export.xlsm (24.14 Ko)
Private Sub spn_AGI_SpinUp()

   [...]
    spn_AGI.Max = 5
    spn_AGI.Min = 1
    [...]
                spn_AGI.Value = Range("AGI").Value 'alors on annule l'incrémentation du spin
   [...]
        Range("AGI").Value = spn_AGI.Value 'sinon on l'autorise
   [...]
End Sub
Private Sub spn_AGI_SpinDown()

et rebelotte :

Private Sub spn_CONN_SpinUp()

   [...]
    spn_CONN.Max = 5
    spn_CONN.Min = 1
      [...]
                spn_CONN.Value = Range("CONN").Value 'alors on annule l'incrémentation du spin
   [...]
        Range("CONN").Value = spn_CONN.Value 'sinon on l'autorise
   [...]
End Sub
Private Sub spn_CONN_SpinDown()

etc etc...

On voit bien qu'il n'y a que AGI qui change en CONN ; d'ailleurs une fois codé pour le bouton AGI je fais un copier coller du code et je remplace AGI par CONN (avec un ctrl+h qui va bien) et en avant guingamp !

Mais du coup je me dis qu'il doit y avoir moyen d'optimiser mon code non ?

Par exemple un genre de fonction Private Sub spn_XXX_SpinUp() avec XXX qui changerait de tag au fur et à mesure pour coder le machin qu'une fois ?

En vous remerciant par avance du temps que vous me consacrerez ; dans l'attente de vos réponses

Cordialement

NL

Bonsoir,

Sub spn_SpinUp(spn As String)
    Dim v%, blnC As Boolean
    blnC = True
    v = Me.OLEObjects("spn_" & spn).Object.Value
    If Range(spn) = 4 Then
        If WorksheetFunction.Max(Range("APTITUDES")) = 5 Then
            blnC = False
            MsgBox "Vous ne pouvez avoir qu'une seule aptitude à 5"
        End If
    End If
    If blnC Then
        If WorksheetFunction.Sum(Range("APTITUDES")) >= Range("pt_APTITUDES") Then
            blnC = False
            MsgBox "Vous avez déja dépensé vos 35 points d'aptitudes !"
        End If
    End If
    If blnC Then
        Range(spn) = v
    Else
        v = Range(spn)
        Me.OLEObjects("spn_" & spn).Object.Value = v
    End If
End Sub

Private Sub spn_AGI_SpinUp()
    spn_SpinUp "AGI"
End Sub

Même chose pour les autres SpinUp...

Max et Min des spin définies comme propriétés par défaut (fenêtre de propriétés) le sont un fois pour toutes...

Bonjour,

Autre proposition : changer le max quand un 5 est mis

Sub spinMax(nomObj, maxi)
    Dim Obj As OLEObject
    For Each Obj In ActiveSheet.OLEObjects
        If TypeName(Obj.Object) = "SpinButton" Then
            If Obj.Name <> nomObj Then Obj.Object.Max = maxi
        End If
    Next Obj
End Sub

Sub appel()
    spinMax spn_AGI.Name, 4 ' tous sauf spn_AGI
    spinMax "", 4 ' tous
End Sub

Tous les spinButton auront leur max à 4, sauf celui passé en paramètre

Plus de contrôle à faire ni de message d'erreur pour l'utilisateur.

Bien sûr les refaire passer à 5 si le 5 passe en 4

Ou bien, sur le même principe, faire une proc unique pour régler tous les maxi selon les règles de distribution (1 seul 5, 31 maxi)

eric

Salut Eric !

Idée intéressante, mais en cas de rétrogradation du 5 à 4, il faut alors remettre tous les Max à 5...

edit : j'avais pas lu la fin ! Je vais aller me coucher !

Cela évite de tester le 5... Mais pour le total on ne peut jouer sur les Max...

Salut MFerrand,

Mais pour le total on ne peut jouer sur les Max...

Ben si, il suffit de faire comme toi la somme sur la feuille et regarder s'il reste encore au moins 1 point à distribuer.

Ou faire la somme des .value sur une autre boucle des toupies.

eric

Oui on fait la somme pour tester, mais cela ne peut conduire à une modification des Max...

Dans le cas de 5, uen seul pouvant y accéder, on peut jouer sur le Max qui est individuel : tous ont vocation à aller à 5 tant que personne n'y est, dès que l'un emporte la palme, le max individuel de chacun peut rétrograder pour tous les autre, mais si le tenant perd la palme, réactivation du Max à 5 pour tous.

Pour le total, qui ne doit pas dépasser 35, serait-on à 34, cela ne peut influer sur le Max individuel de chacun, qui a toujours vocation pour atteindre 4.

Et même : 2 à 4, 8 à 3, total :35 , le Max sera à 5 pour tous, car personne ne l'a et tous conservent cette possibilité, momentanément irréalisable en fonction du total mais qui peut à tout moment le redevenir.

Un autre aspect du passage du Max à 4 quand l'un atteint 5 : cela ôte la possibilité du message d'info qu'un seul peut être à 5 (on peut juste la transférer sur le moment où l'un atteint 5... mais ce n'est plus pareil).

Bonne journée.

Re

Et même : 2 à 4, 8 à 3, total :35 , le Max sera à 5 pour tous, car personne ne l'a et tous conservent cette possibilité, momentanément irréalisable en fonction du total mais qui peut à tout moment le redevenir.

Si la somme = 34 on peut toujours ajouter un point, rien ne change. Si la somme = 35 les max deviennent = .value

Un autre aspect du passage du Max à 4 quand l'un atteint 5 : cela ôte la possibilité du message d'info

oui, dit ici : "Plus de contrôle à faire ni de message d'erreur pour l'utilisateur."

D'un autre coté si son compteur est bloqué à 4 il finira bien par penser "ah oui c'est vrai, j'ai déjà attribué un 5, ou je n'ai plus de points"

Si le message est indispensable, oui, ça n'ira pas écrit comme ça.

Mais rien n'empêche de ne pas toucher aux max dans ce sub et de mettre à la place des messages d'alerte.

Je ne fais pas la promotion de ma solution. C'était juste pour lui montrer une autre possibilité, sa demande première étant de diminuer le nombre de ligne de code similaires sur tous les spinbuttons pour les regrouper dans un sub commun à appeler. Le point important étant de récupèrer l'info du spinbutton activé.

A lui de choisir selon son besoin exact et de voir si ça vaut vraiment le coup de déporter des lignes dans un autre sub

eric

Je ne défends pas une position par rapport à une autre... C'était juste pour racler et extraire les implications au Max !

Merci

je vais prendrel a premiere solution car pour la suite de ce que je vais faire elle me parait plus adapté.

Rechercher des sujets similaires à "optimisation code vba redondant"