Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2010 Une fonction personnalisée au comportement étonnant

Magic_Doctor

XLDnaute Barbatruc
Bonsoir,

Je me heurte à un problème avec une fonction personnalisée.
Dans le paramétrage de cette fonction, il y a 2 paramètres optionnels : un pour un compteur (que l’on omettra), l’autre pour une valeur qui ne peut être dépassée.
Supposons que la valeur indépassable soit, par exemple, 3,45. Si je rentre dans la cellule :
3,3 --> 3° 3’
3,4 --> 3° 4’
3,44 --> 3° 44’
3,48 --> 3° 45’
3,57 --> 3° 45’

Mais, curieusement :
3,5 ou 3,6 ou 3,7 ou 3,8 ou 3,9 --> non pas 3° 5’ ou … 3° 9’, mais toujours 3° 45’.

Comment régler ce problème ?

La fonction :
VB:
Function ConvertirDecimal$(NbDec$, ChxDegGr As Byte, Optional compteur, Optional max)
'Retranscrit une valeur décimale en format TEXTE (qui ne doit pas dépasser 2 décimales après la virgule) en degrés & minutes ou grades
'- NbDec : un nombre entier ou décimal qui n'excède alors pas 2 chiffres après la virgule
'- ChxDegGr : si 1 --> degrés sous forme, par exemple : 42,75 <=> 42° 75'
'             si 2 --> grades
'- compteur : un numéro de compteur (1, 2, 3...)
'             si omis --> pas de signe +/- avant la chaîne de caractères
'             si stipulé --> un signe +/- (suivant la valeur du compteur) avant la chaîne de caractères
'             Ex : pour degrés --> compteur omis : 42,25 --> 42° 25'
'                                  compteur stipulé (suivant la valeur de celui-ci) : + 42° 25' | - 42° 25'
'                  pour grades --> compteur omis : 55,75 --> 55,75 gr
'                                  compteur stipulé (suivant la valeur de celui-ci) : + 55,75 gr | - 55,75 gr
'- max : une valeur que ne peut dépasser la variable "NbDec"
'Magic_Doctor

Dim verif As Boolean, deg%, min As Byte, largo As Byte, pos As Byte, pref$
    
    On Error Resume Next                                        'sinon bordel incompréhensible
    
    If IsMissing(max) = False And NbDec > max Then NbDec = max  '"NbDec" <= "max"
    
    verif = IIf(NbDec = Int(NbDec), True, False)                'vérifie si NbDec est entier ou pas
    deg = Int(NbDec)                                            'nombre de degrés (à gauche de la virgule)
    largo = Len(NbDec): pos = InStr(NbDec, ",")
    min = IIf(verif = False, Right(NbDec, largo - pos), 0)      'nombre de minutes (à droite de la virgule)
    
    If IsMissing(compteur) Then
        If ChxDegGr = 1 Then                                    'saisie en degrés sexagésimaux
            ConvertirDecimal = deg & "°" & IIf(min = 0, "", " " & min & "'")
        Else                                                    'saisie en grades
            ConvertirDecimal = NbDec & " gr"
        End If
    Else
'        pref = IIf(compt(compteur) = 1, "+ ", "- ")             'symbole "+/-" qui précède la chaîne de caractères suivant la valeur de "compt(compteur)"
'        If ChxDegGr = 1 Then                                    'saisie en degrés sexagésimaux
'            ConvertirDecimal = IIf(deg = 0 And min = 0, "", pref) & deg & "°" & IIf(min = 0, "", " " & min & "'")
'        Else                                                    'saisie en grades
'            ConvertirDecimal = IIf(NbDec = 0, "", pref) & NbDec & " gr"
'        End If
    End If

End Function
 

Pièces jointes

  • Fonction.xlsm
    17.2 KB · Affichages: 27
Solution
Re,

laurent 950, je viens encore d'essayer, ça bloque à l'ouverture.
Comment vous faite la gestion du compteur avec IsMissing ?
Dans mon application il y a plusieurs compteurs (compt(1), compt(2)...). Chacun de ces compteurs a en général 2 options (mais on pourrait en mettre 36 pour le même compteur).
En paramétrage de la fonction on peut mettre un numéro de compteur (numéro qui se trouve entre les parenthèses qui suivent compt). Le compteur en paramétrage a 2 options : si 1 --> + | si 2 --> -

J'en profite pour glisser ma dernière mouture. Maintenant ça marche (!!!) et avec une seule fonction (en utilisant la seconde ça déconnait) :
VB:
Function ConvertirDecimal$(NbDec$, ChxDegGr As Byte, Optional compteur, Optional max)...

TooFatBoy

XLDnaute Barbatruc
Marcel32, je m'en tamponne le coquillard des conventions internationales ! Vous n'en avez pas marre des règlements...
Les règles, et non règlements, ça permet généralement de vivre correctement ensemble ou de se faire comprendre.
Sans règles, ça peut vite devenir le bazar...
Rien que la règle qui dit qu'on doit tous rouler à droite en France, je trouve ça pas mal... lol
Donc non, je n'en ai pas spécialement marre des règles.

Il n'y a absolument rien de trouble quant à mon choix arbitraire.
Si, c'est troublant. J'ai déjà expliqué pourquoi et ne vais donc pas y revenir.

Plutôt que d'utiliser 2 cellules
...
ce qui figure sur les cartes.
Comme dit précédemment, nous l'avions bien compris. Et si c'est ce qui te semble le mieux, alors pas de souci, c'est comme cela qu'il faut procéder.

Enfin, la virgule me paraît nettement plus parlante, lors d'une saisie, que l'espace (voir PJ) ; mais là c'est un détail superfétatoire (on pourrait tout aussi bien mettre un slash ou ce que vous voudrez).
Comme dit plus haut, je ne citais l'espace que comme exemple, car c'est justement la virgule qui apporte le trouble, mais tout caractère peut être utilisé.
(je n'ai pas la possibilité d'ouvrir les .xlsm)

La seule chose qui compte, c'est que la convention utilisée convienne à l'utilisateur.
Le reste n'est pas très important.


Sur ce, bonne soirée et @+
 

Magic_Doctor

XLDnaute Barbatruc
Re,
Marcel32, en l'occurrence, je m'en tamponne le coquillard des conventions internationales !
J'ai bien compris les règles internationales. Je suis du reste un fervent défenseur du système métrique, n'en déplaise aux Zuniens et autres Anglo-Saxons ; je serais même partisan que nous conduisions tous du bon côté, à savoir à droite ; que nous ayons tous des claviers QWERTY (que je sache, l'AZERTY n'existe qu'en France) ; je suis même un adepte de la terminologie anatomique en latin, comme le prônent les Anglo-Saxons ; je proposerais même, pendant qu'on y est, que tous les pays qui pratiquent ces maudits horaires d'hiver et d'été changent TOUS l'heure le même jour...

Mais vous êtes têtus ! Il s'agit là ni plus ni moins que d'une saisie, et, sur ce coup-là, vos commentaires n'ont jamais fait avancer le Schmilblic...
 

laurent950

XLDnaute Barbatruc
Re @Magic_Doctor
If IsMissing(compteur) Then
si compteur n'est pas renseigné cela rentre dans la condition ' =ConvertirDecimal(Entrée;1;;Max)
mais si compteur est renseigner (Cela ne rentrera jamais dans la condition '=ConvertirDecimal(Entrée;1;1;Max) Ou '=ConvertirDecimal(Entrée;1;2;Max) Ou '=ConvertirDecimal(Entrée;1;3;Max) Ect.
Poste #15
si c'est décoché alors Optional compteur (Ici avec des Nombres Impaires c'est + et Paires -)
Peut être avec ByVal Optional compteur as Boolean et comme choix : Choix 0 = True ou 1 = False
et donc
Dans mon application il y a plusieurs compteurs (compt(1), compt(2)...). Chacun de ces compteurs a en général 2 options (mais on pourrait en mettre 36 pour le même compteur).
En paramétrage de la fonction on peut mettre un numéro de compteur (numéro qui se trouve entre les parenthèses qui suivent compt). Le compteur en paramétrage a 2 options : si 1 --> + | si 2 --> -
Pour
pref = IIf(compt(compteur) = 1, "+ ", "- ")
ByVal Optional compteur() as Boolean
Comment vous amener votre variable tableau compt dans cette fonction ?
 
Dernière édition:

Modeste geedee

XLDnaute Barbatruc
Bonsour®
Mais vous êtes têtus ! Il s'agit là ni plus ni moins que d'une saisie, et, sur ce coup-là, vos commentaires n'ont jamais fait avancer le Schmilblic...

comme dit @Marcel32 :
La seule chose qui compte, c'est que la convention utilisée convienne à l'utilisateur.
Le reste n'est pas très important.
si c'est uniquement pour n'utiliser que le pavé numérique (un seul doigt ???)
en quoi la solution "Correction automatique lors de la saisie ne te convient pas ???
(une seule touche en plus , pas de macro, ni prise de tête)

mnémotechnique :
/, pour mémoriser que ce n'est pas le séparateur décimal mais °


 
Dernière édition:

TooFatBoy

XLDnaute Barbatruc
Pardon @Modeste geedee mais si je comprends bien, il faudrait alors taper systématiquement le slash et la virgule ?

Je crois que cela va à l'encontre de ce qui est ici recherché : saisir le moins de touches possibles.

Et dans ce cas, il vaut mieux taper 3,5 pour 3° 50' et taper 3,05 pour 3° 5', ça permet de retrouver une logique de nombre décimal (même si ça n'en est pas réellement un) et ça ne fait pas plus de touches à saisir par rapport au "slash virgule".


Ceci dit, j'aime tout de même beaucoup la méthode que tu proposes, car j'avoue que je n'aurais jamais pensé à utiliser cette fonction de remplacement automatique dans ce but. Je trouve cela très rusé.
 

Magic_Doctor

XLDnaute Barbatruc
Re,

Pour le(s) compteur(s) :
VB:
Sub Compteurs(n As Byte, x As Byte)
'Administre tous les compteurs de la feuille
'- n : numéro du compteur
'- x : incrémentation
'job75 / Magic_Doctor

    compt(n) = IIf(IsNumeric(Evaluate("Compteur" & n)), Evaluate("Compteur" & n), 0)
    compt(n) = IIf(compt(n) < x, compt(n) + 1, 1)
    ActiveWorkbook.Names.Add Name:="Compteur" & n, RefersTo:=compt(n), Visible:=False

End Sub
Exemple :
VB:
Sub DeclinaisonPositveNegative()

    Compteurs 1, 2                            '--> compt(1) (2 options)

    With [Cel_Rollover1]                       
        .Value = IIf(compt(1) = 1, "E", "W")
    End With

End Sub
Important : déclarer les compteurs en Public dans un module standard, comme, par exemple, ceci :
VB:
Option Explicit

Public compt(1 To 6) As Byte  '6 compteurs : compt(1) --> cellule nommée "Cardinal" (Rollover)
'                                            compt(2) --> cellule nommée "TitreTripVolOiseau" (Rollover)
'                                            compt(3) --> Boutons Options "OptionButton_Deg" & "OptionButton_Gr"
'                                            compt(4) --> cellule nommée "DateTripDeltaCor" (Rollover)
'                                            compt(5) --> label de l'UF "UF_DM" où figurent les points cardinaux "E" & "W" pour la saisie en degrés sexagésimaux
'                                            compt(6) --> label de l'UF "UF_DM" où figurent les points cardinaux "E" & "W" pour la saisie en grades

Soyons un peu sérieux. Pour 3° 49' on entrera forcément 3,49. Pour 3° 51', 3,51. Et d'un seul coup, d'un seul, pour 3° 50' on rentre 3,5... Un peu schizophrénique comme démarche.
Il n'y a strictement aucune logique ici, ce n'est tout simplement qu'une convention pour une application !

Modeste geedee, jonglant très mal dans les options d'Excel (en fait, il n'y a que le VBA qui m'intéresse, je ne sais même pas ce que c'est vraiment un TCD, n'utilisant Excel que pour des trucs très précis pour des raisons professionnelles ou triviales), je préfère la solution VBA. Regarde mon post#15, la fonction est ma foi courte, elle marche enfin bien et gère en fin de compte pas mal de trucs pour la saisie. À aucun moment on ressent un ralentissement de la bécane, et pour finir, j'adore les fonctions personnalisées.
 
Dernière édition:

Modeste geedee

XLDnaute Barbatruc
Bonsour®
Ceci dit, j'aime tout de même beaucoup la méthode que tu proposes, car j'avoue que je n'aurais jamais pensé à utiliser cette fonction de remplacement automatique dans ce but. Je trouve cela très rusé.

J'ajouterai que l'amalgame numérique notation décimale/notation sexagésimale est casse-gueule au possible notamment au-delà de 59 centièmes …

MIMO (Merde In, Merde Out)
cette histoire de limitation/troncature à 45' me hérisse quand on parle de degrés ...

J'en resterai donc à :
La seule chose qui compte, c'est que la convention utilisée convienne à l'utilisateur.
 

laurent950

XLDnaute Barbatruc
Function ConvertirDecimal$(NbDec$, ChxDegGr As Byte, Optional compteur, Optional max)
Donc en ayant compris que le compteur est déclaré en Public :
Public compt(1 To 6) As Byte
donc compteurs :
compt(1) --> cellule nommée "Cardinal" (Rollover) ' Variable tableau 1 case pour un Range
compt(2) --> cellule nommée "TitreTripVolOiseau" (Rollover) ' Variable tableau 1 case pour un Range
compt(3) --> Boutons Options "OptionButton_Deg" & "OptionButton_Gr" ' Variable tableau 2 Cases pour un Boolean
compt(4) --> cellule nommée "DateTripDeltaCor" (Rollover) ' Variable tableau 1 case pour un Range
compt(5) --> label de l'UF "UF_DM" où figurent les points cardinaux "E" & "W" pour la saisie en degrés sexagésimaux ' J'imagine une variable tableau 2 Cases pour un Boolean
compt(6) --> label de l'UF "UF_DM" où figurent les points cardinaux "E" & "W" pour la saisie en grades ' J'imagine une variable tableau 2 Cases pour un Boolean
Donc Ici : =ConvertirDecimal(Entrée;1;1;Max) pour compt(1) ' Pour Compteur = 1
=ConvertirDecimal(Entrée;1;2;Max) pour compt(2) ' Pour Compteur = 2
= Etc.
Comment vous faite pour vous y retrouver quand vous rentrer votre fonction personnalisé (il n'y a aucune aide ?) sans y revenir un certain temps il faut se replonger dans le code !
Alors :
Function ConvertirDecimal$(NbDec$, ChxDegGr As Byte, Optional compteur, Optional max)
ici : Optional compteur est bien de type Byte (de 1 à 255) comme il y a bien 6 case pour variable tableau compte

mais c'est des un tableaux qui en contient d'autres !
donc j'aurais plutôt vu se tableau en variant :
Public compte(1 To 6) As Byte ------->> Changer par ------->> Public compte(1 To 6) As Variant
et donc la case du tableau :
compt(1) serait donc de type Range !
' mais
compt(2) serait donc de type Boolean !
ce compteur compt(2) il ne contient qu'une seule case (soit 1 ou soit 2) / il y a une fonction qui le remplis au préalable ?
Enfin c'est assez complexe quand même j'ai pas tous suivis.
 

Magic_Doctor

XLDnaute Barbatruc
Re,

laurent950, je vous réponds concernant le compteur qui vous intrigue et non pas au sujet de ma fonction ; puisque j'ai résolu le problème, le débat étant, pour moi, définitivement clos.

Rien de plus simple que d'utiliser le(s) compteur(s). Vous pouvez remercier job75 au passage.
Il n'y a aucune raison de déclarer en Public le ou les compteurs comme Variant ; Byte suffisant très largement. Il s'agit là du nombre d'options que peut avoir chaque compteur. Au minimum 2 et, avec Byte, au maximum 255.
Vous pouvez très facilement mettre le nombre de compteurs que vous voulez (bien les déclarer en Public) et affecter à chaque compteur le nombre d'options nécessaire (jusqu'à concurrence de 255...). Dans l'exemple (PJ), j'en ai mis 5.
 

Pièces jointes

  • Compteur.xlsm
    20.8 KB · Affichages: 5
Dernière édition:
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…