Programmation de l'incrémentation automatique

L'objectif de cette note est de fournir une solution générale à la gestion des incréments automatiques. On se reportera à la note concernant l'utilisation des champs de type incrémentation automatique Paradox pour les problèmes posés par ce type de champ...

Exemple de solution

1) Vous définissez une table, nous l'appelerons ici NUMSEQ, qui va vous permettre de gérer les incréments. Sa structure est par exemple la suivante:

 

ALIAS_TABLE: champ A32, contiendra le nom complet (alias+table+extension) de la table

SEQUENCE: champ I, contient le prochain n° à affecter (valeur par défaut: 1)

 

2) Maintenant il faut piéger la validation dans toutes les fiches dans lesquelles les tables à incréments sont mises à jour. Pour cela, on insèrera le code suivant dans l'objet fiche:


USES OBJECTPAL
numseq(var eventInfo actionEvent, var dodefaultLO Logical) ;méthode située en librairie
ENDUSES
METHOD action(var eventInfo ActionEvent)
VAR
dodefaultLO ; passée par référence (VAR) à la méthode Gibbon
LOGICAL
ENDVAR
IF eventInfo.isPrefilter() THEN
else
IF eventInfo.Id() = DataUnlockRecord or eventInfo.Id() = DataPostRecord THEN
gLIB.NumSeq(eventInfo,dodefaultLO)
ENDIF
if dodefaultLO then
DODEFAULT
ELSE
DISABLEDEFAULT
ENDIF
ENDIF


3) La méthode numseq située dans la librairie gib01 va récupérer le nom de la table concernée et gérer l'incrément


method numseq(var eventInfo ActionEvent, var DodefaultLO Logical)
var
AliasTableST String

3) La méthode numseq située dans la librairie gib01 va récupérer le nom de la table concernée et gérer l'incrément


method numseq(var eventInfo ActionEvent, var DodefaultLO Logical)
var
AliasTableST String

si SMALLINT
seqAT ANYTYPE
ChampCleST STRING
ChampCleAT AnyType
endVar
AliasTableST = Active.tableName
;cas standard où on n'utilise pas d'alias de table dans les modèles relationnels pour les tables avec incrément
IF NOT gNumSeqTC.isAssigned() then ;une fois ouvert, le tcursor le restera tant que la bibliothèque sera utilisée
if not gNumSeqTC.open(":SYS_DATA:NUMSEQ.DB") THEN
errorshow("TCursor gNumSeqTC non ouvert")
RETURN FALSE
endif
gnumSeqTC.edit()
ENDIF
AliasTBST = upper(tbST)
; Attention, qLocate est sensible à la casse qqsoit le param IgnoreCaseInLocate
IF NOT gNumSeqTC.qlocate(AliasTBST) THEN return true ENDIF
Si = 0
dmGet(tbST, fieldName(AliasTBST, 1), ChampCleAT)
IF Not ChampCleAT.isBlank() THEN return true endif ; Incrément déjà initialisé
WHILE NOT gNumSeqTC.lockrecord()
si = si + 1
sleep(1000)
IF si > 10 THEN
FAIL(userError,"lockrecord impossible sur TCursor gNumSeqTC")
RETURN FALSE
ENDIF
ENDWHILE
seqAT = gNumSeqTC."SEQUENCE"

; Séquence pour le prochain utilisateur
gNumSeqTC."SEQUENCE" = gNumSeqTC.SEQUENCE + 1
gNumSeqTC.unlockRecord()
IF NOT dmPut(tbST, FieldName(AliasTBST,1), seqAT) THEN
ErrorShow()
RETURN FALSE
ENDIF
RETURN True
endmethod

Var ; variables de bibliothèque
gNumSeqTC Tcursor
endvar
method close() ; de la bibliothèque
if gNumSeqTC.isAssigned() then gNumSeqTC.close() endif
endmethod

Enfin, on prendra soin de faire une fiche d'administration du système qui permettra de recalculer le prochain n° d'incrément.

 

Vous pouvez enrichir la table Numseq et le code ci-dessus enrichi pour prendre en compte les différents types d'incréments dont vous pouvez avoir besoin (incrément par année, par mois, ajout des 0 en début de champ, ...), ce sans toucher le code des fiches. Vous pouvez également déclencher l'affectation de l'incrément dès l'insertion (sans attendre l'imputation). Si vous faites des insertions par programmation (via des tcursors par exemple),vous ferez une méthode similaire à Numseq en passant en paramètre le nom de la table concernée.