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 :

Fonction boucle avec condition


Sujet :

Macros et VBA Excel

  1. #1
    Candidat au Club
    Homme Profil pro
    curieux
    Inscrit en
    Février 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : curieux

    Informations forums :
    Inscription : Février 2014
    Messages : 3
    Points : 4
    Points
    4
    Par défaut Fonction boucle avec condition
    Bonjour à tous,

    Je débute en VBA et Macro, après des recherches sur les différents forum j'ai réussi à créer la fonction dont j'ai besoin (fichier joint) :

    - générer des nombres entiers de 1 à 20 sans doublons de façon aléatoire et sous forme de tableau, le tout répété 4 fois ce qui me donne un tableau de 20 colonnes (5 colonnes par répétion) et 5 lignes.

    Dans cette configuration il existe encore des doublons par lignes, je pense utiliser une "boucle avec condition" pour que la macro tourne et s'arrête au moment au il n'y plus de doublons (que ce soit pour les lignes ou les colonnes) mais je n'arrive pas à réaliser cette opération.

    D'avance merci pour vos réponses

    Gaétan
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés

  2. #2
    Membre expérimenté Avatar de Gado2600
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Mai 2013
    Messages
    903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Office VBA

    Informations forums :
    Inscription : Mai 2013
    Messages : 903
    Points : 1 364
    Points
    1 364
    Par défaut
    Bonjour,

    Effectivement, utiliser une boucle peut être pas mal.

    Pour gérer ton problème de doublons, la première idée qui me vient à l'esprit est d'utiliser un tableau numérique comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    dim tabA()   as variant
    redim tabA(1 to 20)
    for i = lbound(tabA) to ubound(tabA)
           tabA(i)=false
    next
    Le code ci-dessus initialise un tableau de la dimension qui correspond aux nombres que tu veux sortir.
    Le but ici, c'est lors de la création de l'un de tes blocs, tu vas appliquer ton random de 1 à 20 et stocké la valeur dans une variable.
    Tu vérifies ensuite si ta valeur est déjà utilisée ou non. Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    dim intVar as integer 
    intVar = 2
    while tabA(intVar) = true 
           intVar = autre valeur
    wend
    rng = intVar ' écriture
    Ensuite, sur chaque bloc, tu réinitialises ton tableau et tu recommences le procédé à chaque fois :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Pour chaque bloc
           Initialisation du tableau (code 1)
           Recherche et inscription des valeurs (code 2)
    Fin pour
    Cordialement,
    Le sabre est une arme. Le kendo est un art de tuer. Quelles que soient les belles paroles pour l'expliquer, telle est sa vérité.

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Septembre 2013
    Messages
    783
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2013
    Messages : 783
    Points : 1 562
    Points
    1 562
    Par défaut
    Bonjour,

    Par rapport à la proposition de Gado2600, je propose une toute petite alternative pour la partie détection des valeurs en doublon et remplacement.
    Schématiquement:
    - On génère le tableau comme indiqué
    - Sachant qu'il doit contenir toutes les valeurs 1 à 20, on remplace les valeurs en doublon par celles manquantes: c'est beaucoup plus rapide

    Ci-joint un cas réel que j'avais utilisé pour générer des tables de hash de Pearson

    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
    Sub Gener_Pears_Arr()
    ' Generate a table based on Nb of bits (user input)
     
    Subname = "Gener_Pears_Arr"
     
    Dim BitN As Integer
    Dim Msganswer As String
    Dim Pears_CrInd As Double, Pears_Ind As Double, Pears_Corr As Double
    Dim MinVal As Integer, MaxVal As Double, RndVal As Double
    Dim ExistVal As Boolean, ValidVal As Boolean
    Dim Pears_arr() As Double
     
    ThisWorkbook.Activate
     
    On Error GoTo Err_Gener_Pears_Arr
     
        ' Number of bits input and value min (0 or 1)
    While BitN = 0 Or MinVal > 1
        BitN = Application.InputBox("Nb of bits: ", Subname, Type:=1)
        MinVal = Application.InputBox("Minimum value (and index): ", Subname, Default:=0, Type:=1)
    Wend
     
    If BitN >= 14 Then MsgBox "Process could be long.... Be patient!", , Subname
     
     
        ' Set the parameters of the table
    MaxVal = 2 ^ BitN - 1 + MinVal
     
    ReDim Pears_arr(MinVal To MaxVal, 1 To 2)
     
        ' Create the table without check of the unicity
    For Pears_Ind = MinVal To MaxVal
     
        Randomize
        RndVal = Int((MaxVal - MinVal + 1) * Rnd + MinVal)
        Pears_arr(Pears_Ind, 1) = RndVal
        Pears_arr(RndVal, 2) = Pears_arr(RndVal, 2) + 1
     
    Next Pears_Ind
     
        'Now, parse the table and detect the records which have been assigned several times
    For Pears_Ind = MinVal To MaxVal
     
            ' More than one assignation
        If Pears_arr(Pears_Ind, 2) > 1 Then
            'Debug.Print Pears_Ind, Pears_arr(Pears_Ind, 2)
     
                ' Search for the first record having this value
     
            For Pears_CrInd = MinVal To MaxVal
     
                If Pears_arr(Pears_CrInd, 1) = Pears_Ind Then
                    'Debug.Print Pears_CrInd, Pears_arr(Pears_CrInd, 1)
     
                    For Pears_Corr = MinVal To MaxVal
     
                        If Pears_arr(Pears_Corr, 2) = 0 Then
     
                            Pears_arr(Pears_CrInd, 1) = Pears_Corr
                            Pears_arr(Pears_Ind, 2) = Pears_arr(Pears_Ind, 2) - 1
                            Pears_arr(Pears_Corr, 2) = Pears_arr(Pears_Corr, 2) + 1
     
                            Exit For
     
                        End If
     
                    Next Pears_Corr
     
                End If
     
            If Pears_arr(Pears_Ind, 2) = 1 Then Exit For
     
            Next Pears_CrInd
     
        End If
     
     
    Next Pears_Ind
    "Idéalement nous sommes ce que nous pensons. Dans la réalité, nous sommes ce que nous accomplissons." A.Senna
    et n'oubliez-pas de développer des .... sourires ^_^

  4. #4
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    Ma proposition (algorithme diverge mais contourné)

    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
    Option Explicit
     
    Const S As Byte = 5
     
    Sub Test()
     
    GenereSerieAleatoireSansDoublons 20, Range("B2")
    End Sub
     
     
    Private Sub GenereSerieAleatoireSansDoublons(ByRef Nb As Long, Dest As Range)
    Dim i As Integer, R As Integer, j As Integer, m As Integer, q As Integer, Tb() As Integer
    Dim P() As String, L() As String
    Dim k As Byte
    Dim H
     
    Application.StatusBar = "Recherche combinaisons en cours..."
    Nb = S * (Nb \ S)
    Dest.Resize(Nb / S, Nb).ClearContents
    ReDim Tb(1 To Nb / S, 1 To Nb)
    ReDim L(1 To Nb)
    ReDim P(1 To Nb / S)
     
    For k = 1 To Nb / S
        i = 1
        Do
            DoEvents
            R = NUMERO(Nb, P, L, i, k)
     
            j = 1 + (i - 1) \ S
     
            If R = 0 Then
                If k > 1 Then
                    For q = 1 To Nb / S
                        H = Split(P(q), ",")
                        P(q) = ""
                        For m = 0 To S * (k - 1)
                            If H(m) <> "" Then P(q) = P(q) & "," & H(m)
                        Next m
                    Next q
     
                    For m = 1 To Nb
                        Tb(k, i) = Empty
                    Next m
     
                    L(k) = ""
                    i = 1
                End If
            Else
                P(j) = P(j) & "," & R
                L(k) = L(k) & "," & R
                Tb(k, i) = R
                i = i + 1
            End If
        Loop While i <= Nb
    Next k
    Dest.Resize(Nb / S, Nb).Value = Tb
    Application.StatusBar = False
    End Sub
     
    Private Function NUMERO(ByVal Nb As Long, ByVal P, ByVal L, ByVal i As Integer, ByVal k As Byte) As Integer
    Dim R As Integer
    Dim Cp As Long
     
    Randomize
    Do
        DoEvents
        R = Int(Nb * Rnd()) + 1
        Cp = Cp + 1
        If Cp > 200 Then Exit Function
    Loop Until Not DEJAP(P, R, i) And Not DEJAL(L, R, k)
    NUMERO = R
    End Function
     
     
    Private Function DEJAP(ByVal vP, ByVal vR As Long, ByVal i As Long) As Boolean
    Dim k As Long
     
    k = 1 + (i - 1) \ S
    DEJAP = InStr(vP(k) & ",", "," & CStr(vR) & ",")
    End Function
     
    Private Function DEJAL(ByVal vL, ByVal vR As Long, ByVal k As Long) As Boolean
     
    DEJAL = InStr(vL(k) & ",", "," & CStr(vR) & ",")
    End Function
    Cordialement.
    J'utilise toujours le point comme séparateur décimal dans mes tests.

Discussions similaires

  1. Boucle avec condition
    Par sl1980 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 28/08/2007, 20h24
  2. Boucle avec condition "perdu"
    Par guismoman33 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 08/06/2007, 10h38
  3. fonction "REPLACE" avec condition
    Par emilek dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 21/03/2007, 17h08
  4. [Oracle 10] Fonction ROWNUM avec condition
    Par SQL_Pour_les_Nuls dans le forum Langage SQL
    Réponses: 6
    Dernier message: 03/07/2006, 15h06
  5. boucle avec condition d'arret changeante
    Par NicoH dans le forum Langage
    Réponses: 3
    Dernier message: 10/06/2003, 11h48

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