Lorsque l'on parcours une table HFSQL en utilisant un index défini en doublon, la question de l'ordre dans lequel les doublons sont parcourus peut se poser.
L'aide répond à la demande, on a par exemple pour HLitDernier : En cas de doublons, la fonction HLitDernier lit le dernier enregistrement "doublon" selon l'ordre des numéros d'enregistrement. Cependant, si l'on est pas familiarisé avec le principe d'utilisation des numéros d'enregistrement dans un fichier, cela ne donne pas immédiatement tous les éléments de réponse !
En effet, "selon l'ordre des numéros d'enregistrement " est parfois associé à l'ordre des ajouts, ou de l'identifiant automatique, et ça n'est pas le cas. Lorsqu'un enregistrement est ajouté, il est positionné soit :
- sur un nouvel emplacement tant qu'il n'y a pas eu de suppression dans le fichier de données,
- à un emplacement laissé libre par une précédente suppression.
Cet emplacement correspond au numéro de l'enregistrement dans le fichier. Il peut être connu après une lecture avec la fonction HNumEnr ou la variable h.NumEnr.
Donc dès qu'il y a eu des suppressions dans un fichier, si on tient compte des numéros d'enregistrement l'ordre des doublons n'est pas forcément celui des ajouts.
L'exemple autonome si dessous permet de bien comprendre le mécanisme, il suffit de le copier / coller dans un bouton et de l'exécuter pour bien comprendre le mécanisme...
UneDescriptionFichier est une Description de Fichier UneRubrique est une Description de Rubrique sdSource est une Source dede Données
UneDescriptionFichier.Nom = "DEMO_DOUBLON" UneDescriptionFichier.Type = hFichierNormal UneDescriptionFichier.CryptageFic = hCryptageStandard
UneRubrique.Nom = "NOM" UneRubrique.Type = hRubTexte UneRubrique.Taille = 40 UneRubrique.TypeClé = hCléDoublon HDécritRubrique(UneDescriptionFichier, UneRubrique)
UneRubrique.Nom = "ORDRE_AJOUT" UneRubrique.Type = hRubEntier1 HDécritRubrique(UneDescriptionFichier, UneRubrique)
HDécritFichier(sdSource, UneDescriptionFichier)
HCreation(sdSource)
sdSource.NOM = "Nom doublon" sdSource.ORDRE_AJOUT = 1 HAjoute(sdSource)
sdSource.NOM = "Nom doublon" sdSource.ORDRE_AJOUT = 2 HAjoute(sdSource)
sdSource.NOM = "Nom doublon" sdSource.ORDRE_AJOUT = 3 HAjoute(sdSource)
Trace("Parcours avant suppression") POUR TOUT sdSource Trace("Enregistrement : "+HEnregistrementVersChaîne(sdSource)+" // Position fichier (h.NumEnr) "+ HNumEnr(sdSource)) FIN

Trace("Suppression de l'enregistrement qui est en deuxième position, donc emplacement deux libre") HSupprime(sdSource, 2)
Trace("Ajout d'un 4ième enregistrement ...") sdSource.NOM = "Nom doublon" sdSource.ORDRE_AJOUT = 4 HAjoute(sdSource)
 Trace("Parcours après suppression et réutilisation de l'enreg laissé libre par un ajout") POUR TOUT sdSource Trace("Enregistrement : "+HEnregistrementVersChaîne(sdSource)+" // Position fichier (h.NumEnr) "+ HNumEnr(sdSource)) FIN Trace("S'il n'y avait pas eu de suppression, le 4 serait bien après le 3 et non à la place du 2")

A noter que la réindexation d'un fichier avec compactage, ou son optimisation complète avec l'utilitaire WDOptimiseur, peut recréer le fichier de données et utiliser de nouveaux emplacements (= nouveau numéros d'enregistrement).
L'ordre des doublons lors d'un parcours peut donc changer après une réindexation.
En conclusion, si un traitement doit lire des valeurs en doublons avec un ordre déterminé ou constant, la lecture sur la clé doublon seule est insuffisante. Il faut utiliser par exemple une clé composée de la rubrique en doublon, combinée avec une autre rubrique (identifiant automatique) qui sera discriminante pour l'ordre voulu. |