IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Comment connaître le nombre de possibilité de combinaison ordre et désordre


Sujet :

Macros et VBA Excel

  1. #21
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    re
    pijaku bonjour et ok ca match
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Sub test2()
        Dim res#, base#, N#
        base = 35
        N = 10
        res = Evaluate("Fact(" & N & ")*Combin(" & base & "," & N & ")")
        Debug.Print res
    End Sub
    Sub test()
        Dim res#, base#, N#
        base = 35
        N = 10
      res = Evaluate("Fact(" & base & ")/Fact(" & base & "-" & N & ")")
        Debug.Print res
    End Sub
     
    Sub test5()
        Dim base#, N#, x#, y#
        base = 35
        N = 10
        x = Application.Combin(base, N)
        y = Evaluate("Fact(" & N & " )*Combin(" & N & "," & N & ")")
        Debug.Print "combinaison:" & x & vbCrLf & "permutation pour chaque combi :" & y & vbCrLf & "resultat  :" & Val(x * y)
    End Sub
    j'avais oublié (long/double) menhir me l'avait fait remarqué plus haut
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  2. #22
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par Menhir Voir le message
    Dans ta macro test5, tu devrais déclarer x et y et leur assigner (au moins) le type Long.

    Je pense que tu devrais remplacer le premier "N" de ton Combin par "base".
    re
    et non menhir c'est le calcul du 2d temps
    y n'est que les combinaisons d'une combinaison de x sauf erreur de ma part
    mai s pijaku a raison j'ai tout mis en double et les 3 fonctionnent
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  3. #23
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 814
    Points : 2 949
    Points
    2 949
    Billets dans le blog
    10
    Par défaut
    Pour ne pas oublier...
    1- je ne déclare en Integer que les très petits chiffres
    2- le type Long n'est pas beaucoup plus gourmand que le type Integer
    3- lorsque je dois utiliser des grands nombres ==> systématiquement en Double

    4- après reste les formats particuliers comme Currency...
    Cordialement,
    Franck

  4. #24
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    re
    ben du coup le 4 solutions fonctionnent
    si ca peux servir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Sub test2()
        MsgBox result_puissance2(35, 10)
    End Sub
    '
    Function result_puissance2(base#, N#) As Double
        'formule de MENHIR DVP
       Dim res#
        res = Evaluate("Fact(" & N & ")*Combin(" & base & "," & N & ")")
        result_puissance2 = res
    End Function
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Sub test3()
        MsgBox result_puissance3(35, 10)
    End Sub
    '
    Function result_puissance3(base#, N#) As Double
        'formule de MENHIR DVP
       Dim res#
          res = Evaluate("Fact(" & base & ")/Fact(" & base & "-" & N & ")")
        result_puissance3 = res
    End Function
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Sub test1()
        MsgBox result_puissance1(35, 10)
    End Sub
    '
    Function result_puissance1(N#, K#) As Double
       'FORMULE PATRICKTOULON DVP
        Dim Nb#, i#: Nb = N
        For i = 1 To K - 1: Nb = Nb * (N - i): Next: result_puissance1 = Nb
    End Function
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Sub test4()
    MsgBox result_puissance4(35, 10)
    End Sub
    '
    Function result_puissance4(base#, N#) As Double
        'FORMULE PATRICKTOULON DVP
        Dim res#, x#, y#
        x = Application.Combin(base, N)
        y = Evaluate("Fact(" & N & " )*Combin(" & N & "," & N & ")")
        result_puissance4 = Val(x * y)
    End Function
    il parait que c'est un luxe d'avoir le choix
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  5. #25
    Expert éminent sénior Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Points : 32 866
    Points
    32 866
    Par défaut
    Citation Envoyé par pijaku Voir le message
    1- je ne déclare en Integer que les très petits chiffres
    Perso, je ne déclare plus rien en Integer.

    2- le type Long n'est pas beaucoup plus gourmand que le type Integer
    Etant donné la mémoire installée dans les PC actuels, la taille de quelques variables (à moins d'en avoir quelques centaines de milliers) c'est une goute d'eau dans la mer.
    Je préfère assurer systématiquement avec le type Long.

    A deux reprises (contrairement au corbeau de la fable, je m'y suis fait prendre deux fois), j'ai passé une plombe pour une erreur qui était due à un dépassement de capacité d'Integer.
    Depuis, je me suis fais une religion anti-Integer. Tant pis si l'exécution prend une microseconde et occupe quelque octets en plus.
    Merci de cliquer sur pour chaque message ayant aidé puis sur pour clore cette discussion.

  6. #26
    Rédacteur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2013
    Messages
    947
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Août 2013
    Messages : 947
    Points : 4 058
    Points
    4 058
    Par défaut
    Citation Envoyé par patricktoulon Voir le message
    re
    ben du coup le 4 solutions fonctionnent
    Bonjour.
    Je me permets de venir participer à votre discussion car un détail me fâche.
    Je m'explique :
    - j'ai testé les 4 fonctions proposées avec les valeurs 35 et 10, ce qui donne dans les 4 cas le résultat 666 172 912 204 800.
    - mais avec 35 et 11, le résultat retourné est : 1,665432280512E+16 pour les 3 premières fonctions et 1 pour la quatrième, soit 3 valeurs approximatives et 1 valeur fausse.

    Pourquoi ? Parce que les fonctions intégrées du VBA renvoient des valeurs de type "Double", soit des nombres à 15 chiffres.
    Pour travailler sur des grands entiers (soit des nombres à 28 chiffres) il faut utiliser le type de données "Decimal" qu'on obtient indirectement en déclarant les variables au format "Variant" puis en les convertissant avec la fonction "CDec".
    Il est ainsi possible de trouver le résultat exact avec les valeurs 35 et 20 : 7901927436407581959782400000 (et non pas 7,90192743640758E+27).
    Le dépassement de capacité intervient avec 35 et 21.

    Ce qui donne en reprenant la formule de Patricktoulon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Function result_puissance(N#, K#) As Variant
       'FORMULE PATRICKTOULON DVP
        Dim Nb As Variant, i#
        Nb = CDec(N)
        For i = 1 To K - 1: Nb = Nb * (N - i): Next: result_puissance = Nb
    End Function
    Sur le même principe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Debug.Print CDec(32) * CDec(31) * CDec(30)
    renvoie le résultat sans dépassement de capacité.

    En tout cas sur EXCEL 32 bits, je ne sais pas ce que donne la version 64 bits.

  7. #27
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    Bonjour Laurent-ott
    tu peux simplement utiliser cdec appliqué sur le resultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Sub test()
    MsgBox result_puissance(35, 11)
    End Sub
    '
    Function result_puissance(N#, K#) As Variant
       'FORMULE PATRICKTOULON DVP+"CDEC" Laurent-ott DVP
        Dim Nb As Variant, i#
        Nb = N
        For i = 1 To K - 1: Nb = Nb * (N - i): Next: result_puissance = CDec(Nb)
    End Function
    merci pour ce retour
    mais attention cdec visiblement a une limite aussi avec ton model ou le mien 35/23 plante "depassement de capacité"
    mes gros calcul encore une fois je les fait en hex

    for i= 1 to hex(blablablablabla)' accepte la forme abrégée du nombre

    next
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  8. #28
    Rédacteur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2013
    Messages
    947
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Août 2013
    Messages : 947
    Points : 4 058
    Points
    4 058
    Par défaut
    Citation Envoyé par patricktoulon Voir le message
    tu peux simplement utiliser cdec appliqué sur le resultat
    Malheureusement, non. Il faut bien faire la déclaration comme indiqué dans le code, si non les chiffres calculés dans la boucle sont de type Double, et donc le résultat retourné est tronqué. En testant ton code avec les valeurs 35 et 20 tu vas trouver 7901927436407580000000000000 au lieu de 7901927436407581959782400000.

    Comme indiqué plus haut, les chiffres de type "Decimal" sont limités à 28 nombres, après on est en dépassement de capacité du VBA.

    Mais bonne nouvelle, je viens de trouver sur internet (http://fordom.free.fr/) des fonctions pour traiter les très grands nombres.
    Les fonctions retournent des String.
    ici result_puissance(35, 34) = "10333147966386144929666651337523200000000"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
     
    Sub Test()
    Debug.Print result_puissance(35, 34)
    End Sub
     
    Function result_puissance(N As Long, K As Long) As String
       'FORMULE PATRICKTOULON DVP
        Dim Nb1 As String, Nb2 As String, i#
        Nb1 = CStr(N)
        For i = 1 To K - 1
            Nb2 = CStr(N - i)
            Nb1 = PGN(Nb1, Nb2)
        Next
        result_puissance = Nb1
    End Function
     
    Function PGN(ByVal Nb1 As String, ByVal Nb2 As String) As String
    'PRODUIT GRANDS NOMBRES
     
    'Info sur les longueurs des termes
    Dim L1 As Long, L2 As Long
    L1 = Len(Nb1): L2 = Len(Nb2)
     
    'Recherche des signes et conversion en nombre positif
    Dim S1 As Long, S2 As Long
    S1 = 1: S2 = 1
    If Left$(Nb1, 1) = "-" Then S1 = -1: Nb1 = Right$(Nb1, L1 - 1): L1 = L1 - 1
    If Left$(Nb2, 1) = "-" Then S2 = -1: Nb2 = Right$(Nb2, L2 - 1): L2 = L2 - 1
     
    'Recherche de la décimale et conversion en entier
    Dim P1 As Long, P2 As Long, Virgule As Long
     
        'Recherche emplacement de la virgule
        P1 = InStr(1, Nb1, ",") + InStr(1, Nb1, ".")
        P2 = InStr(1, Nb2, ",") + InStr(1, Nb2, ".")
        'Recompose en entier
        If P1 > 0 Then
            Nb1 = Left$(Nb1, P1 - 1) & Right$(Nb1, L1 - P1)
            Virgule = L1 - P1
            L1 = L1 - 1
        End If
        If P2 > 0 Then
            Nb2 = Left$(Nb2, P2 - 1) & Right$(Nb2, L2 - P2)
            Virgule = Virgule + L2 - P2
            L2 = L2 - 1
        End If
     
    'Découpage en tranche
    Dim K1 As Long, K2 As Long, Kt As Long
    K1 = L1 \ 7 + 1: K2 = L2 \ 7 + 1: Kt = K1 + K2
     
    'Tableaux de stockage des tranches
    ReDim A(K1) As Double, B(K2) As Double
     
    'Remplissage tableau
    Dim i As Long, j As Long
     
    For i = 0 To K1 - 2
    A(i) = Mid$(Nb1, L1 - 6 - i * 7, 7)
    Next i
    A(K1 - 1) = 0
    If L1 Mod 7 <> 0 Then A(K1 - 1) = Left$(Nb1, L1 Mod 7)
     
    For i = 0 To K2 - 2
    B(i) = Mid$(Nb2, L2 - 6 - i * 7, 7)
    Next i
    B(K2 - 1) = 0
    If L2 Mod 7 <> 0 Then B(K2 - 1) = Left$(Nb2, L2 Mod 7)
     
    'Base de calcul
    Dim Base As Long
    Base = 10 ^ 7
     
    'Déclaration des indices
    ReDim t(Kt + 1) As Double
     
    'Algo multiplication
    Dim P As Double, Q As Double, K As Long, Saut As Long, L As Double
    Saut = 90
    For j = 0 To K1
        L = A(j)
        If j = Saut Then Saut = Saut + 90: GoSub Recalcul
        For i = 0 To K2
            t(i + j) = L * B(i) + t(i + j)
        Next i
    Next j
    GoSub Recalcul
    GoTo suite:
     
    Recalcul: 'recalculs des indices t() dans la Base avant dépassement de capacité
    P = 0
    For K = 0 To K2 + j
        Q = Int((t(K) + P) / Base)
        t(K) = t(K) + P - Q * Base
        P = Q
    Next K
    Return
    suite:
     
    'Rajoute les zeros dans les indices moins long que 7 chiffres
    Dim Z As String 'optimisation string$
    Z = "0"
    Dim ln10 As Double
    ln10 = Log(10)
    For i = Kt To 0 Step -1
        PGN = PGN & String$(6 - Fix(Log(t(i) + 0.11) / ln10), Z) & t(i)
    Next i
     
    'Supprime les zeros inutiles
    PGN = ZeroGN(PGN)
     
    'Replacement de la virgule
    Dim PS As Long
    If Virgule <> 0 Then
        PS = Len(PGN) - Virgule
        If PS < 0 Then PGN = String$(-PS, Z) & PGN
        PGN = Left$(PGN, Len(PGN) - Virgule) & "," & Right$(PGN, Virgule)
    End If
     
    'Mise en forme
    PGN = ZeroGN(PGN)
     
    'Règle des signes
    If S1 * S2 = -1 And PGN <> "0" Then PGN = "-" & PGN
     
    End Function
     
     Function ZeroGN(ByVal Term1 As String) As String
    'RETIRE LES ZEROS INUTILES
     
    'Boucle de recherche des zéros inutiles dans la partie entière
    Dim i As Long
    For i = 1 To Len(Term1)
        If Mid$(Term1, i, 1) <> "0" Then Exit For
    Next i
    Term1 = Mid$(Term1, i)
    If Term1 = vbNullString Then Term1 = "0" 'traite le cas d'un nombre nul
     
    'Recherche si virgule
    Dim V As Long
    V = InStr(1, Term1, ",") + InStr(1, Term1, ".")
     
    'Recherche si Term1<1, si oui remet un zéro devant la virgule
    If V = 1 Then Term1 = "0" & Term1: V = 2
     
    'Boucle de recherche des zéros inutiles dans partie décimale
    If V > 0 Then
    For i = Len(Term1) To V - 1 Step -1
        If Mid$(Term1, i, 1) <> "0" Then Exit For
    Next i
    Term1 = Left$(Term1, i)
    End If
     
    'Recherche si dernier=virgule, si oui=supprime
    If V = Len(Term1) Then Term1 = Left$(Term1, V - 1)
     
    'Renvoi
    ZeroGN = Term1
     
    End Function
    Il y a plein d'autres fonctions mathématiques de disponibles.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Comment connaître le nombre de lignes?
    Par Xanto dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 07/08/2007, 10h23
  2. [C#] Comment connaître le nombre de lignes affectées par un Select ?
    Par diaboloche dans le forum Accès aux données
    Réponses: 6
    Dernier message: 21/09/2006, 13h56
  3. Réponses: 2
    Dernier message: 29/05/2006, 19h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo