Se connecter avec
S'enregistrer | Connectez-vous

problème dans une macro excel

Dernière réponse : dans Programmation

Bonsoir, je vais essayer d'expliquer le problème le plus clairement possible.
J'ai un classeur excel avec 4 feuilles pour la gestion des licenciés de mon association sportive.
Dans la première j'ai tous les noms des joueurs avec leur numéro de licence ainsi que les sports pratiqués.
Une première macro récupère tous les joueurs d'un sport et les copie dans la feuille correspondante, et
ceux-ci pour les 3 sports.
Maintenant je souhaite créer un classeur nommé "BB M + date.xls" pour donner au responsable de l'équipe.
De même pour HB M et F M.
Dans le code qui suit, seule le classeur avec les licenciés de basket masculin est protégé en totalité.
Les deux autres classeurs ne sont pas protégés et je ne voit pas où est le problème.
Je planche sur le code depuis toute l'après midi ( je suis débutant ....) et je ne voit pas le problème
qui est probablement minime.

Merci pour votre aide

philippe

  1. Sub sauve()
  2. Dim dossier As String
  3. dossier = ActiveWorkbook.Path
  4. Application.DisplayAlerts = False '' pour enlever les messages du type "Un fichier porte déjà ce nom" lors de la sauvegarde
  5.  
  6. '' basket ball masculin
  7. Sheets("BB M").Select
  8. Sheets("BB M").Copy
  9. ActiveWorkbook.SaveAs Filename:=dossier & "\BB M" & "-" & Year(Date) & Month(Date) & Day(Date) & ".xls", FileFormat:=xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, CreateBackup:=False
  10. Cells.Select
  11. Selection.Locked = True
  12. Selection.FormulaHidden = False
  13. ActiveSheet.Protect Password:="mdp", DrawingObjects:=True, Contents:=True, Scenarios:=True
  14. ActiveWorkbook.Protect Password:="mdp", Structure:=True, Windows:=False
  15.  
  16. ActiveWorkbook.Save
  17. ActiveWorkbook.Close
  18.  
  19. '' handball masculin
  20. Sheets("HB M").Select
  21. Sheets("HB M").Copy
  22. ActiveWorkbook.SaveAs Filename:=dossier & "\HB M" & "-" & Year(Date) & Month(Date) & Day(Date) & ".xls", FileFormat:=xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, CreateBackup:=False
  23. Cells.Select
  24. Selection.Locked = True
  25. Selection.FormulaHidden = False
  26. ActiveSheet.Protect Password:="mdp", DrawingObjects:=True, Contents:=True, Scenarios:=True
  27. ActiveWorkbook.Protect Password:="mdp", Structure:=True, Windows:=False
  28.  
  29. ActiveWorkbook.Save
  30. ActiveWorkbook.Close
  31.  
  32. '' volley ball masculin
  33. Sheets("VB M").Select
  34. Sheets("VB M").Copy
  35. ActiveWorkbook.SaveAs Filename:=dossier & "\VB M" & "-" & Year(Date) & Month(Date) & Day(Date) & ".xls", FileFormat:=xlNormal, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, CreateBackup:=False
  36. Cells.Select
  37. Selection.Locked = True
  38. Selection.FormulaHidden = False
  39. ActiveSheet.Protect Password:="mdp", DrawingObjects:=True, Contents:=True, Scenarios:=True
  40. ActiveWorkbook.Protect Password:="mdp", Structure:=True, Windows:=False
  41.  
  42. ActiveWorkbook.Save
  43. ActiveWorkbook.Close
  44.  
  45. Application.DisplayAlerts = True
  46. End Sub

Autres pages sur : probleme macro excel

Lassé par la pub ? Créez un compte
Expert Programmation

Ton code est véritablement horrible. (Code de débutant, quoi que je n'en suis pas si sûr ;)  )
Pourquoi faire tous ces Select ?
Comment être sûr de ce que l'on fait quand on accède à l'objet actif ?

Bon, je te propose de faire une fonction générique, puis de l'appliquer plusieurs fois :

  1. Sub Sauve_1(Nom As String)
  2. Dim master_wb As Workbook
  3. Dim new_wb As Workbook
  4.  
  5. Set master_wb = ActiveWorkbook
  6.  
  7. master_wb.Sheets(Nom).Copy
  8. Set new_wb = ActiveWorkbook
  9.  
  10. Application.DisplayAlerts = False
  11. new_wb.SaveAs Filename:=master_wb.Path & "\" & Nom & "-" & Year(Date) & Month(Date) & Day(Date) & ".xls"
  12. Application.DisplayAlerts = True
  13.  
  14. new_wb.Sheets(1).Cells.Locked = True
  15. new_wb.Sheets(1).Cells.FormulaHidden = False
  16. new_wb.Sheets(1).Protect Password:="mdp", DrawingObjects:=True
  17. new_wb.Protect Password:="mdp", Structure:=True, Windows:=False
  18.  
  19. new_wb.SaveAs ' <------ ERREUR !!!!
  20. new_wb.Close
  21.  
  22. Set new_wb = Nothing
  23. Set master_wb = Nothing
  24. End Sub


Pas de Select/Selection ni de Activate/ActiveTruc
Evidemment, ligne 8, je suis obligé de faire confiance à Excel... Beurk.
Pour les DisplayAlert, surtout à utiliser avec parcimonie. Et donc encadrer au plus près la fonction qui le nécessite.

  1. Sub Sauve_plusieurs()
  2. Sauve_1 "BB M"
  3. Sauve_1 "HB M"
  4. Sauve_1 "VB M"
  5. Sauve_1 "VB M"
  6. End Sub


Qu'en dis-tu ?

Disons que j'essaie d'utiliser les macros depuis quelques temps, mais il est vrai que je cherche rarement à simplifier et à minimiser le travail de la machine, du moment qu'elle a fait ce que j'attendais.... c'est un défaut.

Les select me servaient à mettre les cellules en mode verrouillé pour ensuite bloquer complétement leur accès, et que le destinataire ne puisse qu'imprimer ce que je lui envoie sans apporter aucune modification.

C'est vrai que ça fait déjà plus propre comme ça

La fonction générique m'aurait demandé beaucoup plus de réflexion, je dois avouer que la programmation n'est pas trop ma spécialité..... (ça se voit!)

Après plusieurs minutes de lecture, j'avais l'impression de comprendre ce que tu lui fais faire, mais après l'avoir testé sur mon fichier excel, aucun des fichiers créés n'est protégé. Et là, je vois vraiment pas ce qui ne va pas parce que j'étais convaincu par le code.


J'essai de le modifier, mais si tu peux encore m'aider.... merci d'avance

Philippe
Expert Programmation

Attention de ne pas te tromper de forum, ici on parle de programmeur à programmeur.
Dans ce monde, il faut TOUJOURS faire les choses PROPRES. Et ne jamais lésiner sur la REFLEXION.
Il faut aussi bien comprendre ce que l'on fait, ou quand on demande de l'aide, ce que l'on fait faire.
(Ce que tu as fais, j'en suis très content). L'erreur vient de moi, et seulement de moi.

Cela a échapper à ta relecture : ligne 19 de mon code, j'ai mis un SaveAs. Il faut faire un Save tout court.
Ben oui, ce n'est pas ton fichier protégé mais une copie non protégée qui est copiée par dessus !
(D'où le message d'avertissement qui aurait dû te mettre la puce à l'oreille)

Alors, comme ça, ça marche ?
Expert Programmation

Encore une chose, ta façon de nommer ton fichier est très moche.
Le 1 décembre (aujourd'hui ;)  ) et le 21 janvier sont 12 1 et 1 21, soit tout attaché, 121 pour les deux. Ajoute des zéros :

Aide directe et gratuite sans avoir à réfléchir pour me faire pardonner du SaveAs précédent :whistle:  :
  1. new_wb.SaveAs Filename:=master_wb.Path & "\" & Nom & "-" & Format(Now, "yyyymmdd") & ".xls"

J'essairai de faire les efforts nécessaire pour être admis sur ce forum!!

c'est malheureux, mais le SaveAs ne me choquait pas du tout...
j'ai modifié cette ligne de commande

par contre pour éviter les problèmes, j'ai enlevé la date du nom de fichier d'enregistrement.

Malheureusement, la protection n'a fonctionné que pour le premier classeur "BB M", ensuite les suivants ne sont pas protégés, et ça je comprends pas, parce qu'on définit des workbooks "temporaires" mais avant de quitter la procédure, on les déclare comme n'étant plus rien, donc ça devrait recommencer ensuite sans problème.

j'ai tenté de modifier la procédure Sauve_plusieurs en lui faisant:
  1. Sub Sauve_plusieurs()
  2. Sauve_1 "HB M"
  3. Sauve_1 "BB M"
  4. Sauve_1 "VB M"
  5. End Sub

pour qu'il sauvegarde d'abord la page handball avant la basket ball, mais cette fois, c'est pas la 1ère page qui est sauvegardé protégée mais la seconde, donc toujours "BB M"....
ne voyant pas ce que je peux faire, j'ai même essayé de déplacer les pages du classeur principal en mettant "HB M" à la place de "BB M", mais ça change rien....
et là, je sèche
Expert Programmation

Moi aussi, je sèche :/ 

Bon, j'ai revisité ton code et le mien.
Et je fais des choses plus propres :
  • Passage d'objet feuille, et non pas par nom de feuille, comme ça, on n'est pas tributaire du classeur.
  • Passage du chemin de sauvegarde.
  • Une seule sauvegarde !

    1. ' // Enregistre une feuille en lecture seule
    2. Sub Sauve_1(master_sh As Worksheet, path As String)
    3. Dim new_wb As Workbook
    4.  
    5. master_sh.Copy
    6. Set new_wb = ActiveWorkbook
    7.  
    8. new_wb.Sheets(1).Cells.Locked = True
    9. new_wb.Sheets(1).Protect Password:="mdp"
    10. new_wb.Protect Password:="mdp"
    11.  
    12. Application.DisplayAlerts = False
    13. new_wb.SaveAs Filename:=path & "\" & master_sh.Name & "-" & Format(Now, "yyyymmdd" ) & ".xls"
    14. Application.DisplayAlerts = True
    15.  
    16. new_wb.Close
    17.  
    18. Set new_wb = Nothing
    19. Set master_wb = Nothing
    20. End Sub


    Le nouveau Sauve_Plusieurs :
    1. Sub Sauve_Plusieurs()
    2. Dim Chemin As String
    3. Chemin = ActiveWorkbook.Path
    4.  
    5. Sauve_1 Worksheets("HB M"), Chemin
    6. Sauve_1 Worksheets("BB M"), Chemin
    7. Sauve_1 Worksheets("VB M"), Chemin
    8. End Sub

    j'étais une fois de plus convaincu par le code
    :pt1cable:  mais seul le fichier avec la feuille BB M est protégé...
    je rectifie, le "BB M" est protégé et les cellules sont inaccessibles
    les "HB M" et "VB M" sont protégés mais les cellules sont accessibles....

    par contre, ligne 3 tu définis new_wb comme un nouveau classeur de travail
    est-il sélectionné automatiquement avant de faire la copie ligne 5?

    apparemment c'est la ligne 8 qui ne fait rien pour 2 pages

    j'ai essayé en remplaçant les lignes

    1. new_wb.Sheets(1).Cells.Locked = True
    2. new_wb.Sheets(1).Protect Password:="mdp"

    par
    1. new_wb.Sheets(master_sh.name).Cells.Locked = True
    2. new_wb.Sheets(master_sh.name).Protect Password:="mdp"


    ben, ça fait pareil...
    Expert Programmation

    Ligne 3 : Définition d'une variable (en fait un pointeur)
    Ligne 5 : Copie de la feuille vers un nouveau classeur qui ne contient que cette feuille + Auto activation du nouveau classeur (relire l'aide de la fonction Copy).
    Ligne 6 : On affecte la variable new_wb à ce nouveau classeur. (La nature pointeur de la variable impose l'utilisation de Set.)
    Ligne 8 : Plutôt que Sheets(x) on devrait utiliser Worksheets(x) où x est le numéro ou le nom de la feuille.

    Nouveau code :
    1. ' // Enregistre une feuille en lecture seule
    2. Sub Sauve_1(master_sh As Worksheet, path As String)
    3. Dim new_wb As Workbook
    4.  
    5. master_sh.Copy
    6. Set new_wb = ActiveWorkbook
    7.  
    8. new_wb.WorkSheets(1).Name = master_sh.Name
    9. new_wb.WorkSheets(1).Cells.Locked = True
    10.  
    11. Stop
    12.  
    13. new_wb.WorkSheets(1).Protect Password:="mdp"
    14.  
    15. Stop
    16.  
    17. new_wb.Protect Password:="mdp"
    18.  
    19. Stop
    20.  
    21. Application.DisplayAlerts = False
    22. new_wb.SaveAs Filename:=path & "\" & master_sh.Name & "-" & Format(Now, "yyyymmdd" ) & ".xls"
    23. Application.DisplayAlerts = True
    24.  
    25. new_wb.Close
    26.  
    27. Set new_wb = Nothing
    28. Set master_wb = Nothing
    29. End Sub

    J'ai ajouté, ligne 8, le nommage de la feuille, juste pour faire "pluzoli" :) 

    Lignes 11, 15, 19, j'ai mis des Stops. Le déroulement de la procédure s'arrêtera à chaque fois, te permettant de vérifier l'état effectif de ton nouveau classeur, de sa feuille et de ses cellules, avant l'enregistrement.

    Pour lancer ou relancer le code, touche F5.
    Mais ça tu le sais si tu as lu ce topic.

    désolé de te saper le moral, mais ç'est identique:

    pour la page "HB M", il coche bien la propriété "verrouillé" des cellules,
    effectue la protection mais les propriétés cochées lors de la protection de la feuille ne doivent pas être correct vue que les cellules sont accessibles après mais que la feuille et le classeur sont bien protégé par le mdp

    pour la page "BB M", ça fonctionne sans souci

    pour la page "VB M", c'est comme pour "HB M"

    J'ai l'impression de comprendre le code, mais il ne fait pas ce que j'ai l'impression de lui demander....
    Expert Programmation

    :fou: 

    Bon alors, résumons, pour la feuille HB :

  • Avant sauvegarde (Au Stop de la ligne 19)
    La propriété Verrouillée (Format de cellule/Protection) est cochée pour toutes les cellules ;
    La feuille est protégée ;
    Le classeur est protégé.

  • Après sauvegarde
    La propriété Verrouillée (Format de cellule/Protection) est cochée pour toutes les cellules ;
    La feuille est protégée ;
    Le classeur est protégé.
    Mais on peut modifier le contenu des cellules.

    C'est bien ça ?

    J'ai "trouvé" une solution plus ou moins catholique...

    j'ai protégé manuellement les pages du classeur de départ, en décochant donner l'accès au cellules verrouillées, puis j'ai enlevé la protection. Je l'ai pour chaque, et ensuite en faisant tourner la macro, elles sont toutes protégées correctement.

    nota: dans les propriétés de protection je pense qu'il fallait décocher manuellement pour chaque feuille 'autoriser l'accès aux cellules verrouillées'. et la propriété est copiée dans chaque nouveau classeur

    désolé de t'avoir fait galéré pour presque rien
    Expert Programmation

    Bon, ben t'as trouvé tout seul.
    J'aurais voulu que tu me répondes oui, je t'aurais répondu :

    1. Sub ZonesLibres(Feuille As Worksheet)
    2. Dim ZoneLibre As AllowEditRange
    3. Dim Utilisateur As UserAccess
    4. Dim s As String
    5.  
    6. s = "Zones Libres" & vbCrLf
    7. s = s & "========" & vbCrLf
    8. s = s & Feuille.Protection.AllowEditRanges.Count & " zone(s) trouvée(s)." & vbCrLf
    9.  
    10. s = s & "--------------------------------" & vbCrLf
    11.  
    12. For Each ZoneLibre In Feuille.Protection.AllowEditRanges
    13. s = s & " • Zone """ & ZoneLibre.Title & """" & vbCrLf
    14. s = s & " Adresse: " & ZoneLibre.Range.Address(False, False) & vbCrLf
    15. s = s & " Utilisateur: "
    16. If ZoneLibre.Users.Count = 0 Then
    17. s = s & "(Aucune précision)"
    18. Else
    19. For Each Utilisateur In ZoneLibre.Users
    20. s = s & Utilisateur & ","
    21. Next
    22. s = Left(s, Len(s) - 1)
    23. End If
    24. s = s & vbCrLf
    25.  
    26. s = s & "--------------------------------" & vbCrLf
    27.  
    28. Next
    29.  
    30. MsgBox s, , "Zones libres"
    31. End Sub
    Expert Programmation

    Tadaaaaa !!!!!

    1. ' // Enregistre une feuille en lecture seule
    2. Sub Sauve_1(master_sh As Worksheet, path As String)
    3. Dim new_wb As Workbook
    4. Dim ZoneLibre As AllowEditRange
    5.  
    6. master_sh.Copy
    7. Set new_wb = ActiveWorkbook
    8.  
    9. For Each ZoneLibre In new_wb.WorkSheets(1).Protection.AllowEditRanges
    10. ZoneLibre.Delete
    11. Next
    12. new_wb.WorkSheets(1).Name = master_sh.Name
    13. new_wb.WorkSheets(1).Cells.Locked = True
    14. new_wb.WorkSheets(1).Protect Password:="mdp"
    15. new_wb.Protect Password:="mdp"
    16.  
    17. Application.DisplayAlerts = False
    18. new_wb.SaveAs Filename:=path & "\" & master_sh.Name & "-" & Format(Now, "yyyymmdd" ) & ".xls"
    19. Application.DisplayAlerts = True
    20.  
    21. new_wb.Close
    22.  
    23. Set new_wb = Nothing
    24. Set master_wb = Nothing
    25. End Sub
    Lassé par la pub ? Créez un compte