Erreur macro et formulaire

Bonjour,

Je vous contact car je n'arrive plus à utiliser mon ficher excel.

Une personne de mon service à créé un fichier excel avec beaucoup de macro pour l'utiliser comme GMAO.

Sauf que depuis son départ il y a beaucoup de bug et nous ne savons pas comment les résoudre.

Cela a commencé par le fait que les objets ne se lance plus puis après certains utilisateurs n'arrivent plus à sauvegarder les nouvelles interventions.

Est-ce que quelqu'un pourrait jeter un œil pour voir si il n'y a rien d’anormal et si le ficher n'est pas trop complexe inutilement.

Merci beaucoup de votre aide, ce fichier est important nous nous en servons tous les jours pour le travail et la planification.

Benoit

Bonjour Benoit40 le forum

je voulais regarder ton fichier et tester, mais 58 Mo pour ton fichier, tu as quoi là-dedans??

des photos en pagaille???

à te relire

Papou

Bonjour Benoit40 le forum

je viens de charger le fichier, mais franchement tu veux de l'aide????

Même pas un mode d'emploi succinct dans le fichier pour savoir ou chercher les erreurs!!!!

Comment veux-tu que l'on sache utiliser ton fichier sans un minimum d'explication??

Et surtout des explications qui mènent vers un bug de préférence, que l'on puisse tester et corriger.

tu utilises quelle version Excel???

Bonne journée

Papou

Bonjour,

Fichier lourd Et il y a du boulot ! Autant dire que je ne suis pas candidat pour me lancer là-dedans... mais je veux bien apporter une petite contribution pour faire comprendre une partie au moins des problèmes rencontrés, à partir de la procédure qui se lance au démarrage et déclenche une erreur !

D'abord si VBA lira le code quelle que soit la façon dont on l'écrit, il n'en est pas de même du programmeur humain qui a besoin d'une mise en forme lui permettant de le lire rapidement sans se tromper et d'y travailler. Cette mise en forme se nomme indentation et consiste en des retraits successifs d'une tabulation des lignes de code selon les instructions utilisés, de sorte que pour les instructions qui s'écrivent en 2 parties (initialisation de l'instruction et fin) l'oeil puisse se déplacer instantanément à la verticale sans rencontrer d'obstacle (sauf instructions intermédiaire pour celles qui en disposent (comme ElseIf et Else au sein d'une instruction If... End If).

Je mets le code de la procédure tel qu'il figure dans le fichier :

Public Sub temp_arret_today()

'déclaration variable
Dim nb_cur As Single
Dim nb_tmps As Single
Dim result As String
Dim result2 As String
Dim T As Date

'init variable
nb_cur = 0
T = Date
 T = Format(T, "dd mm yyyy")
derniere_ligne = Range("A4").End(xlDown).Row

'création du tableau
ReDim tab_arret(derniere_ligne)
'calcul temps de panne
 For i = 12 To derniere_ligne
  m = Format(Range("E" & i).Value, "dd mm yyyy")
 If m = T Then
      tab_arret(i) = Range("O" & i).Value

     End If
    If tab_arret(i) = "Curative" Then

        nb_cur = nb_cur + Cells(i, 12).Value
        nb_tmps = nb_tmps + Cells(i, 19).Value

       End If
        Next i
  result = nb_cur & " " & "min"
       result2 = nb_tmps & " " & "min"

       Worksheets("histo").Range("C1").Value = "Temps d'indisponibilité aujourd'hui"
       Worksheets("histo").Range("D1").Value = result
       Worksheets("histo").Range("E1").Value = "Temps d'interruption aujourd'hui"
       Worksheets("histo").Range("F1").Value = result2
End Sub

Beaucoup de lignes sont collées à la marge entre Sub et End Sub. On ne devrait rien trouver, hors des étiquettes de branchement (de façon à les distinguer au premier coup d'oeil). Je rencontre un For, je devrais pourvoir trouver le Next correspondant à ce For à la verticale de ce dernier, sans rien rencontrer d'autre entre, c'est loin d'être le cas, et le Next se ballade sur un retrait différent. Même chose pour le If qui suit, étant à l'intérieur d'une instruction For... Next, on devrait le trouver en retrait d'une tabulation par rapport au For, et à la verticale du If on devrait tomber sur le End If correspondant, ce n'est pas du tout le cas...

Je te remets le même code sans modification, réindenté :

Public Sub temp_arret_today()
    'déclaration variable
    Dim nb_cur As Single
    Dim nb_tmps As Single
    Dim result As String
    Dim result2 As String
    Dim T As Date
    'init variable
    nb_cur = 0
    T = Date
    T = Format(T, "dd mm yyyy")
    derniere_ligne = Range("A4").End(xlDown).Row
    'création du tableau
    ReDim tab_arret(derniere_ligne)
    'calcul temps de panne
    For i = 12 To derniere_ligne
        m = Format(Range("E" & i).Value, "dd mm yyyy")
        If m = T Then
            tab_arret(i) = Range("O" & i).Value
        End If
        If tab_arret(i) = "Curative" Then
            nb_cur = nb_cur + Cells(i, 12).Value
            nb_tmps = nb_tmps + Cells(i, 19).Value
        End If
    Next i
    result = nb_cur & " " & "min"
    result2 = nb_tmps & " " & "min"
    Worksheets("histo").Range("C1").Value = "Temps d'indisponibilité aujourd'hui"
    Worksheets("histo").Range("D1").Value = result
    Worksheets("histo").Range("E1").Value = "Temps d'interruption aujourd'hui"
    Worksheets("histo").Range("F1").Value = result2
End Sub

J'espère que tu vois la différence, ce code est lisible, le précédent non ! Pour le lire en l'interprétant correctement on met en moyenne 4 fois plus de temps pour le précédent que celui ci-dessus. tu comprendras que cela devient vite considérable...

Je scinde mon propos pour éviter un post fleuve... A suivre : l'analyse de la procédure pour y déceler les raisons pour lesquelles elle plante au démarrage ou aboutir à des erreurs...

Bonjour Mferrand Benoit 40 le forum

mais le principal problème est de savoir sur quelle page lancer la macro, car cette macro ne fait en l’occurrence référence qu'à la feuille active, bilan si la feuille n'est pas la bonne lors de l'enregistrement, bah la macro plante à l'ouverture!!!

Donc Incrémentation oui bien sur, tu as raison et tu sais que j'aime bien les codes bien lisibles, mais surtout les explications de comment doit marcher le fichier???

Quelle était la feuille de démarrage quand le fichier fonctionnait correctement??? etc etc un minimum d'explications pour que l'on puisse modifier

le résultat va en feuille Histo mais rien ne dit que la macro se fait sur cette feuille, enfin pour moi c'est pas clair et une macro se doit d'être précise, enfin c'est ma conception de la chose.

a+

papou

Bonjour à tous merci de vos retours,

En effet je sais que c'est une usine à gaz mais c'est justement le problème.

Le créateur du fichier en as trop fait et on ne sais plus d'où provienne les erreurs.

Nous utilisons essentiellement la page "histo" avec le bouton "insérer un intervention"

Une fois l'intervention enregistré nous utilisons le bouton "temps d'arrêt journalier" pour visualiser le temps d'indisponibilité et le temps de coupure (l’affichage du temps fonctionne bien).

* La où ça pose problème c'est quand on l'ouvre sur le serveur de fichier à distance l'erreur "pas d'objets trouvé dans la bibliothèque" apparaît.

Avant nous pouvions l'ouvrir de n'importe où.

* Un autre problème vient aussi lors de l'ajout d'une intervention. Hier nous avions rentré plein de nouvelles intervention le fichier à bien été sauvegardé mais à l'ouverture le lendemain par un autre technicien. Aucune donné n'a été rentré.

Est-ce un problème d'identification et de saisie ?

* Un autre onglet qui fonctionné avant et que l'on souhaiterait utiliser c'est la page "planning semaine".

Nous avons fait un essai de remplir la page "Planning OSR 2017" qui sert de base, mais cela n'a pas fait grand chose.

Je sais que ce n'est pas évident à comprendre car il y a beaucoup de chosse dessus mais en discutant et en expliquant au fur et à mesure peut-être que l'on va arriver à trouver ce qui plante.

Merci en tous cas de vos retours !

Benoit

Salut Paritec !

Je poursuis... On va entrer dans les détails, aussi bien ce qui peut s'avérer important que ce qui est sans incidence, mais qu'il est souhaitable de connaître si l'on veut travailler correctement...

Commençons par la déclaration de procédure !

Public Sub temp_arret_today()

Toutes les procédures VBA sont publiques par défaut, autrement dit qu'on mette Public Sub ou simplement Sub c'est du pareil au même, cela ne change strictement rien dans la façon dont la procédure sera appelée.

On peut donc se dispenser de le mettre sans que cela nuise à la distinction des procédures publiques de celles qui ne le sont pas, lesquelles seront obligatoirement affublées du mot-clé Private.

Si on peut s'en dispenser et économiser ainsi du texte écrit, cela ne gêne nullement que la déclaration soit affublée de Public... à condition de ne pas ignorer qu'il s'agit d'une caractéristique par défaut, qui rend la procédure accessible de n'importe quel point du projet (soit de n'importe quel module), et que si elle se trouve dans un module privé elle devra être appelée en faisant référence au module. Car si on ignore ce qu'il en est de la portée des procédures et que le fait de mentionner Public ou non est totalement indifférent, on demeure à la merci d'erreurs ultérieures...

Suivent les déclarations de variables :

    Dim nb_cur As Single
    Dim nb_tmps As Single
    Dim result As String
    Dim result2 As String
    Dim T As Date

Un demi bon-point pour l'auteur ! qui déclare 5 variables et les déclare en-tête de la procédure. Cela fait au moins une convention importante de respectée, il en utilise cependant deux autres dans le cours de la procédure : tab_arret, variable tableau non déclarée, et de même pour derniere_ligne qui aurait due être déclarée As Long !

Il y a aussi le mode d'écriture des déclarations qui me chiffonne, très à la mode semble-t-il sur le Net, qui consiste à les placer en énumération, une variable par ligne, et sans retrait par rapport à la déclaration de procédure...

Je veux bien admettre cette façon de faire comme variante, car elle ne contrevient pas aux règles essentielles, mais ne la partage pas du tout. En particulier parce que si on déclare 10 ou 15 variables ou plus, on aboutit à des procédures excessivement longues rien qu'en raison des déclarations. On les voit aussi bien sinon mieux lorsqu'elles figurent sur une ligne, voire deux, sans avoir à parcourir une longue liste. Ce n'était pas à la mode il y a 25 ans, et je ne vois pas de raison positive à ce changement (purement) de moeurs, qui fort heureusement n'est pas général.

J'écrirai donc pour ma part, en une ligne :

   Dim nb_cur!, nb_tmps!, derniere_ligne&, result$, result2$, T As Date, tab_arret()

en utilisant les caractères de déclaration de type (disponibles pour les variables numériques et String, qui permettent de raccourcir l'écriture) et en réintroduisant la variable tableau (de type Variant) et la variable Long oubliées.

On poursuit sur l'initialisation des variables :

    nb_cur = 0
    T = Date
    T = Format(T, "dd mm yyyy")
    derniere_ligne = Range("A4").End(xlDown).Row
    ReDim tab_arret(derniere_ligne)

C'est là que des petits problèmes vont commencer à apparaître.

La première ligne ci-dessus est tout à fait inutile ! Dès lors qu'une variable est déclarée elle acquiert une valeur par défaut, pour une variable numérique, ce sera la valeur 0, pour une variable String, ce sera la valeur chaîne vide (que l'on note : ""), une variable de type Variant aura la valeur Empty (vide), etc.

Il n'est donc pas utile d'initialiser une variable à la valeur qu'elle a déjà ! Cela ne nuit pas, mais comme toujours, il importe de le savoir...

On affecte la date du jour à la variable T.

Rien de spécial à dire, sinon qu'elle déclenche une erreur de compilation qui se fixe curieusement sur la fonction Date, mais est en fait provoquée par les références Outlook manquantes sur ma machine. C'est donc autre chose.

Par contre la ligne en-dessous pose problème : T est une variable de type Date, et on lui réaffecte une valeur de type String, issue de la valeur date formatée (la fonction Format ne peut produire qu'une donnée de type String. Cela ne déclenche cependant pas d'erreur d'incompatibilité de type parce que VBA convertit automatiquement en date toute chaîne susceptible d'être convertie, mais cette conversion étant sauvage elle pourra produire des erreurs car non réalisée sur les paramètres régionaux Français-France...

En tout état de cause on introduit ici un élément fluctuant qui pourra provoquer des surprises...

Ligne suivante : on cherche la dernière ligne utilisée en colonne A... Oui ? Mais de quelle feuille ?

Là il faut mener une véritable enquête pour aboutir à la certitude que le code doit opérer sur la feuille histo (la mention de cette feuille dans la fin de la procédure ne le garantit pas et ce qui l'indique, ce sont les types de données manipulés dans les colonnes de la feuilles, qui ne peuvent que correspondre à cette dernière...)

Seulement, cette procédure est lancée à l'ouverture du fichier par Workbook_Open, sans activation préalable de la feuille, et rien ne peut donc garantir que ce soit la feuille active à l'ouverture, et le code essaiera d'opérer sur la feuille active quelle qu'elle soit, qui peut être n'importe quelle des nombreuses feuilles du classeur !

On joue donc à la loterie avec des expressions ainsi non qualifiées.

Et que la feuille soit ou non activée au démarrage, pour assurer fiabilité et rapidité du code il demeure indispensable de référer explicitement la plage ciblée (colonne A) à sa feuille parente (histo).

On redimensionne ensuite le tableau: rien à dire à ce stade, il faut voir dans la suite...

Je ne vais pas trop m'étendre sur la suite, d'autant plus que la moindre manipulation manuelle pour aller voir tel ou tel point de la feuille prend un temps fou... Pour rendre ce classeur utilisable, il faudra le scinder en divers classeurs fonctionnels de façon autonome...

En tout état de cause on poursuit par une boucle de la ligne 12 à la fin...

Pourquoi la ligne 12 alors que les données commencent ligne 4 ? Mystère !

Là on jongle encore avec les dates... une variable m (non déclarée, qui m'avait échappée), donc de type variant à laquelle on affecte la date de la colonne E formatée avec Format, avec les mêmes risques évoqués pour T...

Ceci étant cela explique qu'on puisse ne pas avoir d'erreur générée par ce problème de date, car si VBA opère une conversion erronée, il l'opèrera de la même façon deux fois ! Par contre cela ne saurait garantir que la date testée soit celle que l'on croit, ce qui peut fort bien passer inaperçu...

Ce qui apparaît par ailleurs problématique, c'est qu'on a dimensionné un tableau de plusieurs milliers d'éléments, dont on ne va utiliser que les quelques éléments correspondant à la date testée, les seuls que l'on affecte, le reste restera vide. Et non seulement cela, on reteste immédiatement la valeur affectée au tableau pour cumuler les valeurs à obtenir en résultats dans les variables nb_cur et nb_tmps !

Soit à dire que ce tableau ne joue qu'un rôle d'intermédiaire parfaitement inutile, on pouvait servir les variables à partir du premier test sans passer par le tableau.

De même la boucle est pour l'essentiel inutile, commencer par chercher la date testée (les enregistrements étant supposés en ordre chronologique) aurait évité de tester plusieurs milliers de lignes...

J'ai dit supposés chronologique car il y a un trou dans la suite de de la feuille après lequel on retrouve des lignes de mars 2018... Une fausse manipulation à un moment donné aura provoqué cette détérioration.

la feuille est donc de plus à réparer...

Je passe sur l'inutile répétition de Worksheets("histo") : on devait utiliser une instruction With... L'inutile affectation de mentions d'en-têtes qui mises un fois n'ont plus à bouger...

Et on peut conclure qu'on a affaire à une procédure compliquée et à risques multiples, là où une procédure simple et beaucoup plus rapide aurait dû faire le job.

Plus généralement, j'ai aussi compté 12 modules standard... soit 10 de trop : je t'en accorde 2 car il me paraît légitime de dissocier les déclarations d'API et quelques procédures afférentes (encore que j'ai aperçu qu'il s'agissait d'intervention sur l'affichage des Userforms, auquel cas j'ai tendance à penser qu'il s'agit de gadgets inutiles car on peut faire autrement... mais je n'ai pas creusé).

En tout cas, à 1 procédure par module, dont beaucoup d'une ligne, il y a peu de code dans le classeur, et disperser ça dans 12 modules c'est à la fois un gaspillage de ressources, et d'énormes pertes de temps pour travailler !

Cordialement

(je laisse la main à Paritec... )

Re Mferrand benoit40 le forum

oui moi cela ne me gêne pas, mais je pars en vacances ce soir ou demain matin (quand j'aurai fini mon travail), et je ne suis pas sur d'avoir le wifi ou je vais alors!!!

bon si j’arrive à me connecter, je verrai pour modifier l'essentiel, je ne te cache pas Mferrand que je n'ai pas encore lu tes deux derniers post, même pas ce que benoit nous a écrit, j'espère qu'il a bien expliqué que nous puissions avancé sur le sujet

si je trouve un peu de temps avant de partir je regarderai tout cela

a+

papou

Re,

Merci encore pour vos retours !

N’hésitez pas à me demander de l'aide pour comprendre le fonctionnement du fichier.

Comme évoqué, il y a tellement de chose dessus que la première étape sera de bien tout épurer et de séparer si besoin tout cela.

Je pense que l'on pourras enlever certaines fonctions inutiles qui pollues le fichier

Merci.

Bonsoir Mferrand Benoit40 le forum

bon alors un coup de balai et voilà ton fichier passé de 58,4 MO à 1,97 MO, avec les mêmes feuilles et les mêmes données.

Chercher l'erreur!!! ?????

Voilà maintenant moi je n'ai pas excel 2013 ou 2016 alors les dtpicker et monthview je ne peux pas les tester, de toutes façons ce que j'en pense c’est que c'est de la merde les dtpicker en parlant poliment!!! , une honte de la part de microsoft de ne pas avoir un simple calendrier passe partout dans toutes les versions excel et surtout compatible toutes versions, moi perso j'ai un calendrier avec un module de classe et là c'est compatible toutes version , mais bref.

Pour l'ouverture de ajout intervention il faut que tu testes et que tu me redises

une certitude j'ai refais la macro de départ et maintenant c'est résultat immédiat, bref on va avancer, mais sans pouvoir tester cela va être compliqué, surtout que je ne connais pas le résultat à obtenir!!!!!!

Une certitude le code de l'userform entrer une intervention et une catastrophe.

a+

Papou

https://www.cjoint.com/c/HHyrmNixdYQ

Oula énorme !!!

Je vais regarder ça rapidement et te fait un retour !

Le formulaire des ajouts d’interventions il sert « seulement » à incrémenter le tableau pour le calcul du taux de disponibilité.

Mais lors de cet ajout, une pondération sur le temps d’arrêt est fait en fonction du type de panne.

Car si la panne touche un appareillage non imprtant le « temps de disponibilité » est plus faible que le temps d’arrêt réel.

Pour le calcul normalement cela fonctionne toujours, je pense que le problème viens de l’ajout de ligne dans le tableau.

Le formulaire n’affiche pas d’erreurs mais il n’enregistre pas l’intervention.

Enfin, je vais tester tout ça et reviens vers vous.

En tous cas on avance !

Merci encore !

Bonjour Benoit40 le forum

bon alors après 3 heures de recherche je pense avoir bien décortiqué le truc pour les ajouts d'interventions.

J'ai fait dans un premier temps un peu le ménage, j'ai déclaré les variables à peu prêt comme il faut, je dis a peu près car certaines variables sont comme le reste très parlantes, exemple une variable Numéro pour stocker un string donc un texte!!!!!

Pourquoi être logique, cela ne sert à rien..........

Bref voilà donc je pense avoir réglé le problème de l'ajout des interventions pour tous les gars à toi de tester et tu me rediras

une certitude le gars qui a pondu cela, a fait du codage de bricoleur pas autre chose.

dans l'attente de te relire

a+

Papou

https://www.cjoint.com/c/HHzhLd3GNPQ

Rechercher des sujets similaires à "erreur macro formulaire"