Matérialiser l'enregistrement courant dans un cadre de table Il est relativement commun d'avoir à saisir des données relatives à un enregistrement pointé dans un cadre de table, en dehors du cadre de table lui-même. Par exemple, les champ Mémo sont souvent déportés hors du cadre de table pour des raisons de lisibilité. Un modèle relationnel 1,n, représenté par deux cadres de tables, contraint l'utilisateur à sortir du cadre représentant l'enregistrement maître, pour saisir des informations dans la table enfant. Dans cette situation, on perd visuellement la position de l'enregistrement dont dépendent les données en cours de saisie ou de consultation. Paradox ne propose pas d'outils naturels permettant de remédier à cette gêne. Il est évidemment possible de sortir - ou de rappeler - l'identifiant de l'enregistrement maître hors du cadre de table.
Nous proposons deux autres solutions permettant de pointer visuellement l'enregistrement courant d'un cadre de table. La première solution est la plus performante en terme de rapidité d'exécution : elle est moins visuelle mais plus facile à mettre en place. La seconde solution est plus facilement paramétrable et permet d'agir sur chacun des objets inclus dans l'enregistrement (champs, boutons \'85).
La première solution consiste à déplacer un objet sur un bord du cadre, en lui assignant la même position verticale que l'enregistrement lui-même. C'est la proposition standard d'Access. Pour cela, il suffit de grouper l'objet et le cadre de table, d'ouvrir deux variables de type UIObject, sur l'objet à déplacer et sur l'objet enregistrement. Lors de l'arrivée sur le cadre de table, on récupère alors la position relative verticale et la taille de l'enregistrement pour les assigner à l'objet à déplacer.
Un cadre de table posé directement dans une fiche donne un nom particulier à chaque enregistrement du cadre de table. Pour fixer l'Uiobject enregistrement, il est donc nécessaire de renommer l'objet enregistrement.
Dans notre exemple, l'objet à déplacer est un bouton nommé " BOUTON ". L'objet enregistrement du cadre de table est renommé " ENREGISTREMENT ".
Dans l'objet groupe, plus petit conteneur de OBJET et ENREGISTREMENT, sont déclarés deux variables de types UIObject, BTUI pour le BOUTON et EnrUI pour l'ENREGISTREMENT. Elles sont pointées à l'ouverture de l'objet groupe: 
Method Open(var eventInfo Event) BTUI.attach(BOUTON) EnrUI.attach(ENREGISTREMENT) Endmethod

Une méthode BTLigne est crée dans le cadre de table : 
method BTligne() VAR BTPosPT, BTTaillePT, EnrPosPT, EnrTaillePT Point ENDVAR
BTPosPT = BTUI.position;Récupération de la position initiale du bouton BTTaillePT = BTUI.size;Récupération de la position initiale du bouton EnrPosPT = EnrUI.position;Récupération de la position de l'enregistrement EnrTaillePT = EnrUI.size;Récupération de la taille de l'enregistrement
BTPosPT = point(BTPosPT.x(), EnrPosPT.y());Assignation de la position
horizontale du bouton et verticale de l'enregistrement dans une variable
BTTaillePT = point(BTTaillePT.x(), EnrTaillePT.y());Assignation de la
largeur du bouton et de la hauteur de l'enregistrement dans une variable BTUI.position = BTPosPT;Le bouton prend sa nouvelle position verticale et garde sa position horizontale
BTUI.Size = BTTaillePT;Le bouton prend la même hauteur que l'enregistrement et garde sa largeur. Endmethod

Pour synchroniser la position du bouton et celle de l'enregistrement courant, il ne suffit plus que de déclencher la méthode Btligne sur les actions de mouvement du cadre de table : 
method action(var eventInfo ActionEvent) If eventInfo.id() = DataArriveRecord then btligne() endif EndMethod

Notre seconde proposition est un peu plus lourde à mettre en place, et également un peu moins efficace en terme de rapidité d'exécution. Ce dernier point ne sera cependant pas pris en compte lors du choix de la mise place de l'une ou l'autre solution, les temps de réponse étant dans les deux cas négligeables par rapport au temps de rafraîchissement d'un cadre de table.
Cette solution, beaucoup plus visuelle, permet en outre d'agir sur tous les objets contenus dans le cadre de table. Elle consiste à forcer un nom distinct à chaque ligne (objet " Enregistrement ") du cadre de table et à lui assigner des propriétés visuelles dans le cas d'un DataArriveRecord().
Toutes les variables sont définies dans l'objet Cadre de table : 
Var NumSI Smallint NomAR Array[] string OrigineST String RSI,
GSI, BSI smallint RgbLI
Longint Namest string ObjAR Array[] string debLO Logical endvar

Lors de l'ouverture de chaque enregistrement, on donne un nom distincts à tous les objets " Enregistrement " : 
method open(var eventInfo Event) ; Var ChampUI UIobject ST String endvar

Dans le cas du premier enregistrement, on récupère les objets dans un tableau et on ne change pas le nom de l'enregistrement : 
If not NumSI.isassigned() then OrigineST=Self.name NumSI=1 ChampUI.attach(self) ChampUI.enumObjectNames(ObjAR) For n from 2 to ObjAR.size() ObjAR[n].Match(ChampUI.fullname+"..",ST) ObjAR[n]=ST.substr(2,st.size()) If ObjAR[n].Match("#",ST) then ObjAR[n]=ST endif endfor debLO=False endif ; définition de noms définis pour chaque enregistrement et stockage de ces noms dans un tableau If NumSI<>1 then Self.name=self.name+strval(NumSI) getrgb(Self.Color,RSI,GSI,BSI) endif NomAR.grow(1) NomAR[NumSI] = Self.FullName NumSI=NumSI+1 EndMethod

La méthode action du cadre de table déclenche l'appel de la procédure de coloration s'il s'agit d'un déplacement dans le tableau : 
method action(var eventInfo ActionEvent) If eventInfo.id() = DataArriveRecord Then ColLignes(Self.RowNo);La ligne est passée en paramètre à la methode ColLigne Endif EndMethod()

Enfin, la methode ColLignes colore et décolore les objets du tableFrame : 
Proc color(var cUI UIobject) var ui UIobject endvar
ui.attach(cUI) ;Enregistrement courant en Bleu ui.color=DarkBlue ;Coloration des objets présents dans le cadre de table en fonction de paramètres modifiables. ;Ici, les champs en lecture seule apparaissent en blanc sur fond bleu. for n from 2 to ObjAR.size() ui.attach(ObjAR[n]) If UI.Class<> "Field" then loop endif If UI.DisplayType<>"EditField" then loop endif If ui.ReadOnly<>False then ui.font.color=White ui.Translucent=True endif endfor endproc
Proc decolor(var cUI UIobject) var ui UIobject st string endvar ;Récupération de la couleur initiale de l'enregistrement \'85 ui.attach(cUI) ui.color=rgb(RSI,GSI,BSI) ;\'85 et des objets dépendants for n from 2 to ObjAR.size() ui.attach(Cui.name+"."+ObjAR[n]) If UI.Class<> "Field" then loop endif If UI.DisplayType<>"EditField" then loop endif If ui.ReadOnly<>False then
ui.font.color=Black ui.Translucent=False endif
endfor endproc
method ColLignes(RowSI SmallInt)
VAR PriorUI, EnrUI UIObject ENDVAR try If NomAR.size() = 0 Then Return EndIf EnrUI.attach(NomAR[RowSI]);Récupération de l'enregistrement à colorer If nameST.isAssigned() then PriorUI.attach(nameST); Si un autre objet est coloré, décoloration Decolor(PriorUI) endif Color(EnrUI) Switch case NomAR[RowSI]=NomAR[NomAR.size()]:;Gestion des premiers et derniers PriorUI.attach(NomAR[NomAR.size()-1]);Gestion des premiers et derniers decolor(PriorUI) ;
Case NomAR[RowSI]=NomAR[1]: PriorUI.attach(NomAR[2]) decolor(PriorUI); Otherwise: Endswitch nameST=NomAR[RowSI];Prochaine ligne à décolorer ;En cas d'erreur (suppression des enregistrements par empty() par exemple), on perd l'enregistrement courant. ;Il faut alors décolorer tous les enregistrements, ils seront recolorés dans la methode action. onfail For n from 1 to NomAR.size() EnrUI.attach(NomAR[n]) Decolor(EnrUI) endfor endtry

|