Execution macro automatique, changement valeur

Bonjour,

Je dispose d'un fichier avec 400 lignes et une vingtaine de colonnes. Pour le moment, j'ai une macro qui enregistre des infos de ce tableau dans d'autres fichiers excels qu'il crée s'ils n'existent pas et les modifie si les données du tableau source changent. Le problème c'est que pour l'instant pour le faire cela ouvre et recherche chaque fichier même si je ne change qu'une ligne du tableau. Cela prend donc environ 5 min. Je précise que pour le moment j'actionne la macro avec un bouton.

Je souhaiterai faire en sorte que la macro vérifie les données dont la valeur a changé et qu'elle mette à jour les dossiers s'y rapportent uniquement.

Comment puis-je faire ?

Je joins mes fichiers pour vous donner une idée des tableaux ainsi que la macro dans la liste client :

Option Explicit

Sub test3()
Dim Sh1 As Worksheet, Sh2 As Worksheet, Wb1 As Workbook, Wb2 As Workbook, Ch1$, Ch2$, i&, j%, b%
    'chemin vers le doossier client à adapter
    Ch1 = "C:\Users\DerJul\Desktop\Stage L3\internet\clients\mission comptable\"
    'nom complet classeur matrice à adapter
    Ch2 = "C:\Users\DerJul\Desktop\Stage L3\internet\Matrice prévisions clients internet.xls"
    'déclaration classeur et feuille données client
    Set Wb1 = ThisWorkbook
    Set Sh1 = Wb1.Worksheets("Feuil1")
    'pour chaque ligne de la feuille données client
    For i = 4 To Sh1.Cells(Rows.Count, 1).End(xlUp).Row
        'si le classeur portant le nom du client n'existe pas à l'endroit spécifié
        If Dir(Ch1 & Sh1.Cells(i, 1) & ".xlsm") <> "" = False Then
            Workbooks.Open Ch2 'ouvrir le classeur matrice
            Set Wb2 = Workbooks("Matrice prévisions clients internet.xls")
            Set Sh2 = Wb2.Worksheets("prévisions en cours")
            'remplir les informations dans le classeur matrice
            Sh2.Cells(2, 2) = Sh1.Cells(i, 1)
            Sh2.Cells(3, 2) = Sh1.Cells(i, 3)
            Sh2.Cells(5, 2) = Sh1.Cells(i, 24)
            Sh2.Cells(6, 3) = Sh1.Cells(i, 7)
            'sauvegarder le classeur matrice sous le nom du client
            Wb2.SaveAs Ch1 & Sh1.Cells(i, 1) & ".xlsm", FileFormat:=52
            'pour xls ActiveWorkbook.SaveAs Ch1 & w.Cells(i, 1) & ".xls", FileFormat:=56
            'pour xlsx : ActiveWorkbook.SaveAs Ch1 & w.Cells(i, 1) & ".xlsx", FileFormat:=51
        Else 'sinon
            Workbooks.Open Ch1 & Sh1.Cells(i, 1) & ".xlsm" 'ouvrir le classeur client
            Set Wb2 = Workbooks(Sh1.Cells(i, 1) & ".xlsm")
            Set Sh2 = Wb2.Worksheets("prévisions en cours")
            'vérifier les infos et actualiser si nécessaire
            If Sh2.Cells(2, 2) <> Sh1.Cells(i, 1) Then
                Sh2.Cells(2, 2) = Sh1.Cells(i, 1)
                b = True
            End If
            If Sh2.Cells(3, 2) <> Sh1.Cells(i, 3) Then
                Sh2.Cells(3, 2) = Sh1.Cells(i, 3)
                b = True
            End If
            If Sh2.Cells(5, 2) <> Sh1.Cells(i, 24) Then
                Sh2.Cells(5, 2) = Sh1.Cells(i, 24)
                b = True
            End If
            If Sh2.Cells(6, 3) <> Sh1.Cells(i, 7) Then
                Sh2.Cells(6, 3) = Sh1.Cells(i, 7)
                b = True
            End If
            'sauvegarder si au moins une modif
            If b Then Wb2.Save
        End If
        'fermer le classeur créé ou modifié
        Wb2.Close
    Next i
End Sub

Merci de votre aide

Bonjour,

Est-ce que sur ton fichier principal l'on peu ajouter une colonne en Y par exemple, masquée si tu veux même,?

Cette colonne servirait à noter la date du fichier de données associé .

il suffirait de tester si la date du fichier disponible est la même que celle de la colonne Y.

Si cette solution te conviens je peux regarder pour l'intégrer dans ton code , code qu'il faudrait d'ailleurs nettoyer et optimiser

Salut DerJul et le forum

Comment puis-je faire ?

Tu travailles en xlsm (version 2007 et suivantes), je n'ai que 2003. Donc, je ne peux donner que ce que je ferais à un fichier xls

Clic-Droit sur le nom de l'onglet => menu contextuel>>Visualiser le code

Case de Gauche, avec le menu Déroulant : Worksheet

Case de droite avec le menu déroulant : Change

Tu te retrouves avec une macro Worksheet_Change qui se lance à chaque sortie du mode édition de cellules.

Ton code sera de ce style :

Private Sub Worksheet_Change(ByVal Target As Range)
'Déclaration =====================================
Dim Sh1 As Worksheet, Sh2 As Worksheet, Wb1 As Workbook, Wb2 As Workbook, Ch1$, Ch2$, i&, j%, b%
Dim Cel As Range, Plage As Range
'Validité ========================================
Set Plage = Intersect(Target, Union(Columns(1), Columns(3), Columns(7), Columns(24)))
If Plage Is Nothing Then Exit Sub
'Traitement =====================================
For Each Cel In Plage
    'travail à faire
End If
End Sub

Si Target (variable contenant les cellules modifiées, mise à jour par Exccel) contient des cellules des colonnes 1, 3, 7, 24, les mettre dans Plage

Si Plage n'est pas vide, s'occuper de chacune d'elle (travail à faire ).

Je ne peux pas aller plus loin, parce qu'il faut raisonner différemment quand on utilise une macro à lancement automatique :

  • Quelque soit le nombre de cellules modifiées (target peut concerner plusieurs cellules par copier/coller), elle doit assurer son travail => c'est la raison de la boucle Cel.
  • Je veux modifier les cellules 1, 3, 7 et 24 d'une même ligne : soit je fais un savant copier/coller et ça marche. Mais c'est complexe. Ce qui va se passer, c'est que je vais, généralement, modifier une cellule, puis la suivante, puis la troisième, puis la dernière. Pour moi, c'est une modif unique. Mais pour Excel, cela représente 4 modifs distinctes. On pourrait interpréter le changement de ligne des cellules qui sont modifiées. Mais, on ne peux s'y fier, un Enter est si vite arrivé.
  • On peut stocker les lignes ayant subies une modification, et sur un autre évènement (changement de feuille, fermeture du classeur, etc...) déclencher les modifications du/des classeur(s). Ou avec simplement un bouton.
Mais choisir ce qu'on veut faire dépasse ce que les dépanneurs peuvent faire. Seul un utilisateur habituel des fichiers peut décider.

A+

Bonjour Misterno, Gorfael et vous autres

Après réflexion et quelques recherches et je voudrai savoir s'il est possible d'avoir une macro qui me fasse ceci : je me disais qu'il existait peut-être un moyen d'afficher une valeur (0 ou 1) dans une colonne à la fin de mon tableau de ma liste clients ou la valeur 1 apparaitrait pour chaque modification de ligne et qu'ainsi la macro mettrait à jour uniquement les lignes où la case serait remplie avec un 1.

Je ne sais pas si c'est très clair ? N'hésitez pas à me demander des éclaircissements.

Misterno : Comment puis-je optimiser cette macro ?

Merci de votre aide

Salut DerJul et le forum

C'est plus dur de définir ce qu'on veut réellement que de le coder

Private Sub Worksheet_Change(ByVal Target As Range)
'Déclaration =====================================
Dim Cel As Range, Plage As Range, x
'Validité ========================================
Set Plage = Intersect(Target, Range([A2], Range("Y" & Cells(Rows.Count, "A").End(xlUp).Row)))
If Plage Is Nothing Then Exit Sub
'Traitement =====================================
For Each Cel In Plage
    Cells(Cel.Row, "Z") = 1
Next Cel
End Sub

Si on édite une cellule de la plage A2 à (Y et dernière ligne non vide en A), mettre 1 dans la colonne Z

À mettre dans le module de la feuille concernée. Dans ce que tu nous a donné, dans le module lié à Feuil1 du fichier liste clients essai internet 3.xlsm (si j'ai bien compris)

Petite remarque : sur cette feuille, les lignes sont séparées en deux couleurs clair pour les paires et foncées pour les impaires. Je ne te souhaites pas la suppression d'un client

Il existe des possibilités avec des MFC qui maintiennent la différence de couleurs des lignes. par exemple : =IMPAIR(LIGNE())=LIGNE()

A+

Bonjour,

En déplaçant mon tableau de la liste clients de 2 lignes vers le haut et avec ce code que l'on m'a donné, la colonnes Y prends la valeur 0 à l'ouverture du fichier et 1 à chaque modification de ligne, le but étant de mettre à jour les lignes avec 1 en colonne Y.

Je n'arrive pas à écrire quelque chose (où alors je ne sais pas où le placer dans les feuilles/workbook etc..) qui me fasse "si 1 appliquer le programme i" , le programme i étant celui mettant à jour les fichiers liés.

Voici le code dans ThisWorkbook :

Option Explicit

Private Sub Workbook_Open()
Dim w1 As Worksheet, Rw&, Cl%
    Set w1 = Worksheets("Feuil1")
    Rw = w1.Cells(Rows.Count, 1).End(xlUp).Row
    Cl = w1.Cells(1, Columns.Count).End(xlToLeft).Column
    w1.Range(w1.Cells(2, Cl), w1.Cells(Rw, Cl)) = 0
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Dim w1 As Worksheet, Rw&, Cl%, i&
    Set w1 = Worksheets("Feuil1")
    Rw = w1.Cells(Rows.Count, 1).End(xlUp).Row
    Cl = w1.Cells(1, Columns.Count).End(xlToLeft).Column
    For i = 2 To Rw
        If w1.Cells(i, Cl) = 1 Then Call test(i&)
    Next i
End Sub

Et le code dans Feuil1 :

Option Explicit

Sub test(i&)
Dim Sh1 As Worksheet, Sh2 As Worksheet, Wb1 As Workbook, Wb2 As Workbook, Ch1$, Ch2$, j%, b%
    'chemin vers le doossier client à adapter
    Ch1 = "C:\Users\DerJul\Desktop\Stage L3\internet\clients\mission comptable\"
    'nom complet classeur matrice à adapter
    Ch2 = "C:\Users\DerJul\Desktop\Stage L3\internet\Matrice prévisions clients internet.xls"
    'déclaration classeur et feuille données client
    Set Wb1 = ThisWorkbook
    Set Sh1 = Wb1.Worksheets("Feuil1")
    'pour chaque ligne de la feuille données client
            'si le classeur portant le nom du client n'existe pas à l'endroit spécifié
        If Dir(Ch1 & Sh1.Cells(i, 1) & ".xlsm") <> "" = False Then
            Workbooks.Open Ch2 'ouvrir le classeur matrice
            Set Wb2 = Workbooks("Matrice prévisions clients internet.xls")
            Set Sh2 = Wb2.Worksheets("prévisions en cours")
            'remplir les informations dans le classeur matrice
            Sh2.Cells(2, 2) = Sh1.Cells(i, 1)
            Sh2.Cells(3, 2) = Sh1.Cells(i, 3)
            Sh2.Cells(5, 2) = Sh1.Cells(i, 24)
            Sh2.Cells(6, 3) = Sh1.Cells(i, 7)
            'sauvegarder le classeur matrice sous le nom du client
            Wb2.SaveAs Ch1 & Sh1.Cells(i, 1) & ".xlsm", FileFormat:=52
            'pour xls ActiveWorkbook.SaveAs Ch1 & w.Cells(i, 1) & ".xls", FileFormat:=56
            'pour xlsx : ActiveWorkbook.SaveAs Ch1 & w.Cells(i, 1) & ".xlsx", FileFormat:=51
        Else 'sinon
            Workbooks.Open Ch1 & Sh1.Cells(i, 1) & ".xlsm" 'ouvrir le classeur client
            Set Wb2 = Workbooks(Sh1.Cells(i, 1) & ".xlsm")
            Set Sh2 = Wb2.Worksheets("prévisions en cours")
            'vérifier les infos et actualiser si nécessaire
            If Sh2.Cells(2, 2) <> Sh1.Cells(i, 1) Then
                Sh2.Cells(2, 2) = Sh1.Cells(i, 1)
                b = True
            End If
            If Sh2.Cells(3, 2) <> Sh1.Cells(i, 3) Then
                Sh2.Cells(3, 2) = Sh1.Cells(i, 3)
                b = True
            End If
            If Sh2.Cells(5, 2) <> Sh1.Cells(i, 24) Then
                Sh2.Cells(5, 2) = Sh1.Cells(i, 24)
                b = True
            End If
            If Sh2.Cells(6, 3) <> Sh1.Cells(i, 7) Then
                Sh2.Cells(6, 3) = Sh1.Cells(i, 7)
                b = True
            End If
            'sauvegarder si au moins une modif
            If b Then Wb2.Save
        End If
        'fermer le classeur créé ou modifié
        Wb2.Close
    End Sub
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim Cl%, c As Range
    Cl = Cells(1, Columns.Count).End(xlToLeft).Column
    For Each c In Target
        If c.Row > 1 And c.Column < Cl And Cells(c.Row, 1) <> "" Then
            Cells(c.Row, Cl) = 1
        End If
    Next c
End Sub

Le 0 et le 1 si modification fonctionnent mais pas le :

    For i = 2 To Rw
        If w1.Cells(i, Cl) = 1 Then Call test(i&)
    Next i
End Sub

Dans ThisWorkbook.

Comment puis-je faire ?

-- 04 Juil 2011, 14:37 --

Finalement j'ai mis le code de test (i) dans un module standard et changé (i&) en (i) pour le call test et ça fonctionne

Merci

si c'est résolu

Rechercher des sujets similaires à "execution macro automatique changement valeur"