Tél : 01 41 19 27 72 | Contact
L'ensemble de nos notes techniques sont dans une table Paradox, comme tout ce que vous voyez sur notre site. Ces notes sont classées par thème (notes générales, méthodologie, ObjectPal, ...) et sont dans un certain ordre à l'intérieur d'un thème donné. Cet ordre peut être modifié au fil du temps (on peut choisir l'ordre alphabétique, ou un ordre de difficulté, ou regrouper les sujets voisins, ...). Puisque nous disposons d'une application Paradox nous permettant la mise à jour de ces notes, il est intéressant de faire gérer cet ordre directement par l'utilisateur (ici le documentaliste qui gère les notes techniques) et de lui permettre de modifier celui-ci à son gré.
Si on veut présenter nos notes ordonnées par thème, il nous faut un index composé de l'identifiant du thème (nous avons une table des thèmes qui nous fournit le libellé et qui a également un ordre géré par l'utilisateur) et d'un champ Ordre (de type Number) pour classer les notes par thème.
Bien sûr nous pourrions prendre cet identifiant comme clé primaire. Ce serait une très mauvaise idée car chaque fois que nous modifierons l'ordre, il faudrait répercuter ce changement d'identifiant dans tous les liens pointant sur cet enregistrement. On préfèrera toujours une clé primaire non modifiable et si possible mono-champ.
On aura un identifiant primaire Id_NoteT de type entier (le format court suffira pendant quelques temps :-) et un index secondaire composé de Id_Theme et du champ Ordre (nous appelerons par exemple notre index IdTheme_Ordre ).
La fiche Paradox qui nous permet de gérer le sommaire de nos notes technqiues comprend un cadre de table présentant la liste des notes techniques ordonnées suivant l'index IdTheme_Ordre.
Une première solution consiste à afficher la zone Ordre et à laisser l'utilisateur modifier celui-ci pour déplacer l'enregistrement.
Cette solution n'est pas toujours satisfaisante car elle nécessite pour être facilement utilisable que l'ordre soit un nombre entier et que l'utilisateur prévoit des "trous" lorsqu'il effectue ses insertions, pour anticiper de nouveaux ajouts et des modifications.
La solution que nous présentons ci-après nécessite un peu de programmation mais permet de masquer complètement le champ Ordre à l'utilisateur.
Nous ajoutons à côté de notre cadre de table un groupe de 2 boutons correspondant respectivement à la remontée et à la descente de notre note d'un cran dans la liste. Nous appelons ces boutons respectivement BtUp et BtDown et le groupe GRP_UP_DOWN .
Il reste maintenant à gérer l'insertion à un endroit quelconque d'un nouvel enregistrement ainsi que le déplacement dans un sens ou dans l'autre d'un enregistrement.
Détection de l'insertion:
Dans la méthode action du cadre de table, nous insérons le code qui aura pour rôle de capter l'insertion et de déclencher le traitement adéquat:
SWITCH
CASE eventInfo.id() = DataUnlockRecord OR eventInfo.id() = DataPostRecord :
; .....
If Not GRP_UP_DOWN.ActionCreer_LO(eventInfo.id()) Then
DISABLEDEFAULT
eventInfo.setErrorCode(userError)
endif
CASE eventInfo.id() = DataInsertRecord :
; ......
If Not GRP_UP_DOWN.ActionCreer_LO(eventInfo.id()) Then
DISABLEDEFAULT
eventInfo.setErrorCode(userError)
endif
ENDSWITCH
Traitement de l'insertion:
La méthode ActionCreer_LO est localisée dans le groupe GRP_UP_DOWN et possède le code suivant (nous indiquons également les constantes et variables définies au niveau du groupe):
Const
TFNomST = "NoteT" ; nom de l'objet cadre de table
ChpNomST = "Ordre" ; nom du champ Ordre dans la table
endconst
Var
TFUI UIObject
TCUI Tcursor
OldNU, NU Number
EndVar
method ActionCreer_LO(Const ActionIdSI SmallInt) Logical
TFUI.attach(TFNomST)
TCUI.attach(TFUI)
switch
case ActionIdSI = DataInsertRecord :
gAutoAppendLO = TFUI.blankRecord
if not gAutoAppendLO then
NU = TCUI.(ChpNomST)
if not TCUI.priorRecord() then
OldNU = 0
else
OldNU = TCUI.(ChpNomST)
endif
NU = (NU+OldNU)/2
else
if TCUI.nRecords() = 0 then
NU = 1
else
TCUI.end()
NU = TCUI.(ChpNomST) + 1
endif
endif
case ActionIdSI = DataUnlockRecord and TFUI.inserting:
dmPut(TFUI.tableName, ChpNomST, NU)
endswitch
return true
endMethod
Traitement du bouton Up:
Le bouton BtUp permet de faire remonter la note dans la liste. Son code (méthode PushButton) est le suivant.
TFUI.attach(TFNomST)
If TFUI.blankRecord Then Return EndIf
If TFUI.locked Then
If Not TFUI.action(DataUnLockRecord) Then Return EndIf
EndIf
TCUI.attach(TFUI)
OldNU = TCUI.(ChpNomST)
If TCUI.atFirst() Then Return EndIf
TCUI.priorRecord()
NU = TCUI.(ChpNomST)
TCUI.(ChpNomST) = (OldNU + NU) /2
TCUI.unLockRecord()
TCUI.nextRecord()
TCUI.(ChpNomST) = NU
TCUI.unLockRecord()
TCUI.nextRecord()
TCUI.(ChpNomST) = OldNU
TCUI.unLockRecord()
TFUI.resync(TCUI)
TFUI.priorRecord()
Traitement du bouton Down:
La fonction est l'inverse de la précédente. La programmation est la suivante:
TFUI.attach(TFNomST)
If TFUI.blankRecord Then Return EndIf
If TFUI.locked Then
If Not TFUI.action(DataUnLockRecord) Then ReturnEndIf
EndIf
TCUI.attach(TFUI)
OldNU = TCUI.(ChpNomST)
If TCUI.atLast() Then Return EndIf
TCUI.nextRecord()
NU = TCUI.(ChpNomST)
TCUI.(ChpNomST) = (OldNU +NU)/2
TCUI.unLockRecord()
TCUI.priorRecord()
TCUI.(ChpNomST) = NU
TCUI.unLockRecord()
TCUI.priorRecord()
TCUI.(ChpNomST) = OldNU
TCUI.unLockRecord()
TFUI.resync(TCUI)
TFUI.nextRecord()
Le système peut être enrichi : par exemple en ajoutant d'autres boutons permettant de déplacer l'enregistrement par saut de n enregistrements ou de l'envoyer en début ou fin de liste. Les programmeurs intrépides peuvent également se lancer dans une programmation d'un drag and drop (attention cependant à la localisation du code) et dans un paramétrage complet du système.
N'hésitez pas à nous faire part de vos résultats !