Demande précision sur Target.offset

dss

XLDnaute Occasionnel
Bonsoir le forum,

J'ai le code suivant :

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 11 And Target.Row Then
Target.Offset(0, -2).ClearContents (Message debogueur feuille protégée).Effectivement les lignes au-dessus de la ligne concernée (target.row) sont protégées une fois validées.


J'ai absolument besoin de protéger chaque ligne qui a été validée : Au niveau de Target.offset, y a t il possibilité de spécifier que le (0, -2) s'applique uniquement sur la ligne concernée (target.row) qui elle n'est pas encore validée et protégée par "Protect".
 

myDearFriend!

XLDnaute Barbatruc
Re : Demande précision sur Target.offset

Bonsoir dss,

Target.Offset(0, -2) ne cible pas les lignes précédant la cellule "Target" mais uniquement la cellule située à 2 cellules sur la gauche de ta sélection (c'est là ton problème de protection pas au dessus).

La propriété Offset(NbreLignes, NbreColonnes) te renvoie une cellule décalée par rapport à la cellule de référence (Target). NbreLignes et NbreColonnes peuvent être positif ou négatif selon que tu souhaites aller vers la droite et en bas (pour le positif) ou vers la gauche et en haut (pour le négatif).

Cordialement,
 

dss

XLDnaute Occasionnel
Re : Demande précision sur Target.offset

Bonsoir Didier,

Merci de ton aide

Tu confirmes ce que je pensais et je ne comprends pas mon erreur.J'ai un programme articulée autour de 2 procédures : Worksheet_Change et Worksheet_SelectionChange

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Si je retire les lignes ci-dessous, mon programme fonctionne normalement alors que dans le cas inverse débogage avec erreur sur la protection et pire car les lignes précédemment validées et protégées deviennent après le bogue accessibles à la modification.

'Dim lig
'lig = Target.Row

'If Target.Column = 11 And Target.Row Then
'Target.Offset(0, -2).ClearContents
'Target.Offset(0, -1).ClearContents
'Else
'If Target.Column = 9 Then
'Target.Offset(0, 2).ClearContents
'Target.Offset(0, 3).ClearContents
'End If
'End If


Dim mot As String, motdepasse As String, a As String
mot = "x"
If Target.Column >= 1 And Target.Column <= 11 Or Target.Column > 12 Then Exit Sub
If Target.Column = 12 And ActiveCell.Offset(0, -1) = "Chauffeur" Then _
motdepasse = InputBox("Mot de passe,svp")
If motdepasse = mot Then
a = MsgBox("Valeurs autorisées OUI ou NON", vbYesNo, "Saisie de valeurs")
If a = vbYes Then ActiveCell.Value = "OUI"
If a = vbNo Then ActiveCell.Value = "NON"
Else
End If
Target.Offset(0, 1).Select
End Sub

Débutant en VBA, cela demeure un mystère pour ce qui me concerne.

A bientôt peut-être de te lire

Cordialement

dss
 

myDearFriend!

XLDnaute Barbatruc
Re : Demande précision sur Target.offset

Si tu joignais ton classeur épuré à l'essentiel (sans données confidentielles) et de moins de 50 Ko zippé, alors ce serait plus simple car je n'ai pas tout compris...

NB : pour ma part, je n'ouvre jamais les fichiers joints autrement qu'en pièce jointe à partir du forum (donc pour moi, pas de Cjoint.com etc...). Mais il peut y avoir d'autres intervenants pour t'aider aussi !

Cordialement,
 

dss

XLDnaute Occasionnel
Re : Demande précision sur Target.offset

Bonjour le forum,

Effectivement, tu as raison Didier : avec un fichier joint, les choses seront plus simples.
Je joins donc le fichier épuré et je précise qu'il est établi en désactivant les lignes de codes relatives à clearcomments dans la procédure Worksheet_SelectionChange sur les colonnes I,J,K,L et fonctionne correctement dans cette configuration.

Par contre, lorsque je réactive les mêmes lignes, j'ai des erreurs après plusieurs clics entre les colonnes I et K ("message feuille protégée" me renvoyant vers target.offset(0,-2) et les lignes enregistrées jusqu'alors protégées deviennent accessibles).

Je pense que j'ai mal agencé une partie du code mais je ne trouve pas mon erreur.

Merci par avance de votre aide, elle sera la bienvenue car je galère et galère pour aucun résultat.

A+

Cordialement,

dss
 

Pièces jointes

  • Transport.zip
    29.2 KB · Affichages: 99
  • Transport.zip
    29.2 KB · Affichages: 97
  • Transport.zip
    29.2 KB · Affichages: 104

myDearFriend!

XLDnaute Barbatruc
Re : Demande précision sur Target.offset

Bonjour dss,

Je me suis penché sur ton classeur et là... j'avoue que j'ai beaucoup de mal à comprendre le but exact des procédures en place et la démarche qu'il convient de faire pour les mettre en oeuvre... :confused:

Tu dis que ça fonctionne si on laisse les lignes relatives à Clearcomments commentées, mais même en faisant abstraction de ces lignes, je n'ai, pour ainsi dire, rien compris au fonctionnement de ton application (tu devrais quand même veiller à ordonner un peu ton code VBA parce que là...).

Je pense qu'il va falloir que tu expliques pas à pas comment tu remplies une ligne et ce qui est sensé se passer...

Par ailleurs, déjà je n'ai pas compris pourquoi dans la colonne L par exemple, il y a une liste de validation avec la seule valeur "chauffeur" alors que la valeur attendue est semble-t'il "Oui" ou "Non" (?).

Cordialement,
 

dss

XLDnaute Occasionnel
Re : Demande précision sur Target.offset

Bonsoir le forum,

Didier, je viens de prendre connaissance de ton message et je m'attèle à la tâche du mieux que je le peux...
Dès que j'ai terminé, je renverrai avec les explications nécessaires un nouveau fichier qui sera, je l'espère, plus compréhensible.

Quant au code VBA, je réclame de l'indulgence car je débute et j'essaie d'appliquer "au mieux" ce que je lis d'une part, et les bouts de code que vous avez eu l'amabilité de me transmettre sur ce forum, d'autre part.

A très bientôt

Cordialement

dss
 

dss

XLDnaute Occasionnel
Re : Demande précision sur Target.offset

Bonsoir Didier, bonsoir le forum,

Comme je l'indiquais dans mon précédent message, je viens de terminer le fichier qui tente d'expliquer pas à pas la démarche comme me le suggérait Didier (cf onglet explications).

Merci par avance de votre aide en m'expliquant la raison pour laquelle j'ai un "conflit" entre les procédures Worsheet_Change et Worsheet_SelectionChange : du moins, je pense que c'est la source du dysfonctionnement sans en être vraiment sûr en bon débutant que je suis.

Cordialement

A+

dss
 

Pièces jointes

  • Transport.zip
    31.6 KB · Affichages: 74
  • Transport.zip
    31.6 KB · Affichages: 79
  • Transport.zip
    31.6 KB · Affichages: 84

myDearFriend!

XLDnaute Barbatruc
Re : Demande précision sur Target.offset

Re dss,

Tu trouveras ci-joint une tentative de réponse à ton problème.

Je me suis permis de revoir une bonne partie de ton code et j'ai essayé de commenter au maximum les lignes d'instructions afin que tu puisses t'y retrouver un peu.

Quand j'écrivais tout à l'heure que tu devrais "ordonner un peu ton code VBA", je ne faisais pas allusion aux instructions utilisées ni même à la syntaxe, mais simplement à la présentation que tu lui accordes. Si tu es débutant ça me parait encore plus important ! Comment veux-tu t'y retrouver si tu ne structure pas un minimum tes procédures ?
Pour pouvoir t'aider, il m'a fallut un bon moment déjà pour réordonner tout ça afin d'y voir un peu plus clair... c'est une perte de temps que toi comme moi, nous pourrions nous passer...

Par ailleurs, tu verras un Nota de ma part dans le code concernant les choix que tu as fait et pour lesquels je ne suis pas très fan... à toi de voir s'il convient de revoir la procédure ou non.

Je n'ai évidemment pas tout testé, et je te laisse le soin de voir si tout tient debout !

Dernière chose : ton projet commence à devenir assez complexe aussi je te déconseille fortement d'envisager des cellules clignotantes comme tu le laisses entendre. Tu risques fort de frôler l'usine à gaz avec des gadgets de ce genre et ce serait dommage car globalement, je trouve le projet assez bien pensé...

Bon courage pour la suite,

Cordialement,
 

Pièces jointes

  • mDF Transport.zip
    29.1 KB · Affichages: 160

dss

XLDnaute Occasionnel
Re : Demande précision sur Target.offset

Bonsoir didier,

Franchement j'ai pris connaissance tout à l'heure du fichier que tu m'as envoyé et bien que ne comprenant forcément le détail de chaque instruction (pour l'instant seulement j'espère), j'en perçois je crois assez bien la portée générale pour me rendre compte de la maîtrise dont tu fais preuve dans l'écriture et surtout de la suite claire et logique que tu donnes à l'ordonnancement des différentes tâches.

Sincérement, je suis épaté! d'autant plus lorsque je compare avec la lourdeur de mon code initial... et le temps que j'ai pu y passer...
Ne dit-on pas que "rendre simple les choses compliquées relève du véritable talent!"

Je suis désolé de t'avoir fait perdre du temps par rapport à la structure de mon code mais le temps que j'ai pu y passer explique en partie cela car combien de fois j'ai du faire, aménager, défaire et refaire sur l'instant et encore, encore et encore... pour tester une solution qui marche tant et si bien que par moment je ne savais plus forcément où j'en étais...
Lorsque tu me parles de présentation du code, dois-je comprendre par là le saut de ligne, les end if par exemple qui ne sont pas décalées etc...
Les commentaires sans instructions qui suivent me permettaient de me repérer par rapport au couper coller que je pouvais faire de manière successive.

Par rapport à ton envoi, j'ai cru bon d'annuler la ligne suivante :

'If Target.Value = "NON" Then Target.ClearContents car je ne pouvais plus saisir la valeur "NON" en colonne H alors que celle-ci doit être saisie à OUI ou NON et que la valeur de la colonne M en dépend.
Merci de me dire si cela peut avoir une incidence que je n'aurais pas décelé?

Si tu as encore quelques minutes à me consacrer et sans vouloir abuser de ton temps tu m'orientes vers une autre solution à partir de la validation :
J'ai l'idée suite à ta remarque de renvoyer vers une ou plusieurs procédures les fonctions d'enregistrement, de tri et de sauvegarde :
l'idée te paraît-elle opportune et réalisable sur le plan technique,et si oui, le programme demeurerait-il plus robuste sur le long terme ?

Enfin, pourrais-tu m'expliquer l'origine du conflit entre Worsheet_Change et SelectionChange lorsque j'essayais d'effacer les cellules concernées entre les colonnes I,J,K,L ?
Je remarque également que dans SelectionChange Target.value = IIf(Msgbox
Que signifie le IIf ?

Je tiens à te signifier une fois encore mes très sincères remerciements pour l'aide importante que tu m'as apportée et la disponibilité dont tu as fait preuve.

A bientôt peut-être,

Cordialement

dss
 

myDearFriend!

XLDnaute Barbatruc
Re : Demande précision sur Target.offset

Bonsoir dss,

Pour le code :
Code:
    [COLOR=NAVY]Case[/COLOR] 8           [COLOR=GREEN]'colonne H[/COLOR]
        [COLOR=NAVY]If[/COLOR] Target.Value = "NON" [COLOR=NAVY]Then[/COLOR] Target.ClearContents
il s'agit visiblement d'une erreur de ma part (je n'ai pas pu tout tester). Il convient certainement de remplacer par :
Code:
    [COLOR=NAVY]Case[/COLOR] 8           [COLOR=GREEN]'colonne H[/COLOR]
        [COLOR=NAVY]If[/COLOR] Target.Value = "NON" [COLOR=NAVY]Then[/COLOR] Cells(Lig, 13).ClearContents
Son objectif (après correction) est d'effacer la cellule M... si la cellule H... est définie à "NON". La suppression de cette ligne de code n'a pas d'incidence sinon.

D'autre part, je pense que l'épuration des lignes vide, le tri et la sauvegarde devraient se trouver gérer à un autre endroit qu'une procédure évènementielle Change(). C'est trop sensible comme manipulation de données, je pense que tu devrais prévoir une routine qui pourrait se lancer à la demande (bouton, double clic quelque part, ....) ou à l'ouverture / fermeture du classeur par exemple.

Pour ton ancien conflit entre Worsheet_Change et SelectionChange, je n'ai pas pris le temps d'analyser avant modif à vrai dire... mais j'imagine qu'il s'agissait sans doute d'un effet d'évènements en cascade mal géré (d'ailleurs je te déconseille fortement l'utilisation de Application.EnableEvents qui reste assez dangereux si mal appliqué).

Concernant la fonction IIF(), tu devrais jeter un oeil sur l'aide VBA (mettre le curseur d'édition sur IIF et faire F1). C'est un peu comme une instruction If then... End If condensée. Ca se presente comme ça :

IIf(ExpressionAEvaluer, ValeurSiVrai, ValeurSiFaux)

Selon l'expression, l'une ou l'autre des valeurs sera retournée par cette fonction.

Cordialement,
 

dss

XLDnaute Occasionnel
Re : Demande précision sur Target.offset

Bonsoir didier,

J'ai profité de la soirée pour examiner et tenter de comprendre un peu plus dans le détail le code que tu m'as envoyé (je lis beaucoup en même temps pour essayer de me familiariser avec le détail de chacune des lignes mais crois-moi : y'a du boulot.

Une fois, cette étape avancée, je vais réfléchir comme tu me le conseilles à repenser la fin du programme sachant que j'ai absolument besoin de l'épuration, du tri et de l'enregistrement : pour ce dernier, as tu volontairement oté cette fonctionnalité?

J'ai fait un test rapide en créant une procédure non évenementielle mais là, je me suis heurté comme je le pensais à la déclaration de variable et à leur contenu, (lig=target.row ne pouvant se rapporter qu'à une procédure évenementielle si j'ai bien compris) ; d'autant que j' ai surtout beaucoup de mal à comprendre le rôle de"tabtemp" attaché à la notion de tableau temporaire et encours , cette notion de static et le rôle qu'elle joue.

Peux-tu me confirmer qu'il me faut bien déprotéger les cellules de A à O sauf G et protéger celles des colonnes P et Q : "bidouille que j'avais trouvé pour que la protection se fasse ligne par ligne et non pas à toute la feuille après que l'on ait enregistré une ligne".

Je te tiendrai au courant de l'avancée de mes travaux dès qu'il me semblera avoir trouvé au moins un début de solution pour reconsidérer la suite du programme car ta remarque est très importante dans la mesure ou j'ai besoin d'un "code robuste" car ce fichier sera utilisé par plusieurs utilisateurs dont beaucoup ne sont pas très familiarisés avec l'informatique et encore moins avec excel.

A bientot

Et encore une fois, mes sincères remerciements pour ton aide précieuse

Cordialement

dss
 

myDearFriend!

XLDnaute Barbatruc
Re : Demande précision sur Target.offset

Bonsoir dss,

C'est ma semaine de reprise au boulot, alors je ne vais pas pouvoir te consacrer tout le temps nécessaire ce soir à l'ensemble des explications que tu souhaites (ça fait beaucoup de questions d'un coup lol :)).

J'ai désactiver l'enregistrement uniquement pour mes tests (gain de temps). Cela dit, j'ai peur de m'être mal exprimé : ce n'est pas tant l'endroit où tu as placé les routines de tri, d'épuration ou d'enregistrement qui me fait t'alerter, mais plutôt le choix de l'évènement déclencheur de ces routines.
Un évènement Change(), au même titre qu'un évènement SelectionChange(), est un évènement qui intervient souvent dans le cadre d'une utilisation normale d'un classeur. Il doit donc être réservé à des traitements que je qualifierais de légers, donc sans trop de conséquence en terme d'utilisation de ressources machine notamment.
Cet événement Change() se déclenche à chaque cellule modifiée par l'utilisateur et je ne pense pas qu'un tel évènement soit propice à des traitements lourds tels que le tri, l'épuration ou l'enregistrement du classeur. Je te proposais donc d'envisager l'utilisation de l'évènement de fermeture du classeur par exemple ou l'utilisation d'un bouton pour déclenchement à la demande. Ce n'est évidemment pas une obligation, tu es seul maître à bord. C'est un conseil uniquement.

Pour le tableau variant TabTemp, c'est une vieille habitude chez moi. Il s'agit du transfert de l'ensemble des données utiles de ta feuille dans une variable tableau. Je me sers ensuite de cette variable tableau comme je me servirais du tableau de la feuille de calcul. Cet intermédiaire me permet de récupérer dans la suite du code les valeurs beaucoup plus rapidement que si je demandais à Excel d'aller lire telle ou telle cellule. Je ne vais pas pouvoir aller dans le détail cette fois, mais en gros, comme mon Tabtemp commence à la cellule A1 de la feuille, une fois chargé, si je souhaite obtenir la valeur de la cellule E3 par exemple, alors je demande la valeur TabTemp(3,5) qui correspond à la 3ème ligne/5ième colonne de mon tableau variant. Dans une boucle avec beaucoup de données, tu t'apercevras que cette façon de faire donne un résultat beaucoup plus rapide qu'une lecture dans la cellule elle-même.

Pour ta routine de protection de ligne, j'avoue que je n'ai pas trop analysé et l'ai laissée telle que tu l'avais définie.

Pour ton histoire de "lig=target.row ne pouvant se rapporter qu'à une procédure évenementielle", il s'agit d'un simple problème de portée de variable, ce qui n'est pas insurmontable... Tu peux par exemple transmettre les variables en argument à une procédure tierce... mais là, je n'aurais pas le temps de t'expliquer. En tout cas, pas ce soir et peut être pas dans ce fil mais dans un autre, sans doute un peu plus spécifique à ce genre de problème... On attaque là l'apprentissage VBA pur et plus vraiment le cas particulier de ton classeur.

Voilà, j'espère que ça pourra te dépanner un peu pour l'instant.

Cordialement,
 

dss

XLDnaute Occasionnel
Re : Demande précision sur Target.offset

Bonjour didier,

Je viens de prendre rapidement connaissance de ton message et te remercie de toutes ces explications.

Le + important pour l'instant, c'est de te souhaiter :

Bon courage et bonne reprise

Merci encore de ta disponibilité et de ton appui

A+

dss
 

Discussions similaires

Membres actuellement en ligne

Aucun membre en ligne actuellement.

Statistiques des forums

Discussions
312 305
Messages
2 087 084
Membres
103 459
dernier inscrit
Arnocal