Créer une formule sur VB (macro) pour calculer une médiane

Tessel750 Messages postés 47 Date d'inscription   Statut Membre Dernière intervention   -  
Tessel750 Messages postés 47 Date d'inscription   Statut Membre Dernière intervention   -

Bonjour à tous,

La formule intégrée de calcul d'une médiane sur Excel ne me convient pas; surtout qu'on ne peut pas l'utiliser sur un autre logiciel comme Access. Aussi je voudrais créer une formule personnelle en VisualBasic qui me permettrait de l'intégrer ailleurs qu'Excel.  Quelqu'un d'entre vous pourrait-il m'y aider?  Je suis assez pressé et j'ai peu de temps à  y consacrer.

Alors le plan de la macro serait quelque chose du genre :

Ecriture de la  formule   DMed = DMed(DMin;DMax; Dom)

Dom  = (A1:Z24)  ordonné du plus petit au plus grand

DMin = Ka  appartenant à Dom

           DMin =   SI(EstNull(DMin); Min(Dom); DMin)

DMax = K'a'  appartenant à Dom

           DMax =   SI(EstNull(DMax ); Max(Dom); DMax )

DNomb = Nombre de données compris entre DMin et DMax

DNomb2=  Ent( (DNomb/2) ;0)

Sélectionner DMed  tel que rang de DMed = DNomb2

DMed(DMin;DMax; Dom)  =  DMed 

Voila, si quelqu'un pouvait m'aider à écrire cette procédure je lui en serais très reconnaissant.

Tessel


Windows / Firefox 141.0

3 réponses

  1. danielc0 Messages postés 2196 Date d'inscription   Statut Membre Dernière intervention   286
     

    Bonjour,

    Le calcul est assez facile. Ce qu'il faut savoir c'est comment tu vas passer les nombres à la fonction. Tu peux le faire soit en passant une série de nombres discrets soit en passant un tableau de nombres. Dans l'attente de ta réponse, je vais commencer le code avec l'hypothèse de la série de nombres discrets (auquel cas tu serais limité à 255 nombres).

    Daniel


    0
    1. Tessel750 Messages postés 47 Date d'inscription   Statut Membre Dernière intervention   1
       

      Bonjour et merci pour ta réponse.

      Le nombre de donnée est variable mais peut être assez grand, jusqu'à 10 000 ou 15 000 voire plus encore. Et ce ne sont  pas des entiers mais des réels simples (des prix). En principe ils sont en colonnes, comme sur une base de données, mais j'ai fait comme s'ils étaient en pavé pour que la formule soit plus universelle.

      Merci

      0
      1. danielc0 Messages postés 2196 Date d'inscription   Statut Membre Dernière intervention   286 > Tessel750 Messages postés 47 Date d'inscription   Statut Membre Dernière intervention  
         

        Tu veux dire que les données sont dans des cellules Excel ?

        Daniel

        0
      2. danielc0 Messages postés 2196 Date d'inscription   Statut Membre Dernière intervention   286 > danielc0 Messages postés 2196 Date d'inscription   Statut Membre Dernière intervention  
         

        Avec une plage de cellules en entrée :

        Function Mediane3(Plage As Range) As Double
          Dim Arr(), C As Range, I As Long
          I = -1
          For Each C In Plage
            If IsNumeric(C) Then
              I = I + 1
              ReDim Preserve Arr(I)
              Arr(I) = C.Value
            End If
          Next C
          QuickSortArray Arr
          nb = (UBound(Arr) + 1) / 2
          If Int(nb) <> nb Then
            nb = nb + 0.5
          End If
          Mediane3 = Arr(nb - 1)
        End Function
        

        Pour tester :

        Sub test3()
        MsgBox Mediane3([A1:A17])
        End Sub
        

        Daniel

        0
      3. Tessel750 Messages postés 47 Date d'inscription   Statut Membre Dernière intervention   1 > danielc0 Messages postés 2196 Date d'inscription   Statut Membre Dernière intervention  
         

        Cela se pourrait, mais ce n'est pas gênant. En fait je compte surtout l'utiliser sur Access où la médiane n'existe pas. Les nombres y sont en colonnes, comme j'ai dit par ailleurs, et on travaille avec des tables qui peuvent être très grandes. Quant à Excel, le tableau descend au delà de 1 000 000, donc i ne devrait pas y avoir de difficultés.

        Merci

        0
  2. danielc0 Messages postés 2196 Date d'inscription   Statut Membre Dernière intervention   286
     

    A tester, avec un tableau en entrée :

    Function Mediane(ParamArray Tbl() As Variant) As Double
      Dim Arr() As Double
      ReDim Arr(UBound(Tbl(0)))
      For i = 0 To UBound(Tbl(0))
        Arr(i) = Tbl(0)(i)
      Next i
      QuickSortArray Arr
      nb = UBound(Tbl(0)) / 2
      If Int(nb) <> nb Then
        nb = nb + 0.5
      End If
      Mediane = Arr(nb)
    End Function
    
    Function QuickSortArray(avarArrFiles As Variant, _
    Optional intFirst As Integer = -1, _
    Optional intLast As Integer = -1) As Variant
    ' Algorithme QuickSort utilisé pour trier les fichiers
    ' du tableau avarArrFiles.
    Dim intLow As Integer
    Dim intHigh As Integer
    Dim intMiddle As Integer
    Dim varTempVal As Variant
    Dim varTestVal As Variant
    
    If intFirst = -1 Then intFirst = LBound(avarArrFiles)
    If intLast = -1 Then intLast = UBound(avarArrFiles)
    
    If intFirst < intLast Then
    intMiddle = (intFirst + intLast) / 2
    varTestVal = avarArrFiles(intMiddle)
    intLow = intFirst
    intHigh = intLast
    Do
    Do While avarArrFiles(intLow) < varTestVal
    intLow = intLow + 1
    Loop
    Do While avarArrFiles(intHigh) > varTestVal
    intHigh = intHigh - 1
    Loop
    If (intLow <= intHigh) Then
    varTempVal = avarArrFiles(intLow)
    avarArrFiles(intLow) = avarArrFiles(intHigh)
    avarArrFiles(intHigh) = varTempVal
    intLow = intLow + 1
    intHigh = intHigh - 1
    End If
    Loop While (intLow <= intHigh)
    If intFirst < intHigh Then QuickSortArray avarArrFiles, intFirst, intHigh
    If intLow < intLast Then QuickSortArray avarArrFiles, intLow, intLast
    End If
    End Function
    

    La fonction "QuickSortArray" est une fonction que l'on trouve facilement sur internet. Je ne sais pas à qui en attribuer la paternité.

    Pour tester la fonction :

    Sub test1()
      Dim Tbl(2)
      Tbl(0) = 10
      Tbl(1) = 2
      Tbl(2) = 5
      MsgBox Mediane(Tbl)
    End Sub
    

    0
    1. Tessel750 Messages postés 47 Date d'inscription   Statut Membre Dernière intervention   1
       

      Merci de ta réponse, je vais regarder ça, mais je ne peux pas en cinq minutes.

      0
  3. danielc0 Messages postés 2196 Date d'inscription   Statut Membre Dernière intervention   286
     

    Avec une série de nombres, par exemple 2, 5, 10 :

    Function Mediane2(n1, Optional n2, Optional n3, Optional n4, Optional n5) As Double
      Dim Arr() As Double
      Ctr = -1
      Ctr = Ctr + 1
      ReDim Preserve Arr(Ctr)
      Arr(Ctr) = n1
      If IsMissing(n2) = False Then
        Ctr = Ctr + 1
        ReDim Preserve Arr(Ctr)
        Arr(Ctr) = n2
      End If
      If IsMissing(n3) = False Then
        Ctr = Ctr + 1
        ReDim Preserve Arr(Ctr)
        Arr(Ctr) = n3
      End If
      If IsMissing(n4) = False Then
        Ctr = Ctr + 1
        ReDim Preserve Arr(Ctr)
        Arr(Ctr) = n4
      End If
      If IsMissing(n5) = False Then
        Ctr = Ctr + 1
        ReDim Preserve Arr(Ctr)
        Arr(Ctr) = n5
      End If
      QuickSortArray Arr
      nb = (UBound(Arr) + 1) / 2
      If Int(nb) <> nb Then
        nb = nb + 0.5
      End If
      Mediane2 = Arr(nb - 1)
    End Function
    

    Pour tester :

    Sub test2()
      MsgBox Mediane2(10, 2, 5)
    End Sub
    

    Même fonction  QuickSortArray que dans le message précédent. La fonction ne peut traiter ici que 5 nombres maximum. La méthode par tableau du post précédent doit être privilégiée, celle-ci étant limitée à 255 nombres.


    0
    1. Tessel750 Messages postés 47 Date d'inscription   Statut Membre Dernière intervention   1
       

      Merci de ta réponse, je vais regarder ça, mais je ne peux pas en cinq minutes surtout que ta proposition contient des expressions que je ne maitrise pas.

      0