XL 2010 Comparer le nombre de décimales après la virgule d’une série de chiffres

Magic_Doctor

XLDnaute Barbatruc
Bonjour,

J’ai une série de 4 chiffres décimaux, par exemple :
-55,4927644455
-125
-35,920236
56,01666666

Je veux connaître le nombre de chiffres après la virgule le plus long de cette série de chiffres.

J’ai bricolé ceci, qui ma foi fonctionne :
VB:
Sub NbMaxChiffresAfterVirgule()

Dim c As Range, i As Byte, nb(4) As Byte, tableau

    For Each c In [Zardoz] 'nom de la plage de 4 cellules contenant les 4 valeurs
        i = i + 1
        nb(i) = ChiffresAfterVirgule(c.Value, 1)
    Next

    tableau = Array(nb(1), nb(2), nb(3), nb(4))
    
    [S14] = Application.Max(tableau) 'résultat

End Sub
-----------------------------------------------------------------------
Function ChiffresAfterVirgule(dNum As Double, Opt As Byte)
'Renvoie le nombre de chiffres après la virgule ou tous les chiffres après la virgule
'- dNum : le chiffre à traiter
'- opt : si opt = 1 --> le nombre de chiffres après la virgule
'        si opt <> 1 --> tous les chiffres après la virgule
'Ex : 125,587349 | opt = 1 --> 6
'                  opt <> 1 --> 587349

Dim SepDec$, tmp, posDec, nb As Double, cap$

  SepDec = Application.International(xlDecimalSeparator)
  tmp = CStr(dNum)
  posDec = InStr(tmp, SepDec)
  nb = Len(tmp) - Len(Right(tmp, posDec)) 'nombre de chiffres après la virgule
  cap = Right(dNum, nb) 'chiffres après la virgule
 
  ChiffresAfterVirgule = IIf(Opt = 1, IIf(posDec = 0, 0, nb), IIf(posDec = 0, 0, cap))
  
End Function
Le problème, c’est que la plage « Zardoz » est en fait constituée de 4 cellules fusionnées. Sur la feuille : R17:S17 ; R18:S18 ; R19:S19 ; R20:S20. Pour des raisons techniques ces cellules doivent rester fusionnées. Et là ma routine ne marche plus. Comment y remédier ?
 

fanfan38

XLDnaute Barbatruc
Bonjour
Je te propose cette solution
VB:
Sub NbMaxChiffresAfterVirgule()
  Dim mavar As String, a, c As Byte
  On Error Resume Next ' si pas de decimale
  For c = 17 To 20
    mavar = CStr(Range("R" & c))
    a = Split(mavar, ",")
    MsgBox Len(a(1))
  Next
End Sub
A+ François
 

Magic_Doctor

XLDnaute Barbatruc
Bonjour à tous,

Merci pour vos réponses. Toutes vos solutions marchent. Comme le problème se joue dans une macro, je n'ai pas retenu la solution de la formule. Des 2 solutions en VBA, c'est la fonction de soan qui est la plus polyvalente. En la paramétrant :
VB:
Function NbMaxChiffresAfterVirgule(plage As Range) As Byte
'Renvoie le plus grand nombre de décimales après la virgule d'une série de chiffres décimaux ou pas
'soan

Dim cel As Range, chn$, p As Byte, lng As Byte, k As Byte
 
    For Each cel In plage
        If cel <> 0 Then
            chn = str$(cel): p = InStr(chn, ".")
            If p > 0 Then
                lng = Len(chn) - p: If lng > k Then k = lng
            End If
        End If
    Next cel
    
    NbMaxChiffresAfterVirgule = k
    
End Function
Bonne journée.
 

fanch55

XLDnaute Accro
Salut à Tous,
En combinant les soluces de @fanfan38 , @soan et @Magic_Doctor :
VB:
Function NbMaxChiffresAfterVirgule(Plage As Range) As Integer
  Dim Cel As Range
  On Error Resume Next ' si pas de decimale
  For Each Cel In Plage
    NbMaxChiffresAfterVirgule = WorksheetFunction.Max(NbMaxChiffresAfterVirgule, Len(Split(Cel.Value, ".")(1)))
  Next
End Function
 

job75

XLDnaute Barbatruc
Bonsoir MagicDoctor, le fil,

Voyez les 2 solutions dans le fichier joint :

- formule matricielle sur la plage nommée Zardoz :
VB:
=MAX(NBCAR(STXT(Zardoz;TROUVE(STXT(1/10;2;1);Zardoz&STXT(1/10;2;1))+1;15)))
- fonction VBA à placer impérativement dans un module standard :
VB:
Function NbMaxChiffresAfterVirgule(plage As Range)
NbMaxChiffresAfterVirgule = Evaluate("MAX(LEN(MID(" & plage.Address & ",FIND(MID(1/10,2,1)," & plage.Address & "&MID(1/10,2,1))+1,15)))")
End Function
qui ne fait que reproduire la formule Excel.

Bonne nuit.
 

Pièces jointes

  • NbMaxChiffresAfterVirgule(1).xlsm
    16 KB · Affichages: 2

job75

XLDnaute Barbatruc
Dans ce fichier (2) je simplifie la fonction VBA car quel que soit le séparateur décimal de l'ordi c'est toujours le point qui est recherché :
VB:
Function NbMaxChiffresAfterVirgule(plage As Range)
NbMaxChiffresAfterVirgule = Evaluate("MAX(LEN(MID(" & plage.Address & ",FIND("".""," & plage.Address & "&""."")+1,15)))")
End Function
Re bonne nuit.
 

Pièces jointes

  • NbMaxChiffresAfterVirgule(2).xlsm
    16 KB · Affichages: 6

soan

XLDnaute Barbatruc
Bonjour à tous,

@fanfan38

Ton idée d'utiliser Split() est très bien, mais dans ton code, il manque le maximum.

@job75

J'ai vu tes posts, mais perso, je préfère éviter les formules matricielles (c'est juste
car je ne les comprends pas bien)
.

@fanch55

J'ai essayé ton code VBA, mais ça n'a pas marché : ça retourne 0 au lieu de 10.
J'ai alors eu l'idée de remplacer le point par une virgule, et là, ça a marché.

Ce qui suit est ton code VBA, avec la présentation de Magic_Doctor ; pour le type renvoyé par la fonction, je préfère mettre un Byte plutôt qu'un Integer, car Byte : de 0 à 255 : ça suffit amplement pour un nombre de décimales ! (pour la précision numérique, Excel a une précision maximum de 15 chiffres après la virgule)

VB:
Option Explicit

Function NbMaxChiffresAfterVirgule(plage As Range) As Byte
'Renvoie le plus grand nombre de décimales après la virgule d'une série de chiffres décimaux ou pas

Dim cel As Range

    On Error Resume Next ' si pas de décimales

    For Each cel In plage
        NbMaxChiffresAfterVirgule = WorksheetFunction.Max(NbMaxChiffresAfterVirgule, Len(Split(cel.Value, ",")(1)))
    Next cel

End Function

Sub Essai()
  MsgBox NbMaxChiffresAfterVirgule([Zardoz])
End Sub


@Magic_Doctor

Utilise plutôt une version avec Split()

soan
 
Dernière édition:

fanch55

XLDnaute Accro
@fanch55
J'ai essayé ton code VBA, mais ça n'a pas marché : ça retourne 0 au lieu de 10.
J'ai alors eu l'idée de remplacer le point par une virgule, et là, ça a marché.

Avec le séparateur décimal utilisé sur le système, c'est vrai que c'est mieux ..

VB:
Option Explicit
Function NbMaxChiffresAfterVirgule(plage As Range) As Byte
'Renvoie le plus grand nombre de décimales après la virgule d'une série de chiffres décimaux ou pas

Dim cel As Range, Decim as String

    On Error Resume Next ' si pas de décimales
    Decim = Application.International(xlDecimalSeparator)
    For Each cel In plage
        NbMaxChiffresAfterVirgule = WorksheetFunction.Max(NbMaxChiffresAfterVirgule, Len(Split(cel.Value, Decim)(1)))
    Next cel

End Function

Sub Essai()
  MsgBox NbMaxChiffresAfterVirgule([Zardoz])
End Sub
 

patricktoulon

XLDnaute Barbatruc
re
bonjour
je pige pas le chemin que prennent les solutions proposées o_O
il me semble qu'il est question de fusion de cellule dans la quelle se trouve plusieurs nombres décimaux et il faut en extraire le plus grand décimal en terme de string(len)
il faut donc couper la chaîne par les saut de ligne ( CHR 10 ou 13 OU MÊME 160 ) ou VBCRLF) et examiner les éléments du split
 

soan

XLDnaute Barbatruc
Bonjour Patrick,

Il ne s'agit pas d'une cellule où il y a plusieurs nombres mais d'un nombre sur 2 cellules fusionnées horizontalement, cela 4× verticalement (en colonnes R et S, lignes 17 à 20 ; 4 nombres en tout).

Si tu télécharges par exemple le fichier de mon post, tu pourras mieux le voir.

soan
 

patricktoulon

XLDnaute Barbatruc
Bonjour
ok ton fichier donne 10 ???????? o_O
et oui en effet au moins la première cellule est formatée on vois pas les 10 décimales
VB:
Sub essaiPat()
    MsgBox NbMaxChiffresAfterVirgulePat([Zardoz])
End Sub

Function NbMaxChiffresAfterVirgulePat(Rng As Range)
    Dim tbl, x&, i&
    tbl = Application.Transpose(Rng.Columns(1).Value)
    For i = 1 To UBound(tbl)
        If InStr(tbl(i), ",") Then If x < Len(Split(tbl(i), ",")(1)) Then x = Len(Split(tbl(i), ",")(1))
    Next
    NbMaxChiffresAfterVirgulePat = x
End Function
 

Discussions similaires

Haut Bas