Signaler

Excel cesse de fonctionner [Résolu]

Posez votre question will_1234 7Messages postés lundi 2 février 2015Date d'inscription 18 juillet 2017 Dernière intervention - Dernière réponse le 18 juil. 2017 à 17:59 par Patrice33740
Bonjour à tous, dans mon classeur excel, j'ai une macro qui me permet d'insérer une ligne en double cliquant (dans la 4e colonne).

98% du temps sa fonctionne à merveille et le reste du temps, excel "cesse de fonctionner" et redémarre.

Si quelqu'un aurait une piste à savoir pourquoi le logiciel fait cela.

Voici le code en question.

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
With Application
.ScreenUpdating = False
.Calculation = xlManual
End With

If ActiveCell.Column = 4 Then
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
ActiveCell.Offset(1, 0).Rows("1:1").EntireRow.Select
Selection.Insert Shift:=xlDown
ActiveCell.Offset(0, 9).Range("A1").Select
Application.CutCopyMode = False
Selection.ClearContents
ActiveCell.Offset(0, -4).Range("A1:B1").Select
Selection.ClearContents
ActiveCell.Offset(0, -2).Range("A1").Select
Selection.ClearContents
ActiveCell.Select
End If

With Application
.Calculation = xlAutomatic
.ScreenUpdating = True
End With
End Sub
Utile
+0
plus moins
Bonjour,

Il faut éviter l'emploi de Select, Selection et ActiveCell
Éviter aussi le Copy /Insert via le Presse papier (ou vider le Presse papier avant la copie mais ça marche pas à 100%).
Donnez votre avis
Utile
+0
plus moins
Bonjour à tous,

En suivant les indications judicieuses de Patrice (que je salue), voici ta macro écrite autrement. Essaies de voir si cela répare ton problème.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    With Application
        .ScreenUpdating = False
        .Calculation = xlManual
    End With
    Cancel = True
    If Target.Column = 4 Then
        With Target
            .Offset(1, 0).EntireRow.Insert Shift:=xlDown
            Rows(.Row).Resize(2).FillDown
            .Offset(1, 6).ClearContents
            .Offset(1, 2).Resize(1, 2).ClearContents
            .Offset(1, 0).ClearContents
            .Offset(1, 0).Activate
        End With
    End If
    With Application
        .Calculation = xlAutomatic
        .ScreenUpdating = True
    End With
End Sub
Donnez votre avis
Utile
+0
plus moins
Bonjour,

Voici une version légèrement optimisée du code de gbinforme :


Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
  If Target.Column <> 4 Then Exit Sub
  With Application
    .ScreenUpdating = False: .Calculation = xlManual
  End With
  With Target
    .Offset(1, 0).EntireRow.Insert Shift:=xlDown
    Rows(.Row).Resize(2).FillDown
    .Offset(1).ClearContents
    .Offset(1, 2).Resize(, 2).ClearContents
    .Offset(1, 6).ClearContents
    .Offset(1).Activate
  End With
  Application.Calculation = xlAutomatic
End Sub


NB : Application.ScreenUpdating = True est implicite et automatique
avant la sortie d'une sub, donc inutile de le mettre explicitement.
 
Patrice33740 6126Messages postés dimanche 13 juin 2010Date d'inscription 13 septembre 2017 Dernière intervention - 17 juil. 2017 à 23:01
Ce code pseudo-optimisé est loin d'être aussi bien écrit que celui de gbinforme (bonsoir à toi).

Quand on code proprement on évite tout ce qui est implicite !!!
Répondre
steve- 18 juil. 2017 à 02:56
 
Bonsoir Patrice33740,

Dans mon message du 17 juillet à 22:50, j'avais bien précisé d'emblée :
« Voici une version légèrement optimisée du code de gbinforme ».

Contrairement à ce que tu penses, je n'ai pas fait une pseudo-optimisation,
et je prouve les améliorations apportées :

1) Ligne 4 : on sort de suite de la sub si Target.column <> 4 (donc si l'utilisateur
n'a pas cliqué sur une cellule de la colonne D) ; avantage : inutile de faire tout
ce qui suit (y compris les instructions Application.xxx).

2) J'ai volontairement enlevé l'instruction Application.ScreenUpdating = True
qui était inutile : lis mon message à gbinforme du 18 juillet à 1:07 ; je ne vais
pas réécrire ce que j'ai amplement démontré !

3) J'ai remplacé 2 .Offset(1, 0) par .Offset(1) ; en effet, quand un paramètre
vaut 0 (pour cette instruction), c'est inutile de le mettre ; même si c'est pour
la colonne ; exemple : .Offset(, 1) ; note bien la virgule juste après "(" ! et si
Microsoft avait voulu absolument qu'on mette les 2 paramètres, ils seraient
obligatoires et pas facultatifs ; attention : sur une feuille Excel, l'instruction
DECALER() correspondante exige bien les 2 paramètres ; pas en VBA.

4) Lignes 11 à 13 : j'ai modifié l'ordre des 3 .Offset() pour les mettre dans
un ordre plus naturel (car de gauche à droite) : on efface d'abord Dxx,
puis Fxx:Gxx, puis Jxx (où xx est le bon n° de ligne).

===============================

Tu as écris : « Quand on code proprement on évite tout ce qui est implicite !!! » ;
tu as ta façon de programmer et j'ai la mienne ; je considère qu'à condition de
bien savoir ce que l'on fait, on peut éviter de mettre des choses explicites.

Exemple : rien n'interdit d'écrire cette référence explicite complète :
MsgBox Workbooks("Classeur X").Worksheets("Feuil").Range("B2")

Mais si on lance toujours la macro à partir de Feuil1 du Classeur X,
c'est inutile et il suffit de mettre : MsgBox Range("B2") ; et même,
en utilisant la notation abrégée, ça donne : MsgBox [B2] (qui est
strictement équivalent) ; quelle est l'instruction la plus courte et
la plus clairement lisible ? c'est : MsgBox [B2]

-------------------------------------------------------

Pour être sûr qu'une macro se lance depuis la bonne feuille, ici "Feuil1",
mettre en début de macro : If ActiveSheet.Name <> "Feuil1" Then Exit Sub
ou carrément (selon les cas), mettre : Worksheets("Feuil1").Select

S'il y a plusieurs classeurs, alors ajouter un test pour vérifier si on est sur
le bon classeur.

Mais effectivement, il y a des fois où même en procédant à ma façon, je dois
quand même préciser explicitement la feuille ou le classeur à utiliser.

-------------------------------------------------------

Encore une fois, à chacun sa façon de programmer ; en aucun cas tu n'as
le droit de chercher à me dicter la mienne ; et inversement, je n'ai pas à
exiger que tu programmes à ma façon.

Aussi, ta remarque bien péremptoire « Quand on code proprement »
est tout à fait déplacée !

Cordialement
 
Répondre
Patrice33740 6126Messages postés dimanche 13 juin 2010Date d'inscription 13 septembre 2017 Dernière intervention - 17 juil. 2017 à 23:14
Steve, pour le ScreenUpdating, regardes ce post :
http://www.commentcamarche.net/forum/affich-33931181-bug-affichage-suite-a-l-execution-du-code
Répondre
steve- 18 juil. 2017 à 04:29
 
Patrice, j'ai bien suivi ton lien et lu l'article ; c'est effectivement très intéressant,
mais ça « semble lié à la nouvelle interface SDI apparue avec Excel 2013 » ;
donc aucun problème avec les versions antérieures (et j'ai Excel 2007).

Lis mes 2 messages précédents ; notamment celui de ce jour à 1:07 pour
voir ce que j'ai écrit à propos de : Application.ScreenUpdating = True

L'anomalie décrite par l'article du lien est-elle un bug des 2 dernières
versions d'Excel (2013 et 2016) ? je n'en sais rien ! mais c'est sûr que
ça complique bien les choses !  :(  moi, ce n'est pas ça qui me donne
envie de passer à une version ultérieure, bien au contraire !!! donc
pour l'instant, je garde mon Excel 2007 !  :)
 
Répondre
will_1234 7Messages postés lundi 2 février 2015Date d'inscription 18 juillet 2017 Dernière intervention - 18 juil. 2017 à 16:21
Bonjour à tous, merci pour vos solution, aucun bug jusqu'à maintenant ! Petit précision, ma cellule de la colonne 4 est fusionné à ma cellule de la 5e colonne. Si je prend le code tel quel, sa génère une fenetre qui me dit que le code ne gère pas les cellule fusionné.

Est-il possible de modifier le code en ce sens.

Merci beaucoup de votre aide rapide et efficace!
Répondre
Donnez votre avis
Utile
+0
plus moins
Bonjour,

Le code de gbinforme (que je salue) modifié :
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    With Application
        .ScreenUpdating = False
        .Calculation = xlManual
    End With
    Cancel = True
    If Target.Column = 4 Then
        With Target
            .Offset(1, 0).EntireRow.Insert Shift:=xlDown
            Me.Rows(.Row).Resize(2).FillDown
            .Offset(1, 6).Formula = ""
            .Offset(1, 2).Resize(1, 2).Formula = ""
            .Offset(1, 0).Formula = ""
            .Offset(1, 0).Activate
        End With
    End If
    With Application
        .Calculation = xlAutomatic
        .ScreenUpdating = True
    End With
End Sub
will_1234 7Messages postés lundi 2 février 2015Date d'inscription 18 juillet 2017 Dernière intervention - 18 juil. 2017 à 17:01
UN gros merci, sa semble avoir régler mon problème !

Merci à tous.

PS: Où puis-je apprendre à coder efficacement sous vba ?
Répondre
Patrice33740 6126Messages postés dimanche 13 juin 2010Date d'inscription 13 septembre 2017 Dernière intervention - 18 juil. 2017 à 17:59
« Où puis-je apprendre à coder efficacement sous vba ? »
Avec du temps, beaucoup d'erreurs et de la rigueur.

Comme tu as pu le constater, les erreurs proviennent très souvent d'une forme de codage qui manque de rigueur.
Sur le web on trouve de très nombreux cours VBA, Malheureusement, je n'en connais aucun qui s'affranchisse de l'utilisation de forme de code implicite (simplifié) dans les apprentissages initiaux.

Voici un des meilleurs cours (un peu ancien mais toujours d'actualité) :
ftp://ftp-developpez.com/bidou/Cours/VBA/formationVBA.pdf

Cdt
Patrice
Répondre
Donnez votre avis

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !