Macro - Verrouillage de cellules - VB/VBA/VBS - Programmation
Marsh Posté le 17-06-2006 à 00:16:16
En effet, ce n'est pas trés clair et incomplet.
Ton tableau est-il fixe ou à dimension variable ?
Il faut mieux définir ton projet
A+
Marsh Posté le 17-06-2006 à 18:19:50
ok... lol
Bon je vais essayer d'etre plus claire en reprenant depuis le début.
Mon role est d'optimiser l'activité des commerciaux dans l'entreprise. Pour cela, je fais un suivi de leur activité via les ordres de mission, qu'ils remplissent avant chaque visite aux clients. Cet ordre de mission est sous forme informatique (excel) et j'aimerai qu'à chaque fois que cet OM est rempli, le tableau associé se mette à jour. Seulement, j'ai fait plusieurs essais et à chaque fois que je mets à jour le tableau, ce sont toutes les lignes qui se mettent à jour, et non pas seulement la dernière.
En bref, j'aimerais savoir s'il y a un moyen,sous forme de macro, de verrouiller une cellule, une fois qu'elle est remplie, afin que son contenu ne soit plus modifiable.
Suis-je plus claire ??
Merci !!
Marsh Posté le 18-06-2006 à 00:03:40
Bonsoir,
Je pense qu'il faut protéger les lignes en question. Je ne pourrais pas te dire comment le faire en VBA mais en passant par l'enregistreur, tu pourras peut-être y arriver.
Voici la procédure:
Tu sélectionnes toute ta feuille en clliquant sur la 1ère cellule (au-dessus de la 1ère ligne, à gauche de la 1ère colonne).
Ensuite: Format/Cellule/Protection/Décocher Case Verrouillée
Sélectionner les lignes à protéger
Format/Cellule/Protection/Cocher Case Verrouillée
Outils/Protection/Protéger la feuille
Saisir mot de passe
Confirmer mot de passe
Attention AU MOT DE PASSE!!!
Bon courage
Marsh Posté le 18-06-2006 à 12:45:28
Salut,
je n'ai pas testé, mais si tu tentes d'écrire sur des cellules protégées, tu risque d'avoir des messages d'erreur !
Ton problème vient de ce que tu colles dans ta cellule un "lien" vers ton fichier OM1:
Citation : ActiveCell.FormulaR1C1 = "=([OM1.xls]OM!R10C3)" |
alors forcément, si les valeurs originales changent, elles vont aussi changer dans ta deuxième feuille !
Si tu veux que cela ne change plus, il faut que tu colles la valeur "en dur":
Citation : ActiveCell.FormulaR1C1 = workbooks("OM1.xls" ).Worksheets("OM" ).cells(2,1) |
(en changeant cells(2,1) par les coordonnées des cellules que tu veux copier, bien sûr !)
kenavo,
Jean-Marc
Marsh Posté le 18-06-2006 à 14:46:38
Bonjour,
Effectivement, il y aura de messages d'erreur. J'ai omis de le préciser. Si des cellules sont protégées, on ne peut les modifier. On en est averti.
Marsh Posté le 18-06-2006 à 19:51:28
bonsoir,
Formules ou "en dur", s'il met toutes les lignes dans sa macro avec des offset, il faut passer à chaque fois par toutes les cellules. Dans les deux cas, il se tape toute la colonne à copier.
Il faut absolument passer par un comptage de lignes et ne rajouter que les lignes nouvelles.
Après ça, Formules "en dur", tout dépend si les données du classeur source sont susceptibles de changer ou pas...
A+
Marsh Posté le 19-06-2006 à 23:03:15
Je pense qu'avant de se poser la question comment verrouiller une cellule, qu'il faut d'abord définir son projet et savoir quelles fonctions d'Excel utiliser et pour atteindre quel objectif.
Par exemple :
hypothèse 1 --> 1 OM = une ligne par commercial et tous les OM de tous les commerciaux dans une même feuille Excel !
hypothèse 2 --> 1 OM = une ligne par commercial dans une feuille nominative (pour chaque commercial) dans le même classeur !
hypothèse 3 --> chaque commercial a son propre classeur Excel !
D'où la question : si je dois mettre à jour un tableau récapitulatif en ne reprenant que la dernière ligne renseignée par le commercial cela implique 2 choses :
il faut pouvoir sélectionner cette ligne (recherche de la dernière ligne non vide hypothèse 2 et 3 ou créer une boucle qui trouve la dernière ligne de ce commercial hypothèse 1 à condition de mettre à jour un indicateur lors de la sélection et avant le transfert des informations vers le tableau récapitulatif.
Je ne pense pas qu'un lien soit la meilleure solution. de plus en faisant un déplacement par ActiveCell.Offset(x,x) pour y incrire une formule ne donne aucun choix de blocage. Je suis d'accord sur la notion de copier / coller info
A méditer
A+
Marsh Posté le 20-06-2006 à 00:39:53
Pour ce que j'en ai compris:
- Le code présenté (et incertain car fait par une débutante) semble être du code généré par l'enregistreur de macro et qui a été épuré et transformé.
- Le nombre de classeur OM importe peut, car je comprends que ce sont tjs les même cellules (en colonnes) d'un classeur "OM" qui doivent être copiées-collées, en ligne, dans le nouveau classeur.
- Puisque ce sont des copiés-collés avec liaisons, c'est normal que lorsque l'ordre de mission du classeur "OM" change, les cellules changent également dans le nouveau classeur.
C'est pourquoi, je proposais de coller les valeurs et non pas les liens. Maintenant, la façon de le faire est multiple, en fonction de la connaissance de la personne en VBA (débutante): recherche de la dernière ligne du nouveau classeur, itération pour remplir les cellules, avec saut de rangé n°5 etc.
Mais Moonliz ne s'est pas remanifestée, peut être a t-elle résolue son pb ?
kenavo,
Jean-Marc
Marsh Posté le 22-06-2006 à 10:22:37
Non, désolée, mais je n'ai plus accès à internet de chez moi, j'ai donc dû attendre d'arriver au boulot pour répondre...
Merci pour vos réponses, mais non, je n'ai toujours pas résolu mon problème. Le fait de coller les valeurs ne m'arrange pas, car ce sont des valeurs qui seront variables en permanence. Donc si je fais une macro en indiquant les valeurs à chaque fois, autant que je passe par la saisie non? (enfin, à moins que je n'ai pas tout à fait compris !!!).
Ce que j'avais prévu, mais qui ne semble pas réalisable d'après vos réponses, c'est d'avoir une seule feuille pour l'ordre de mission, qui sera modifiée en permanence (en effet, le test n'est fait que sur une dizaine de personnes, mais pourrait par la suite en toucher plusieurs centaines) avec un seul tableau récapitulatif.
Pensez-vous que j'ai une chance de réussir, ou vaut-il mieux que je commence à réfléchir à un autre moyen ???
En tous cas, merci pour vos réponses...
Laura
Marsh Posté le 22-06-2006 à 18:17:10
Salut,
je trouve que ta demande n'est pas très claire... es-tu d'accord avec mon message écrit juste au dessus du tiens ?
Je récapitule:
- tu as 1 classeur type nommé "OM1" qui sert à plusieurs personne pour remplir les ordres de mission (chaque personne à son classeur OM ou bien tout le monde utilise le même classeur, à la manière d'un formulaire ?).
- sur ce classeur (OM1), il y a quelques cellules à remplir:
-> ces cellules sont toujours les même
-> quand une deuxième personne rempli l'ordre de mission, les valeurs précédentes des cellules sont effacées
-> ce sont ces cellules que tu veux récupérer pour les mettre ligne par ligne dans un deuxième classeur, afin d'en faire un historique.
si c'est le cas, c'est parfaitement possible avec VBA, pas besoin de taper les valeurs à chaque fois, VBA le fait pour toi
JM
Marsh Posté le 23-06-2006 à 00:58:28
Bonjour,
Pour avoir de l'aide, il faut vraiment commencer par le début. Cela signifie que nous devons comprendre ton problème.
Explique STP comment fonctionne l'OM (ou les OM).
1 classeur, plusieurs classeurs, 1 feuille, plusieurs feuilles, ton tableau est-il sur le même classeur que ton ou tes OM ?
Que signifie "car ce sont des valeurs qui seront variables en permanence" ? probablement sur la feuille OM !
Est-ce que ça signifie nouvelles données au même endroit ex (D3) ou même colonne mais pas la même cellule parce que ajoute de ligne ? elles sont variables par rapport à quels critères ?
et "toutes les lignes se mettent à jour à chaque modification du fichier lié" --> que veut dire toutes les lignes ?
et "je fais un suivi de leur activité via les ordres de mission" --> comment fais-tu le suivi dans ton tableau récapitulatif ?
1 ligne fixe par Cial ou certaines cellules sont mises à jour ? ou création de ligne à chaque mise à jour ?
En fait, explique nous avec plus de détails comment est structuré ton ou tes OM ainsi que ton tableau récapitulatif.
A+
Marsh Posté le 23-06-2006 à 09:29:22
foot49 a écrit : |
ALors l'Olympique de Marseille évolue en ligue 1, championne d'europe en ....
je sors
Marsh Posté le 23-06-2006 à 10:53:17
lol
Donc je vais essayer d'être plus claire (merci de m'orienter avec les questions !!!)...
Tous les commerciaux utiliseront le même classeur OM (effectivement en tant que formulaire) composé d'une seule et unique feuille, et ce seront toujours les mêmes cellules qui seront modifiées, donc les cellules précédentes sont effacées à chaque mise à jour.
Ce que je cherche à faire dans le tableau récapitulatif est en effet un historique, avec création d'une nouvelle ligne lors de chaque mise à jour. Le tableau reprend tous les champs de l'OM.
Le suivi que je veux faire se fera à partir du tableau "historique", qui lui sera lié avec d'autres fichiers (mais ça c'est bon !!!).
Je pense avoir répondu à toutes les questions...
Si besoin est, je peux vous faire parvenir les 2 fichiers.
Merci........
Laura
Marsh Posté le 23-06-2006 à 11:11:11
pour la gestion d'un historique, tu peux très bien passer d'abord par un formulaire, où ton commercial mets les valeurs qu'il souhaite ajouter, tu crées la fonction qui te mets toutes ces valeurs dans les bonnes cases (si elles sont fixes) par l'appui sur un bouton, et tu ajoutes les mêmes valeurs sur un page annexe (nommée pkoi po historique) où tu ajoutes l'ensebmle des infos en bas de colonne.
par la suite, ce fichier historique, tu en fais ce que tu veux.
Marsh Posté le 23-06-2006 à 19:45:14
C'est bien ce que je pensais ! la solution de jpcheck est une possibilité: lancer un formulaire pour remplir ensuite une feuille historique.
Ou alors, plusieurs classeurs OM qui mettent à jour un classeur Historique.
Ou alors, une petite base Access, à mon avis la plus adaptée, mais d'usage moins souple pour créer des graphiques ou statistique...
Sans indiscrétion, ton classeur historique te servira à quoi ?
Je te donne mon mail par MP, si tu veux m'envoyer tes fichiers.
kenavo,
JM
Marsh Posté le 27-06-2006 à 02:54:51
Me voici de retour.
Je te propose 2 solutions la première assez complexe pour quelqu'un qui débute et la seconde très simple.
Solution 1 : il s'agit dans un classeur de définir une feuille qui te serviras de base de données dans laquelle tu ajoutes le dernier ordre de mission saisi à l'aide d'un userform ( à créer dans l'éditeur de VBA).
L'utilisation d'un userform (formulaire) présente de nombreux avantages. Tu peux y mettre des textbox (zones de saisie texte). De plus, VBA permet de faire le contrôle de saisi, par exemple : vérifier avant validation que le textbox est non vide ou numérique etc ..
il y a aussi les Boutons option, les cases à cocher ou les listes déroulantes qui oblige l'utilisateur à choisir parmi ce qui est proposé. Ou encore le Calendar qui a l'avantage de standardiser la saisie de date. Enfin, tu peux (par ex) mettre un Bouton de commande "Valider" pour déclencher la mise à jour de la BD. Un Bouton de commande "Annuler" pour mettre à blanc les zones de saisies sans pour autant quitter le formulaire et sans mise à jour de la BD. Un Bouton de commande "Quitter" pour fermer le formulaire et le classeur avec une sauvegarde.
VBA permet aussi de ne donner accès qu'au formulaire, empêchant les commerciaux d'intervenir sur la feuille BD qui serait soit cachée et ou protégée, avec en prime disparition des barres d'outils et verrouillage de l'accès à la fermeture de la fenêtre Excel.
Solution 2 : Dans un classeur tu nommes la première feuille "Ordre de Mission" elle servira de formulaire et la deuxième "Base" pour l'historique.
Il est important que les lignes de titres des 2 feuilles soient structurées de façon identique. Je m'explique :
Si par exemple l'OM comporte les zones A1 = Nom, B1 = Prémon, ...., G1 = Date
il faut que la ligne de titres de la BD soit ---> A1 = Nom, B1 = Prémon, ...., G1 = Date
Sur la feuille OM les cellules A2 à G2 serviront à la saisie des données.
Une astuce ---> tu nommes "OrdreMission" les cellules (A2:G2), elles seront déprotégées et la feuille.protégée.
Tu peux aussi, utiliser la fonction Données / Validation pour établir des contrôles de saisi.
Passons à la feuille BD. En dessous de la ligne de titre (donc A2:G2, tu colores ces cellules, c'est un repère visuel de fin d'enregistrements. Ensuite, tu nommes la cellule A2 "Fin" ---> pour l'utilité voir ci-sessous.
Passons à l'enregistrement de la macro.
1) faire Edition / Atteindre "OrdreMission" + Copier
2) faire Edition / Atteindre "Fin" + Insertion / Cellules / Décaler vers le bas (ajout d'un OM dans la BD)
3) Edition / Atteindre "OrdreMission" + Del (mise à blanc des cellules de l'OM pour une nouvelle saisie)
Bien entendu, il faut affecter la macro à un bouton, un clipart, une zone de texte etc..Ce bouton sera sur la feuille OM. Un bouton "Quitter peut-être ajouté, il aurait pour fonction de fermer et de sauvegarder le classeur
(voir les fonctions ActiveWorkbook.Save et ActiveWorkbook.Close)
Ou alors prévoir la sauvegarde du classeur lorsque le commercial Click sur le bouton de la macro (prévoir en dernière ligne VBA ActiveWorkbook.Save)
Ensuite, tu peux y mettre un filtre auto, etc..
A+
Marsh Posté le 12-07-2006 à 15:05:36
Bonjour à tous !!
Désolée pour ce retour tardif, mais je voulais vous remercier pour votre aide. J'ai en effet trouvé une solution à mon problème, grâce à vos conseils, et ça a l'air de fonctionner!!
Voici la macro (à titre indicatif) :
Sub Test()
ActiveSheet.Unprotect
ActiveCell.FormulaR1C1 = Worksheets("OM" ).Cells(4, 1)
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = Worksheets("OM" ).Cells(4, 4)
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = Worksheets("OM" ).Cells(6, 3)
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = Worksheets("OM" ).Cells(7, 3)
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = Worksheets("OM" ).Cells(8, 3)
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = Worksheets("OM" ).Cells(9, 3)
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = Worksheets("OM" ).Cells(10, 3)
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
End Sub
Par contre, juste une petite question (promis cette fois c'est la dernière) : est-il possible de faire en sorte que la macro s'exécute systématiquement à chaque enregistrement du classeur, afin que la personne qui travaillait sur le classeur n'ait pas à activer la macro elle-même?? (il me faut en effet simplifier la tâche de mes collègues si je veux que ce système d'historique fonctionne!!)
En tous cas merci pour tout...
Laura.
Marsh Posté le 12-07-2006 à 15:08:07
L'objet workbook comporte un événement BeforeSave; ça peut te convenir.
Marsh Posté le 12-07-2006 à 15:09:13
tu peux le faire lors de l'ouverture, en mode automatique, regarde ton workbook, une fonction toute faite existe, tu y inséres ton code et le tour sera joué
Marsh Posté le 12-07-2006 à 15:24:26
Euh.....
Excusez mon inculture mais ça se trouve où exactement??? :-s
Marsh Posté le 12-07-2006 à 15:34:31
dans visual basic editor, menu déroulant à gauche et à droite, ac t'ajoutera la fonction dans ton code...
Marsh Posté le 12-07-2006 à 17:25:34
J'ai trouvé cette fonction mais je ne parviens pas à l'insérer dans mon code.... J'ai dû rater quelque chose....
Marsh Posté le 12-07-2006 à 17:33:44
Le WorkBook_BeforeSave est une fonction déclenchée automatiquement par l'événement d'enregistrement de ton classeur.
Donc si tu mets du code VBA dedans il va s'exécuter chaque fois que tu vas enregistrer ton classeur.
Dans ton cas
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) |
J'espère t'avoir éclairer
Marsh Posté le 12-07-2006 à 18:09:44
Effectivement cette fois-ci il me l'accepte, mais il faut tout de même que j'active la macro systématiquement.
Mais faut-il que je fasse une macro à part pour celle-ci ou bien je l'incruste dans ma macro test??
Marsh Posté le 13-07-2006 à 08:06:17
A la place de "Test" tu mets le nom de ta macro dans "Workbook_BeforeSave"
Marsh Posté le 13-07-2006 à 16:25:21
Ok c'est bon j'ai compris!!! C'est un problème de rattachement que j'avais, je ne l'avais pas enregistrée dans "this workbook" mais dans la feuille directement, donc forcément.....
C'est bon j'ai tout ce qu'il me fallait, ca fonctionne nickel !
En tous cas merci à tous pour votre aide !!
Laura.
Marsh Posté le 15-06-2006 à 20:03:18
Bonjour!!
J'ai un petit souci avec une macro.
Il s'agit d'un tableau qui se met à jour automatiquement par rapport à un autre fichier. Seulement toutes les lignes se mettent à jour à chaque modification du fichier lié. Est-il possible de verrouiller les cellules remplies précédemment, de manière à ce que seule la dernière ligne se mette à jour? Je ne sais pas si je suis très claire, mais suis à disposition pour d'autres précisions.
Je joins mon début de macro, si ça peut aider... (je ne sais même pas si elle est correcte, je débute!! )
Sub test()
ActiveCell.FormulaR1C1 = "=([OM1.xls]OM!R4C1)"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=([OM1.xls]OM!R6C3)"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=([OM1.xls]OM!R7C3)"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=([OM1.xls]OM!R8C3)"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=([OM1.xls]OM!R9C3)"
ActiveCell.Offset(0, 1).Select
ActiveCell.FormulaR1C1 = "=([OM1.xls]OM!R10C3)"
ActiveCell.Offset(1, -5).Select
End Sub
Merci à tous de votre aide...
---------------
Depuis que tu es montée là-haut, les anges n'ont jamais été si beaux...