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 :

Division par 0 dans une boucle


Sujet :

Macros et VBA Excel

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 23
    Points : 15
    Points
    15
    Par défaut Division par 0 dans une boucle
    Bonjour à tous,

    Aujourd'hui, j'ai un souci très étrange. Voici le code VBA concerné (sous Excel 2003) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ...
    Dim iter As Long
    For iter = 1 To UBound(sortieIndice)
        'SendKeys "{ENTER}"
        'MsgBox iter
        If sortieIndice(iter) <> 0 Then     'premier élément non-nul, à mettre à 0
            sortieIndice(iter) = 0
            Exit For
        End If
    Next iter
    ...
    Comme vous pouvez le constater ce code parcourt le tableau "sortieIndice" et met à zéro le premier élément non-nul.

    Et bien quand j'exécute ma macro, le programme plante avec pour raison "division par zéro" et pointe sur la ligne du If ! Heu... de quelle division parle-t-il ?

    Vous constaterez que j'ai mis deux lignes en commentaire. Je me suis apperçu qu'en affichant l'itération dans un MsgBox, il n'y avait plus d'erreur (j'ai rajouté le SendKeys "{ENTER}" pour masquer l'apparition de la fenêtre, je sais que c'est pas très propre, mais dans l'urgence...). Donc plus de problème... ...sur ma machine. Parce que si je lance le code sur une autre bécane, l'erreur revient.

    Si quelqu'un a une idée du pourquoi du comment de ce gloubi-boulga, merci d'avance de m'éclairer...

    VDM...

  2. #2
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Points : 5 537
    Points
    5 537
    Par défaut
    Bonjour,

    - qu'est exactement sortieIndice ? comment et par quoi est-il défini et chargé ?
    - la modifdication de sortieindice dsécelenche-t-elle une exécution ou une autre modification ailleurs ? si oui : laquelle et comment ?

    Je note que tu fais une boucle de l'article d'indice 1 à l'indice le plus élevé et que tu quittes dès avoir trouvé un article <> 0 (que tu mets à 0).

    Questions :
    - pourquoi commencer à l'indice 1 ? tu as choisi de dimensionner un tableau en commençant à 1 et non à 0 ?
    - ton commentaire :
    'premier élément non-nul, à mettre à 0
    donne à penser que tu ne veux remettre à 0 que le 1er article non nul et quitter. Quid si aucun n'est nul ? (avec ton code, il continue jusqu'au dernier) est-ce bien ce que tu veux ?

    Tu nous montres un morceau de code.
    Question : ce morceau est-il réitéré ? (dans une fonction récursive, par exemple ?)

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 23
    Points : 15
    Points
    15
    Par défaut
    - qu'est exactement sortieIndice ? comment et par quoi est-il défini et chargé ?
    sortieIndice est un tableau de Double avec des éléments de 1 à 721, il est le résultat d'une routine un peu trop complexe pour l'expliquer ici.

    - la modifdication de sortieindice dsécelenche-t-elle une exécution ou une autre modification ailleurs ? si oui : laquelle et comment ?
    Non, non.

    - pourquoi commencer à l'indice 1 ? tu as choisi de dimensionner un tableau en commençant à 1 et non à 0 ?
    Je commence mon tableau à 1 effectivement. C'est plus simple pour moi parce que suis en train de transcrire du code Matlab en VBA.

    tu ne veux remettre à 0 que le 1er article non nul et quitter. Quid si aucun n'est nul ? (avec ton code, il continue jusqu'au dernier) est-ce bien ce que tu veux ?
    Oui, c'est exactement ce que je veux faire.

    Tu nous montres un morceau de code.
    Question : ce morceau est-il réitéré ? (dans une fonction récursive, par exemple ?)
    Non, pas de récursivité ou autre.

    Bon, entre temps j'ai trouvé une solution pour contourner le problème (attention, c'est TRES empirique). Sur ma machine, faire apparaître une MsgBox et la fermer suffisait à faire disparaître l'erreur. Sur une machine un peu plus puissante l'erreur persistait. J'ai donc remplacé l'apparition de la MsgBox par un petit temps d'attente (avec Wait au départ pour vérifier mon hypothèse, puis avec une combinaison de DoEvents et Sleep qui vient de kernel32). Maintenant ça marche, merci pour votre intérêt.

    Toutefois, ce que j'en déduis c'est qu'il est possible que VBA "s'emmèle les pinceaux" parfois. Et si quelqu'un peu m'expliquer ça, je suis preneur.

  4. #4
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Bonjour.

    Cela semble bien curieux. Quelle est la valeur de i au premier dysfonctionnement et au deuxième? Tu peux montrer le code avec les rustines que tu as imaginées? La déclaration du tableau?

    L'étrange c'est souvent juste un truc qu'on n'a pas compris.

    PGZ

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 23
    Points : 15
    Points
    15
    Par défaut
    L'étrange c'est souvent juste un truc qu'on n'a pas compris.
    Non, là c'est plus de l'étrange, c'est du surnaturel, du paranormal, du vaudou !

    En fait, ça plante dès la première itération, pour i=1.

    Voilà la déclaration de mon tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim sortieIndice(1 To 721) As Double
    Et voilà ma rustine (dont je suis assez fier ) :

    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
        Dim iter As Long
        Dim attente As Long
        Dim maxattente As Long
     
        ' récupération de la fréquence processeur pour adapter l'attente
        Dim freq As Long
        freq = frequence_proc()
        maxattente = CLng((5 / 0.6) * freq - 5) 'équation de droite établie empiriquement
     
        For iter = 1 To UBound(sortieIndice)
            For attente = 0 To maxattente       'permet de faire une petite pause pour éviter le plantage
                DoEvents
                Sleep 1
            Next attente
            If sortieIndice(iter) <> 0 Then     'premier élément non-nul, à mettre à 0
                sortieIndice(iter) = 0
                Exit For
            End If
        Next iter
    la fonction de récupération de la fréquence du processeur :

    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
    Function frequence_proc() As Long
     
        Dim objs As Object
        Dim obj As Object
        Dim WMI As Object
        Dim lAns As Long
     
        Set WMI = GetObject("WinMgmts:")
        Set objs = WMI.InstancesOf("Win32_Processor")
     
        lAns = 0
        For Each obj In objs
            If obj.MaxClockSpeed > lAns Then
                lAns = obj.MaxClockSpeed
            End If
        Next
     
        frequence_proc = lAns / 1000 ' fréquence en GHz
     
    End Function
    et la définition de Sleep :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

  6. #6
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Points : 5 537
    Points
    5 537
    Par défaut
    Re,

    Tant le "bidouillage" que tu nous montres là que ce que tu as écrit dès ton 1er message
    Je me suis apperçu qu'en affichant l'itération dans un MsgBox, il n'y avait plus d'erreur
    donne très fortement à penser que ton tableau n'est pas encore rempli lors de l'exécution de ton code ...
    tout est probablement dans :
    sortieIndice est un tableau de Double avec des éléments de 1 à 721,
    il est le résultat d'une routine un peu trop complexe pour l'expliquer ici
    .

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 23
    Points : 15
    Points
    15
    Par défaut
    Admettons. Mais à partir du moment où je l'ai déclaré, il est au moins rempli de zéros, non ? Ou alors, ce que tu veux dire, c'est que le tableau ne serait pas encore alloué au moment du plantage ?

    [EDIT]
    Je viens de faire un test : j'ai mis la petite boucle d'attente juste avant la boucle de recherche du premier élément non-nul, et là plus de bug.

    Entre la déclaration de mon tableau et mon bout de code, je fais appel à une DLL Fortran pour le remplir. VBA continuerait-il l'execution de son code avant la fin de l'exécution de l'appel à la DLL ?

  8. #8
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Tu n'as pas un moyen propre de savoir quand le traitement du tableau est terminé?

    PGZ

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 23
    Points : 15
    Points
    15
    Par défaut
    Tu veux dire pendant l'execution de la DLL ? Dans ce cas, non, je ne vois pas comment faire.

  10. #10
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Points : 5 537
    Points
    5 537
    Par défaut
    Voilà pourquoi je te posais une question précise, plus haut !
    - qu'est exactement sortieIndice ? comment et par quoi est-il défini et chargé ?
    Seul l'examen de ce code permettrait de décider valablement de l'attitude à observer.
    Dans l'état actuel des choses, c'est une inconnue gênante (je ne sais même pas si l'on peut envisager l'utilisation de la fonction WaitForSingleObject de l'Api de Windows)...

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 23
    Points : 15
    Points
    15
    Par défaut
    J'aimerais fouiller un peu plus, mais là j'ai pas matériellement le temps, la rustine devra faire l'affaire (Je vais quand même pas commencer à gérer des problèmes de synchronisation dans une macro Excel !). En tout cas merci pour ton aide !

Discussions similaires

  1. Réponses: 2
    Dernier message: 03/10/2014, 11h33
  2. Insérer <form> dans une boucle for et traiter par POST
    Par IRONicMAN dans le forum Langage
    Réponses: 10
    Dernier message: 26/03/2010, 14h09
  3. Réponses: 8
    Dernier message: 05/12/2008, 11h43
  4. prendre par id dans une boucle
    Par kaking dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 23/09/2008, 10h19
  5. division par 0 dans une requête donne #Erreur
    Par bugprog dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 29/05/2007, 09h57

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