IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Tutoriel Oracle Forms : manipulations dynamiques 2e partie

Un écran de sélection de valeurs (LOV) générique, dynamique et personnalisable par l'utilisateur ♪

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Introduction

Cet outil permet de gérer toutes les LOV d'une application Oracle Forms9i de façon centralisée, sans manipulation des sources, ni compilation ni déploiement.

L'écran de LOV générique permet de restreindre la liste des valeurs à chaque caractère frappé selon la colonne de recherche indiquée par l'utilisateur
Un mode recherche globale permet de rechercher une valeur dans toutes les colonnes de la table liée


Générique parce qu'il s'adapte à toutes les LOV possibles de 2 à 9 colonnes

Dynamique car entièrement paramétré

  • Position X et Y de l'écran
  • Titre de la LOV
  • Auto sélection des valeurs
  • Libellé des colonnes
  • Position des colonnes
  • Largeur des colonnes

Personnalisable par l'utilisateur en lui permettant les actions suivantes

  • Permutation des colonnes entre elles
  • Redimensionnement des colonnes
  • Choix de la colonne de recherche
  • Enregistrement des préférences (une même LOV peut donc être représentée différemment selon l'utilisateur)


Le développeur dispose d'un écran Forms pour gérer les LOV de son application, permettant d'ajouter, modifier ou supprimer toute LOV du projet sans aucune intervention dans les modules sources.

Celui-ci affiche les modules, blocs et items de toute l'application. Sur chaque item il est possible de définir une LOV avec les caractéristiques suivantes :

  • Titre
  • Clause Select
  • Clause From
  • Clause Where
  • Clause Order by
  • Position X, Y
  • Auto affichage des lignes ramenées
  • Lov pour Validation de l'item

Et pour chaque colonne de la LOV

  • Position de la colonne
  • Nom de la colonne
  • Libellé de la colonne
  • Largeur d'affichage de la colonne
  • Nom de l'item de retour
  • Clause restrictive sur la colonne qui peut contenir une référence à un autre item de la forme



Liste des concepts étudiés

  • Utilisation de Groupe d'enregistrements (Record group) et de LOV native

    Ou comment à partir d'un unique groupe d'enregistrements et d'une unique LOV simuler n'importe quelle LOV de 2 à 9 colonnes avec adaptation des titres et largeur des colonnes.

    • Création dynamique d'un groupe d'enregistrements
    • Alimentation du groupe d'enregistrements
    • Comptage des enregistrements
    • Assignation du groupe d'enregistrements à une LOV native
    • Adaptation des titres de colonne de la LOV
    • Adaptation des largeurs de colonne de la LOV
    • Affichage de la LOV de contrôle
  • Modification dynamique de l'affichage

    • Affichage/masquage des objets
    • Positionnement des objets (Items, Canvas, Windows)
    • Redimensionnement des objets (Items, Canvas, Windows)
  • Utilisation d'un Timer
  • Gestion d'un menu POPUP
  • Gestion d'un bloc basé sur une clause FROM
  • Appel d'écran (CALL_FORM) avec passage de paramètres
  • Navigation à l'intérieur des items d'un bloc
  • Mécanisme de validation de l'item par LOV
  • SQL dynamique natif pour alimenter la liste des valeurs depuis la procédure stockée ainsi que pour la validation des items

Remerciements

Chaleureux remerciements à Developpez.com et à l'équipe SGBD.

2. L'écran de LOV générique

Image non disponible

Le titre de la LOV est affiché dans le libellé de la fenêtre
Le champ de saisie des caractères en haut à gauche a toujours le focus, permettant à l'utilisateur d'ajouter des lettres à chaque frappe au clavier et de réduire la liste
La colonne sur laquelle s'effectue la recherche est matérialisée par un fond gris (Colonne Nom dans l'exemple ci-dessus)
La navigation dans la liste de valeurs se fait soit avec la souris dans une des lignes affichées, soit en activant l'ascenseur vertical, soit avec les touches du clavier (UP, DOWN, SCROLL_UP, SCROLL_DOWN)
La sélection d'une ligne dans la liste se fait soit par un double clic sur la ligne, soit via le bouton OK

Possibilités de personnalisation

  • Redimensionnement des colonnes

Pour redimensionner une colonne, il faut d'abord la sélectionner par un clic gauche sur la colonne. Ensuite, un clic droit fait apparaître un menu popup
Dans ce menu, choisir l'option Dimensions

Image non disponible

Sous la colonne sélectionnée apparaissent alors deux boutons permettant de réduire (-) ou d'augmenter (+) la largeur de la colonne

Image non disponible

Les tailles minimum et maximum pour une colonne sont respectivement de 20 à 700 points.

Une fois la bonne dimension réglée, un clic sur n'importe quelle région de l'écran fait disparaître les deux boutons

  • Changement de la colonne de recherche

Il est possible de sélectionner n'importe quelle colonne de la LOV pour effectuer la recherche.
La colonne de recherche est soulignée par un fond gris.

Pour changer la colonne de recherche, sélectionnez la colonne désirée par un clic gauche puis afficher le menu popup avec un clic droit

Clic gauche sur la colonne Fonction puis clic droit

Image non disponible

Clic sur le sous-menu Colonne de recherche

Image non disponible

La colonne de recherche est désormais Fonction.
D'ailleurs la frappe du caractère C dans le champ de saisie ramène bien les lignes dont la colonne Fonction commence par C

  • Permutation des colonnes

Pour permuter les colonnes entre elles, sélectionner la colonne par un clic gauche puis afficher le menu popup avec un clic droit.

Sélectionner l'option de menu Déplacement, puis la sous-option Déplacer à droite ou Déplacer à gauche.


Dans l'exemple, nous choisissons de déplacer la colonne Fonction vers la gauche

Image non disponible

La colonne Fonction a été permutée sur la gauche avec la colonne Nom

Image non disponible


Le mode Recherche globale

Si le développeur a pris soin de définir une table principale sur cette LOV, la case à cocher Recherche Multicolonne est activable.
Ce mode permet de rechercher une occurrence dans toutes les colonnes de la table définie par le développeur (à l'exception des colonnes de type LONG, LONG RAW, RAW, BLOB et BFILE)

Pour activer le mode Recherche globale il suffit de cocher la case Recherche Multicolonne, de saisir l'occurrence dans le champ de saisie et de valider par la touche Tab ou Enter

Ce mode est pratique lorsque les colonnes affichées ne permettent pas à l'utilisateur d'identifier la ligne voulue, alors que ce dernier " se souvient " par contre d'une information saisie dans une autre colonne

Image non disponible

Dans cet exemple (peu vraisemblable, mais c'est pour l'exemple) l'utilisateur a " oublié " le nom mais se souvient que le salaire est de 1215 euros.
Il clique donc sur la case Recherche Multicolonne, saisi 1215 dans le champ de saisie et presse la touche Tab du clavier.


Enregistrement des réglages

Si l'utilisateur souhaite conserver les réglages qu'il vient d'effectuer, afin de les retrouver automatiquement à la prochaine ouverture de cette LOV, il clique sur le bouton Sauver réglages
Suivant le même principe que la gestion des couleurs, ces nouveaux réglages ne sont valables que pour cet utilisateur. Tout autre utilisateur n'ayant pas modifié ses préférences verra cette LOV affichée avec les réglages par défaut.


Comment ça marche ?

Ouvrons le fichier source de l'écran et analysons le contenu

  • Le canvas
Image non disponible

Contenu du bloc associé au canvas

Image non disponible

9 colonnes sont définies dans le bloc BLOC2 afin de supporter toute LOV possible de 2 à 9 colonnes.

Les items COL1 à COL9 sont de type Elément texte Char d'une longueur maxi de 512 caractères

Au chargement de la LOV seuls les items nécessaires seront affichés et disposés dans la fenêtre

Afin de pouvoir gérer la sélection des données depuis n'importe quelle requête dynamique, le bloc BLOC2 est basé sur une Interrogation de clause FROM

Voyons comment le bloc BLOC2 est configuré pour être alimenté par une Interrogation de clause FROM

Image non disponible

La propriété Type de source de données est renseignée à Interrogation de clause FROM
La propriété Nom de source de données est valorisée avec la requête virtuelle : select '1','2','3','4','5','6','7','8' from dual
La propriété Colonnes de source de données permet de définir les items de réception

Image non disponible



Le champ de saisie (P1), la boite à cocher (Recherche Multicolonne) ainsi que tous les boutons sont contenus dans le bloc CTRL

Image non disponible

Le champ P1 reçoit la frappe de l'utilisateur
Le champ RECHERCHE permet de basculer en mode Recherche globale
Le bouton BT_OK valide la sélection dans la liste, retourne les valeurs et quitte la forme
Le bouton BT_QUITTER quitte la forme sans retour de valeur
Le bouton BT_SAUVE permet de sauvegarder en base les réglages de l'utilisateur
Les boutons PLUS et MOINS permettent le redimensionnement des colonnes

Comment faire défiler avec le clavier la liste des enregistrements ramenés alors que le focus est constamment sur le champ de saisie P1 ?

Regardons le contenu des triggers KEY-DOWN, KEY-UP, KEY-SRCDOWN et KEY-SCRUP définis sur l'item P1 et analysons le premier

 
Sélectionnez
 -- Trigger KEY-DOWN --
 Go_Block( 'BLOC2' ) ; -- déplacement sur le bloc BLOC2
 Down ;
 Go_Item( 'CTRL.P1' ) ; -- retour dans l'item :CTRL.P1

Simple, non ?

Mécanisme général du fonctionnement de l'écran GEN_LOV

La procédure Init_form() est appelée depuis le trigger WHEN-NEW-FORM-INSTANCE dès le chargement de l'écran

Elle commence par masquer les 9 items du bloc BLOC2

 
Sélectionnez
  -- Masquage des champs --
  For I in 1..9 Loop
  	 Set_Item_Property( 'BLOC2.COL' || Ltrim( To_char( I ) ), VISIBLE, PROPERTY_FALSE ) ;
  End loop ;

- Positionne l'indicateur de modification à zéro

 
Sélectionnez
	-- Indicateur de modification --
	:CTRL.MODIF := 0 ;

- Désactive la case à cocher de la Recherche globale si aucune table n'est transmise via le paramètre : PARAMETER.PM$TABLE

 
Sélectionnez
	-- Table en paramètre pour recherche globale ? --
	If :PARAMETER.PM$TABLE Is null Then
		  Set_Item_Property( 'CTRL.RECHERCHE', ENABLED, PROPERTY_FALSE ) ;
	End if ;

- Positionne la fenêtre en coordonnées X,Y selon les paramètres fournis

 
Sélectionnez
	-- Position X,Y --
	If Nvl( :PARAMETER.POSX, 0 ) > 0 Then
		 Set_Window_Property( 'FENETRE1', X_POS, :PARAMETER.POSX ) ;
	End if ;
	If Nvl( :PARAMETER.POSY, 0 ) > 0 Then
		 Set_Window_Property( 'FENETRE1', Y_POS, :PARAMETER.POSY ) ;
	End if ;

- Lit dans la table LOV_ELEMENT_COLONNE les informations nécessaires à la gestion de la LOV

 
Sélectionnez
	-- Lecture des colonnes de la LOV en table --
	init_bloc_bl_col ;

Cette procédure permet de retrouver les colonnes, leur libellé, position et largeur

- Dimensionne, ordonne et affiche les colonnes nécessaires

 
Sélectionnez
	-- Affichage des colonnes --
	dessine_colonnes ;
 
Sélectionnez
PROCEDURE Dessine_colonnes IS
  LN$PosX	PLS_INTEGER := :CTRL.POS_X ;
  LN$Long	PLS_INTEGER ;
  LC$Item	VARCHAR2(30);
  LN$TCan	PLS_INTEGER := 0;
  LN$Max	PLS_INTEGER ;
  LN$larg	PLS_INTEGER ;
  LN$Taille	PLS_INTEGER ;
BEGIN
  ----------------------------------
  -- Affiche les colonnes de la lov
  -- et dimensionne la fenêtre
  ----------------------------------

  LN$TCan := 325 ;     -- Taille minimum du canvas
  LN$Max := LN$PosX ;  -- Largeur maxi du canvas
  go_block( 'BL_COL' ) ;
  First_record ; -- première colonne
  Loop -- pour chaque colonne
		
		LC$ITEM := 'BLOC2.' || :BL_COL.COLONNE ;
	
		LN$Long := :BL_COL.Taille ;  -- largeur de la colonne
		LN$Max := LN$Max + LN$Long ; -- largeur canvas avec colonne
		-- Ajuster la largueur du Canvas ? --
		If LN$Max > LN$TCan Then
			LN$TCan := LN$Max + 20 ;
			Set_Canvas_Property( 'CV_LOV', WIDTH, LN$TCan ) ; -- agrandissement du canvas
		End if ;
		
		Set_Item_Property(LC$Item, VISIBLE, PROPERTY_TRUE); -- affichage de la colonne
		Set_Item_Property(LC$Item, ENABLED, PROPERTY_TRUE);
		Set_Item_Property(LC$Item, NAVIGABLE, PROPERTY_TRUE);
		Set_Item_Property(LC$Item, UPDATE_ALLOWED, PROPERTY_TRUE);
		Set_Item_Property(LC$Item, WIDTH, :BL_COL.Taille);  -- largeur de la colonne
		Set_Item_Property(LC$Item, NEXT_NAVIGATION_ITEM, :BL_COL.Suivant);       -- item suivant
		Set_Item_Property(LC$Item, PREVIOUS_NAVIGATION_ITEM, :BL_COL.Precedent); -- item précédent
		-- Coordonnée X de la colonne sur le canvas --
		Set_Item_Property(LC$Item, X_POS, LN$PosX);
		LN$PosX := LN$PosX + LN$Long ;  	
		If :system.last_record = 'TRUE' Then
			exit ;
		End if ;
		Next_record ;
  End loop ;
  
  If LN$Tcan < 325 Then
  	LN$Larg := 325 ;
  Elsif LN$Tcan > 600 Then
  	LN$Larg := 600 ;
  Else
  	LN$Larg := LN$Tcan ;
  End if ;

  -- Adaptation de la largeur de la vue --
  Set_View_Property( 'CV_LOV', WIDTH, LN$TCan ) ;
  Set_View_Property( 'CV_LOV', VIEW_SIZE, LN$TCan, 324 ) ;
  -- Adaptation de la largeur de la fenêtre (maxi 600 points) --
  If LN$TCan < 600 Then
 	Set_Window_Property( 'FENETRE1', WIDTH, LN$TCan ) ;
  Else
 	Set_Window_Property( 'FENETRE1', WIDTH, LN$Larg ) ;
  End if ;
   
END;

- Met en relief la colonne de recherche

 
Sélectionnez
 -- Mise en relief de la colonne de recherche --
 Colore_colonne ;
 
Sélectionnez
PROCEDURE COLORE_COLONNE IS
BEGIN

  -- Colore la colonne de recherche --
  If :GLOBAL.ANCCOLONNE is not null Then
  	-- dé-grise l'ancienne colonne de recherche --
  	Set_Item_Property( :GLOBAL.ANCCOLONNE, VISUAL_ATTRIBUTE, 'VA_COL_NOSELECT' );
  End if ;
  -- grise la nouvelle colonne de recherche --
  Set_Item_Property( :CTRL.COL_RECH, VISUAL_ATTRIBUTE, 'VA_COL_SELECT' );

END;

La colorisation des items s'effectue via la définition d'un attribut visuel

- Active le temporisateur

 
Sélectionnez
	-- Init du timer --
	Init_timer ;

Le temporisateur est utilisé pour lancer l'exécution de la requête (execute_query) à un intervalle de temps exprimée en millisecondes, lue depuis la variable de package (PKG_GESTION_LOV.GN$Duree_Timer) afin de pouvoir être adaptée au plus juste de votre configuration.
Par défaut elle est de 800 millisecondes, ce qui permet à l'utilisateur de saisir plusieurs caractères avant le déclenchement du query
Le timer reste actif tant que le focus se trouve dans le champ de saisie (:CTRL.P1) et désactivé dès que l'on en sort

Lorsque le temporisateur est actif, le trigger de niveau forme WHEN-TIMER-EXPIRED se déclenche et exécute le code suivant :

 
Sélectionnez
Begin
	If :CTRL.P1 is not null Then
		if :CTRL.P1 <> nvl(:CTRL.PSAUV,'_') Then
			:CTRL.PSAUV := :CTRL.P1;
			Execute_recherche ;
		End if ;
	End if ;
End;

Pour lancer la recherche on vérifie que le champ de saisie n'est pas NULL et que sa valeur a été modifiée depuis le précédent query

Il faut noter que lorsque que l'on enclenche le mode Recherche globale, le temporisateur est désactivé puisque le query est déclenché manuellement par l'utilisateur lors de la frappe de la touche Tab ou Enter

Voici le code du trigger (WHEN-CHECKBOX-CHANGED) attaché à la boite à cocher :

 
Sélectionnez
If :CTRL.RECHERCHE = 1 Then
	-- recherche multicolonne --
	Init_timer( FALSE ) ; -- désactivation du timer --
	:CTRL.P1 := '' ;      -- on vide le champ de saisie --
	:CTRL.ACTION := 'W' ; -- word index --
Else                           
	-- recherche monocolonne --
	:CTRL.P1 := :CTRL.PSAUV ; -- on réalimente le champ de saisie avec l'ancienne valeur--
	:CTRL.ACTION := 'N' ;     -- recherche approchée --
	Init_timer( TRUE ) ;      -- réactivation du timer --
End if ;	

go_item('CTRL.P1');

- Prérenseigne le champ de saisie en fonction du paramètre transmis et se positionne

 
Sélectionnez
	-- Item de sélection des valeurs --
	If :PARAMETER.AUTO_SELECT = 'O' Then
		 :CTRL.P1 := '%' ;
	End if ;
	Go_item('CTRL.P1');

Si le développeur a configuré cette LOV pour afficher la sélection dès l'apparition de l'écran, on prérenseigne le champ de saisie avec le caractère %, sinon l'écran attend que l'utilisateur frappe un caractère pour lancer la recherche

Dimentionnement d'une colonne

Le choix de l'option Dimension du menu popup exécute la fonction Redim_colonne().
Celle-ci positionne (Set_Item_Property( …, X_POS/Y_POS) )et rend visible les boutons + et - en bas de la colonne concernée (Set_Item_Property ( …, VISIBLE, PROPERTY_TRUE ) ;)

Si l'utilisateur décide d'agrandir la colonne, un clic sur le bouton + exécute le code suivant :

 
Sélectionnez
Declare
	LN$T	PLS_INTEGER := Get_Item_Property( :GLOBAL.COLONNE, WIDTH );
	LC$Col	VARCHAR2(30);
Begin
	-- redimensionnement de la colonne --
	-- plus 10 pixels --
	If LN$T < 300 Then
		LN$T := LN$T + 10 ;
		Set_Item_Property( :GLOBAL.COLONNE, WIDTH, LN$T ) ;
		LC$Col := Substr( :GLOBAL.COLONNE, instr( :GLOBAL.COLONNE, '.' ) + 1, 30 ) ;
		Maj_Taille_Colonne( LC$Col, LN$T ) ;
		Dessine_colonnes ;
	End if ;
End ;

La taille de l'item est augmentée de 10 points, la procédure Maj_Taille_Colonnes() est invoquée pour mettre à jour les infos de la colonne sauvegardées dans le bloc caché BL_COL, puis l'écran est redessiné via la procédure Dessine_colonnes()

Lorsque l'utilisateur clique à l'extérieur d'un des deux boutons, ceux-ci sont masqués via le trigger de niveau forme WHEN-MOUSE-CLICK

 
Sélectionnez
-- Effacer les boutons de dimensionnement --
If Nvl(:system.mouse_item,'_') not in ('CTRL.MOINS','CTRL.PLUS') Then
	Set_Item_Property( 'CTRL.PLUS', VISIBLE, PROPERTY_FALSE ) ;
	Set_Item_Property( 'CTRL.MOINS', VISIBLE, PROPERTY_FALSE ) ;
End if ;

Sélection d'une valeur et retour à l'écran d'appel

Pour sélectionner une valeur, l'utilisateur clique sur la ligne de la liste puis sur le bouton Ok ou double clique sur la ligne, déclenchant l'appel de la procédure Selection_valeur(), dont voici le code :

 
Sélectionnez
PROCEDURE Selection_valeur IS
	  LR_COL_LOV  PKG_GESTION_LOV.TYPE_REC_LOV ;
Begin
	-- Ligne selectionnee --
	Go_block( 'BLOC2' ) ;
	If :system.record_status = 'QUERY' Then -- si la ligne n'est pas vide

		-- RAZ des variables de retour --
		PKG_GESTION_LOV.RAZ_Valeurs_LOV ;
	
		LR_COL_LOV.COl1 := :BLOC2.COL1 ;
		LR_COL_LOV.COl2 := :BLOC2.COL2 ;
		LR_COL_LOV.COl3 := :BLOC2.COL3 ;
		LR_COL_LOV.COl4 := :BLOC2.COL4 ;
		LR_COL_LOV.COl5 := :BLOC2.COL5 ;
		LR_COL_LOV.COl6 := :BLOC2.COL6 ;
		LR_COL_LOV.COl7 := :BLOC2.COL7 ;
		LR_COL_LOV.COl8 := :BLOC2.COL8 ;
		LR_COL_LOV.COl9 := :BLOC2.COL9 ;
		
		-- Mise à jour des variables de retour --
		PKG_GESTION_LOV.MAJ_Valeurs_LOV( LR_COL_LOV ) ;
		
		Exit_form( NO_VALIDATE ) ;
		
	Else
		Go_Item( 'CTRL.P1' ) ;
	End if ;
End ;

Les variables de retour, stockées dans le package sont d'abord effacées, puis valorisées avec celles de la ligne sélectionnée, permettant à l'écran d'appel de les traiter.

3. L'écran de gestion des LOV (INIT_LOV.FMB)

Image non disponible

Il présente la liste des modules, blocs et items de votre application

Ces informations sont automatiquement enregistrées en table pour chacun de vos modules grâce à l'appel de procédure Init_referentiel_lov() qui se trouve en commentaire dans chaque trigger WHEN-NEW-FORM-INSTANCE
Pour renseigner l'ensemble de ces informations, il suffit de retirer le commentaire, exécuter le module, quitter et remettre le commentaire

En regard de chaque composant : module, bloc et item, vous pouvez saisir un libellé

Le canvas inférieur contient 3 onglets

Un onglet Items qui affiche la liste des items du bloc et du module sélectionné, un libellé libre ainsi qu'un rappel du format appliqué sur l'item

Image non disponible

Un onglet LOV qui permet de définir les propriétés de la LOV attachée à l'item sélectionné

Nom table permet de définir le nom d'une table qui servira à la recherche globale
Validation permet de définir si la LOV doit servir a valider l'item en saisie
Auto select permet de définir si la LOV affichera la liste de sélection dès son affichage
PosX et PosY, facultatifs, permettent de positionner la LOV
Titre de la LOV permet d'indiquer le titre
Select reçoit la partie Select de la requête (sans le mot clé Select)
From reçoit la partie From de la requête (sans le mot clé From)
Where (facultatif) reçoit la partie Where de la requête (sans le mot clé Where)
Order by (facultatif) reçoit la partie Order by de la requête (sans le mot clé Order by)

La case à cocher Ok non modifiable indique si la LOV est valide et donc accessible à l'utilisateur
Tant que cette LOV n'est pas valide, elle ne sera ni visible ni utilisable pour l'utilisateur

Le bouton Afficher l'ordre select permet de visualiser la requête complète

Image non disponible

Le bouton Contrôle de la syntaxe permet de vérifier la cohérence de la requête, d'alimenter les colonnes de l'onglet Colonnes LOV

Image non disponible

Tant que vous n'avez pas la certitude que votre LOV s'exécutera correctement, il est inutile de répondre Oui pour la reconstruction des correspondances de colonne
(Cette opération remplace les définitions de colonnes de cette LOV dans la table LOV_ELEMENT_COLONNE et par conséquent les réglages utilisateurs éventuellement sauvegardés)

Et d'afficher dans une LOV native le résultat de la requête

Image non disponible

Nous n'avons utilisé pour cela qu'un unique groupe d'enregistrement et une unique LOV native !

Pourtant nous pouvons représenter n'importe quelle LOV de 2 à 9 colonnes…

Dans cet exemple, nos 3 colonnes sont correctement affichées, dimensionnées et titrées

Image non disponible

L'onglet Colonnes LOV permet de configurer chaque colonne de la LOV

Ordre permet d'ordonner l'affichage par défaut des colonnes
Colonne contient le nom de la colonne
Item de réception reçoit l'item qui devra recevoir la valeur de cette colonne
Rech permet de définir la colonne de recherche par défaut
Val permet de définir la colonne qui servira à valider l'item
(Les LOV natives de Forms ne permettent d'utiliser que la première colonne pour la validation des items. Ici, vous pouvez sélectionner n'importe laquelle)
Taille permet de définir la largeur d'affichage en caractères
Libellé colonne LOV permet de définir le libellé tel qu'il apparaîtra dans la LOV

Image non disponible

Clause permet de définir une clause restrictive sur la colonne. Cette clause peut contenir une référence à un autre item de la forme (Placeholder). Dans ce cas, il doit se conformer à la syntaxe Forms :bloc.item (par exemple >2 ou bien = :bloc.item, ou n'importe quel ordre sql pouvant apparaître dans la clause Where)

Valeur de test permet de saisir la valeur de remplacement du placeholder (uniquement pour la validation de la LOV)

Rentrons dans le détail

La procédure Init_referentiel_lov(),présente dans le trigger WHEN-NEW-FORM-INSTANCE permet d'initialiser pour chaque forme les items qui la compose (cette procédure se trouve dans la librairie Forms LOV.PLL)

Le nom du module (Name_in( 'system.current_form' )) est enregistré dans la table LOV_MODULE

 
Sélectionnez
Begin
	Insert into LOV_MODULE
	(
	  NOM_MODULE
	 ,LIBELLE
	)
	Values
	(
	  LC$Module
	 ,Null
	);
Exception
	When DUP_VAL_ON_INDEX then
    		Null ;
End;

Le traitement de l'exception DUP_VAL_ON_INDEX permet de faire l'économie d'un Select pour vérifier si l'item existe déjà.

On sélectionne le premier bloc de la forme avec l'instruction :

 
Sélectionnez
LC$Block := Get_Form_Property( LC$Module, FIRST_BLOCK ) ;

Et l'on boucle sur tous les blocs

 
Sélectionnez
While LC$Block is not null Loop -- pour chaque block --

Le nom du bloc est enregistré dans la table LOV_BLOCK

 
Sélectionnez
Begin
	Insert into LOV_BLOCK
	(
	  MOD_NOM_MODULE
	 ,NOM_BLOCK
	)
	Values
	(
	  LC$Module
	 ,LC$Block
	);
Exception
	When DUP_VAL_ON_INDEX then
	    Null ;
End;

On se positionne sur le premier item du bloc avec l'instruction suivante :

 
Sélectionnez
LC$Item := Get_Block_Property( LC$BLOCK, FIRST_ITEM ) ;

Puis l'on boucle sur tous les items de ce bloc

 
Sélectionnez
While LC$Item is not null Loop  -- Pour chaque item

On rejette les items de type BUTTON ou de type LONG

 
Sélectionnez
If Get_Item_Property( LC$Bitem, ITEM_TYPE ) <> 'BUTTON' Then
  	LC$Type := Get_Item_Property( LC$Bitem, DATATYPE ) ;
  	If LC$Type <> 'LONG' Then

Le libellé de l'item est issu de son prompt

 
Sélectionnez
LC$Prompt := Substr( Get_Item_Property( LC$Bitem, PROMPT_TEXT ), 1, 80 ) ;

Le format est également sauvegardé

 
Sélectionnez
LC$Format := Get_Item_Property( LC$Bitem, FORMAT_MASK ) ;

Il servira à mettre en conformité de format la valeur de retour de la LOV

Et l'on enregistre chaque item dans la table LOV_ITEM

 
Sélectionnez
Begin
	Insert into LOV_ITEM
	(
	  MODULE
	 ,BLOC
	 ,ITEM
	 ,LIBELLE
	 ,ID
	 ,ITEM_TYPE
	 ,FORMAT
	)
	Values
	(
	  LC$Module
	 ,LC$Block
	 ,LC$Item
	 ,LC$Prompt
	 ,SEQ_ITEM.NEXTVAL
	 ,Decode( LC$Type, 'CHAR', 'C', 'DATE', 'D', 'N' )
	 ,LC$Format
	);
Exception
When DUP_VAL_ON_INDEX then
	    Null ;
End;

Un seul groupe d'enregistrement et une seule LOV native pour simuler n'importe quelle LOV de 2 à 9 colonnes ?
Comment cela fonctionne-t-il ?

Pour cela nous allons utiliser un groupe d'enregistrement construit dynamiquement

Si l'on peut construire dynamiquement un groupe d'enregistrement, il n'en va pas de même pour une LOV native
Celle-ci doit exister physiquement dans la forme
Puisque nous nous autorisons à gérer des LOV de 2 à 9 colonnes, il faut donc disposer d'une LOV native composée de 9 colonnes à laquelle nous associerons ensuite le groupe d'enregistrements, qui sera lui-même composé de 9 colonnes
Une LOV native LV_SYNTAXE est donc créée dans la forme composée de 9 colonnes COL1, COL2,...,COL9
Si la requête fait référence à moins de 9 colonnes, des colonnes NULL seront ajoutées au groupe d'enregistrement pour coïncider avec la LOV native de contrôle d'une part, et la procédure stockée qui renseigne également 9 colonnes d'autre part

Ouvrons la procédure Check_sql_order() du module INIT_LOV.FMB

Définissons une variable de type record_group

 
Sélectionnez
rg_name    VARCHAR2(40) := 'RG_SYNTAXE2';
rg_id      RecordGroup;

Reconstituons l'ordre SQL complet et jetons-le en pâture au paquetage Oracle DBMS_SQL

 
Sélectionnez
  ------------------------------------------
  -- Verifie que l'ordre SQL est conforme --
  ------------------------------------------
  --
  LC$Req := 'Select ' || CHR(10) || :BL_LOV.ORDRE || CHR(10) 
     || ' From ' || CHR(10) || :BL_LOV.FROM ;
  If :BL_LOV.FILTRE is not null Then
    LC$Req := LC$Req || CHR(10) || ' Where ' || CHR(10) || :BL_LOV.FILTRE ;
  End if ;
  If :BL_LOV.T_ORDERBY is not null Then
    LC$Req := LC$Req || CHR(10) || ' Order BY ' || CHR(10) || :BL_LOV.T_ORDERBY ;
  End if ;  
  LC$Req := Rtrim( LC$Req, ';' ) ;
  Begin
    c := dbms_sql.open_cursor;
    dbms_sql.parse(c,LC$Req, 1);
    d := dbms_sql.execute(c);
  Exception
  	When others Then
  	  dbms_sql.close_cursor(c);
  	  :BL_LOV.OK := 'N' ;
  	  Set_Alert_Property( 'AL_ERREUR', TITLE, 'Contrôle de l''ordre SQL' ) ;
  	  Set_Alert_Property( 'AL_ERREUR', ALERT_MESSAGE_TEXT, 'Ordre SQL incorrect' ) ;
  	  LN$Cpt := Show_Alert( 'AL_ERREUR' ) ;  	  
  	  Raise form_trigger_failure ;
  End ;
  dbms_sql.describe_columns2(c, col_cnt, rec_tab);
  dbms_sql.close_cursor(c);

Si la requête ne franchit pas cette étape, c'est qu'elle est incorrecte

Nous rejetons également les colonnes de type LONG, LONGRAW, RAW et les LOBs

 
Sélectionnez
  LB$Ret := TRUE ;
  For i IN rec_tab.first .. rec_tab.last Loop
  	 If rec_tab(i).col_type IN (8,23,24,113,114) Then
  	   Set_Alert_Property( 'AL_ERREUR', TITLE, 'Contrôle de l''ordre SQL' ) ;
  	   Set_Alert_Property( 'AL_ERREUR', ALERT_MESSAGE_TEXT, rec_tab(i).col_name 
  	      || ' Colonnes LONG, LONGRAW, RAW, BLOB, BFILE non autorisées' ) ;
  	   LN$Cpt := Show_Alert( 'AL_ERREUR' ) ;
  	   LB$Ret := FALSE ;
  	 End if ;
  End loop ;
  If not LB$Ret Then
  	Raise form_trigger_failure ;
  End if ;

Nous n'acceptons pas non plus les LOV de moins de 2 colonnes ou de plus de 9 colonnes

 
Sélectionnez
  If col_cnt < 2 or col_cnt > 9 Then
  	 Set_Alert_Property( 'AL_ERREUR', TITLE, 'Contrôle de l''ordre SQL' ) ;
  	 Set_Alert_Property( 'AL_ERREUR', 
  	    ALERT_MESSAGE_TEXT, 'l''ordre SQL doit contenir entre 2 et 9 colonnes' ) ;
  	 LN$Cpt := Show_Alert( 'AL_ERREUR' ) ;
  	 :BL_LOV.OK := 'N' ;
  	 Raise form_trigger_failure ;
  End if ;

Nous ajoutons ensuite à la clause where les clauses éventuellement définies au niveau de chaque colonne de l'onglet Colonnes LOV

L'extraction des colonnes de la partie Select de l'ordre, ainsi que l'ajout éventuel des colonnes NULL manquantes sont réalisés par la procédure Build_Select_line()

Puis nous construisons notre groupe d'enregistrements dynamique à l'aide de la requête stockée dans la variable LC$Req

 
Sélectionnez
	rg_id := Find_Group( rg_name ); 
	IF Not Id_Null(rg_id) THEN 
		Delete_group( rg_id ) ;
	End if;

	rg_id := Create_Group_From_Query( rg_name, LC$Req ) ;

	errcode := Populate_Group( rg_id );

Si cette étape est encore franchie et que nous avons répondu Oui à la demande de reconstruction des colonnes de la LOV, l'onglet Colonnes LOV est pré alimenté

Enfin nous associons à notre LOV native le groupe d'enregistrement fraîchement créé

 
Sélectionnez
Set_Lov_Property( 'LV_SYNTAXE', GROUP_NAME, rg_name ) ;

Nous réglons les titre et largeur par défaut des colonnes

 
Sélectionnez
  -- Mise a jour titre et largeur des colonnes --
  For i IN rec_tab.first..rec_tab.last Loop
    -- Titre --
    Set_Lov_Column_Property( 'LV_SYNTAXE', i, TITLE, rec_tab(i).col_name ) ;
    -- Largeur --
    LN$Pos := 30 ;
    If rec_tab(i).col_type IN (1,96) Then
    	If rec_tab(i).col_max_len > 30 Then
           LN$Pos := 30 ;
    	Else
    	   LN$Pos := rec_tab(i).col_max_len ;
    	End if ;
    Elsif rec_tab(i).col_type = 2 Then
    	If rec_tab(i).col_precision = 0 Then
    	  LN$Pos := 10 ;
    	Else
    	  LN$Pos := rec_tab(i).col_precision ;
    	End if ;
    Elsif rec_tab(i).col_type = 12 Then
    	  LN$Pos := 12 ;
    Elsif rec_tab(i).col_type IN (112,113) Then
    	  LN$Pos := 30 ;
    End if ;  	
    LN$Pos := LN$Pos * 6 ;
    Set_Lov_Column_Property( 'LV_SYNTAXE', i, WIDTH, LN$Pos ) ;
  End loop ;

Masquons les colonnes inutiles (NULL) en positionnant leur largeur à 0

 
Sélectionnez
  -- Masquage des colonnes non renseignées --
  If rec_tab.last < 9 Then
      For i IN rec_tab.last + 1..9 Loop
  	     Set_Lov_Column_Property( 'LV_SYNTAXE', i, WIDTH, 0 ) ;
      End loop ;
  End if ;

Et affichons la LOV native

 
Sélectionnez
LB$Ret := Show_Lov('LV_SYNTAXE') ;

Gestion des LOV

Nous avons défini une LOV sur notre item et vérifié que sa syntaxe est correcte

Que se passe-t-il lorsque l'utilisateur utilise son application ?

Lorsqu'une LOV native est présente sur un item de saisie, la barre d'état affiche l'indication "Liste de valeur…"
Lorsque cette LOV native est surchargée par une LOV générique, elle est automatiquement désactivée car devenue inutile.
Dans ce cas la barre d'état n'indique plus à l'utilisateur la présence d'une LOV disponible !
C'est pourquoi, au lancement de chaque forme, la procédure Init_item_lov() stockée dans la librairie LOV.PLL, est appelée depuis le trigger WHEN-NEW-FORM-INSTANCE

Cette procédure recherche pour l'écran en cours la liste des LOV génériques que vous avez définis, inhibe les éventuelles LOV natives concurrentes en fixant la propriété LOV_NAME à NULL

 
Sélectionnez
-- Désactivation de l'éventuelle LOV native --
Set_Item_Property( LC$Item, LOV_NAME, '' ) ;
Set_Item_Property( LC$Item, VALIDATE_FROM_LIST, PROPERTY_FALSE ) ;

Et indique à l'utilisateur la présence de la LOV en ajoutant (LOV) à la fin du Hint…
C'est la raison pour laquelle il est impératif que la propriété Aide automatique de vos items soit positionnée à OUI !
Lorsqu'il s'agit d'une LOV de validation, l'indicateur (LOVV) est ajouté

L'utilisateur entre dans le champ de saisie et demande l'affichage de la LOV avec les touches Ctrl+L

Le trigger de niveau forme KEY-LISTVAL se déclenche et appelle la procédure Display_lov() stockée dans la librairie LOV.PLL

Celle-ci commence par vérifier qu'une LOV générique a été définie pour cet item
Si elle n'en trouve pas, elle vérifie qu'une LOV native existe et l'exécute. (ce système permet de conserver le fonctionnement des LOV natives que vous n'aurez pas jugé bon de surcharger)

Si elle trouve une LOV générique, elle récupère dans les tables les informations nécessaires, reconstruit la clause where à partir des clauses de colonne éventuellement définies dans l'onglet Colonnes LOV et appelle l'écran de LOV générique GEN_LOV via la procédure Call_gen_lov()

 
Sélectionnez
------------------------------
-- Appel de l'écran GEN_LOV --
------------------------------
PROCEDURE CALL_GEN_LOV
 (
   PN$Item    IN NUMBER,
   PC$Table   IN VARCHAR2,
   PC$Select  IN VARCHAR2,
   PC$From    IN VARCHAR2,
   PC$Where   IN VARCHAR2,
   PC$Orderby IN VARCHAR2,
   PC$Affiche IN VARCHAR2,
   PN$PosX    IN NUMBER,
   PN$PosY    IN NUMBER,   
   PC$Titre   IN VARCHAR2   
 )
  IS
pl_id ParamList; 
pl_name VARCHAR2(10) := 'gen_lov'; 
BEGIN
-- Création de la liste de paramètres --
pl_id := Get_Parameter_List(pl_name); 

IF NOT Id_Null(pl_id) THEN 
	Destroy_Parameter_List(pl_id); 
End if ;

pl_id := Create_Parameter_List(pl_name); 
IF Id_Null(pl_id) THEN Message('Erreur de création de liste de paramètres '||pl_name);
	RAISE Form_Trigger_Failure; 
END IF; 
-- Ajout des paramètres à la liste --
Add_Parameter(pl_id,'UTI_ID'     ,TEXT_PARAMETER, Name_in('PARAMETER.UTI_ID'));
Add_Parameter(pl_id,'ITEM_ID'    ,TEXT_PARAMETER, PN$Item);
Add_Parameter(pl_id,'PM$TABLE'   ,TEXT_PARAMETER, PC$Table);  
Add_Parameter(pl_id,'P_SELECT'   ,TEXT_PARAMETER, PC$Select);
Add_Parameter(pl_id,'P_FROM'     ,TEXT_PARAMETER, PC$From); 
Add_Parameter(pl_id,'P_WHERE'    ,TEXT_PARAMETER, PC$Where);
Add_Parameter(pl_id,'P_ORDERBY'  ,TEXT_PARAMETER, PC$Orderby);
Add_Parameter(pl_id,'TITRE'      ,TEXT_PARAMETER, PC$Titre);
Add_Parameter(pl_id,'AUTO_SELECT',TEXT_PARAMETER, PC$Affiche);
Add_Parameter(pl_id,'POSX'       ,TEXT_PARAMETER, PN$PosX);
Add_Parameter(pl_id,'POSY'       ,TEXT_PARAMETER, PN$PosY);

-- Appel de l'écran LOV générique --
CALL_FORM('GEN_LOV', NO_HIDE, DO_REPLACE, QUERY_ONLY, pl_id);

END;

GEN_LOV est le nom de la forme appelée
NO_HIDE indique de ne pas masquer la forme appelante
DO_REPLACE remplace le menu de la forme appelante
QUERY_ONLY place l'écran appelé en mode non modifiable
pl_id est le nom de la liste des paramètres

Au retour, elle place les valeurs sélectionnées dans les différents items définis également dans l'onglet Colonne LOV

 
Sélectionnez
------------------------------
-- Récupération des valeurs --
------------------------------
T_VALEURS := PKG_GESTION_LOV.GET_Valeurs_LOV ;
	
-- Valorisation des items de retour --
If Tab_col.first is not null Then
  For i IN Tab_col.first..Tab_col.last Loop
	  If Tab_col(i).bloc_item_retour is not null Then
	  	 Case i
	  	    When 1 Then LC$Valeur := T_VALEURS.col1 ;
	  	    When 2 Then LC$Valeur := T_VALEURS.col2 ;
	  	    When 3 Then LC$Valeur := T_VALEURS.col3 ;
	  	    When 4 Then LC$Valeur := T_VALEURS.col4 ;
	  	    When 5 Then LC$Valeur := T_VALEURS.col5 ;
	  	    When 6 Then LC$Valeur := T_VALEURS.col6 ;
	  	    When 7 Then LC$Valeur := T_VALEURS.col7 ;
	  	    When 8 Then LC$Valeur := T_VALEURS.col8 ;
	  	    When 9 Then LC$Valeur := T_VALEURS.col9 ;
	  	 End case ;

	  	 If LC$Valeur is not Null Then
	  	    -- Copie de la valeur dans l'item --
	  	    Copy( LC$Valeur, Tab_col(i).bloc_item_retour ) ;
	  	 End if ;
	  End if ;
  End loop ;
End if ;

4. L'écran de test TEST_LOV.FMB

Image non disponible

Une LOV générique a été définie sur l'item Date entrée

Pour tester la LOV et le retour des valeurs nous allons appeler la LOV depuis le champ Date entrée du premier enregistrement (CLARK)

Image non disponible

Et sélectionner la ligne correspondant à Duboudin dont nous devrions récupérer la date d'entrée

Image non disponible

Ce qui est bien le cas.

LOV de validation

Pour le cas particulier de l'utilisation des LOV génériques pour la validation des items, c'est cette fois le trigger de niveau forme WHEN-VALIDATE-ITEM qui entre en jeu

Ce trigger vérifie qu'une LOV générique est définie puis exécute la procédure Validate_Lov()

 
Sélectionnez
If Instr( Get_Item_Property( :system.trigger_item, HINT_TEXT ), '(LOVV)' ) > 0 Then
	  Validate_Lov ;
End if ;

La requête est constituée de la manière suivante :

 
Sélectionnez
-- Constitution du Select --
LC$Ordre := 'Select 1 From DUAL Where exists(Select ' ;
If Tab_col.first is not null Then
For i IN Tab_col.first..Tab_col.last Loop
	If Tab_col(i).fl_val = 'O' Then -- Colonne de validation --
		 LC$Colonne := Tab_col(i).colonne ;
		 LN$ColType := Tab_col(i).col_type ;
		 LC$Format  := Trim(Tab_col(i).format) ;  
		 LC$Ordre := LC$Ordre || Tab_col(i).colonne ;
		 exit ;
	End if ;
End loop ;
End if ;

Mise en conformité de format de la valeur à contrôler

 
Sélectionnez
  -- Valeur du champ a controler --
  LC$Champ := Name_In( Name_In( 'system.cursor_item' ) ) ;
  If LN$Coltype = 12 Then -- Type DATE --
    If LC$Format is null Then
 	LC$Champ := '''' || LC$Champ || '''' ;
    Else -- Format défini au niveau de l'item --
	forms_ddl('ALTER SESSION SET NLS_DATE_FORMAT = ''' || LC$Format || '''');
	LC$Champ := '''' || To_char( To_date( LC$Champ, 'DD/MM/YYYY HH24:MI:SS') ,LC$Format ) || '''' ;
    End if ;
  Elsif LN$Coltype In (1,96) Then -- Type CHAR --
  	LC$Champ := '''' || LC$Champ || '''' ;
  End if ;

Ajout des clauses finales

 
Sélectionnez
-- Constitution du filtre --
If LC$Where is not null Then
	LC$Filtre := ' Where ' || LC$Where ;
End if ;
IF LC$Clause is not null Then
	LC$Filtre := LC$Filtre || ' ' || LC$Clause ;
End if ;
If Instr( Upper(LC$Filtre), 'WHERE' ) > 0 Then
	LC$Filtre := LC$Filtre || ' And ' || LC$Colonne || ' = ' || LC$Champ  ;
Else
	LC$Filtre := LC$Filtre || ' Where ' || LC$Colonne || ' = ' || LC$Champ ;
End if ;
  
LC$Ordre := LC$Ordre || ' FROM ' || LC$From || LC$Filtre || ')';

Et enfin soumission à la procédure stockée PKG_GESTION_LOV.Controle_Valeur

 
Sélectionnez
  -- Test de la valeur --
  If PKG_GESTION_LOV.Controle_Valeur( LC$Ordre ) = 0 Then
  	 -- Valeur non trouvée appel de la LOV--
  	 Affiche_lov ;
  End if ;

Un retour à zéro indique qu'aucune correspondance n'est trouvée et la LOV générique est affichée

Attention. Le trigger de niveau forme WHEN-VALIDATE-ITEM ne se déclenchera qu'après un trigger identique de niveau plus bas (bloc ou item).Si vous avez défini ce type de trigger sur l'item, il sera peut-être nécessaire de définir sa propriété Ordre d'exécution à la valeur Après (After)

5. Le paquetage PKG_GESTION_LOV

Il est constitué des variables globales et fonctions publiques suivantes

 
Sélectionnez
CREATE OR REPLACE PACKAGE Pkg_Gestion_Lov
 AUTHID CURRENT_USER IS
 /*----------------------------------------*/
 /*               TYPES                    */
 /*----------------------------------------*/
  -- based-block record type
  TYPE TYPE_REC_LOV IS RECORD (
  col1          VARCHAR2(512),
  col2          VARCHAR2(512),
  col3          VARCHAR2(512),
  col4          VARCHAR2(512),
  col5          VARCHAR2(512),
  col6          VARCHAR2(512),
  col7          VARCHAR2(512),
  col8          VARCHAR2(512),
  col9          VARCHAR2(512)
  );
  -- records collection
  TYPE TYPE_TAB_LOV  IS TABLE OF TYPE_REC_LOV INDEX BY BINARY_INTEGER;

  -- return values record --
  GR_COL_LOV		  TYPE_REC_LOV ;

  -- Record type LOV --
  TYPE TYPE_COL_LOV IS RECORD (
  LOV_ID			LOV_ELEMENT_COLONNE.ID%TYPE,
  LOV_ITEM			LOV_ELEMENT_COLONNE.NOM_ITEM%TYPE,
  LOV_COD_UTIL		LOV_ELEMENT_COLONNE.UTL_ID%TYPE,
  LOV_COL_TAB		LOV_ELEMENT_COLONNE.NOM_COLONNE%TYPE,
  LOV_POS			LOV_ELEMENT_COLONNE.ORDRE%TYPE,
  LOV_POS_INIT		LOV_ELEMENT_COLONNE.ORDRE_INIT%TYPE,
  LOV_PRECEDENT		LOV_ELEMENT_COLONNE.NOM_ITEM_P%TYPE,
  LOV_SUIVANT		LOV_ELEMENT_COLONNE.NOM_ITEM_S%TYPE,
  LOV_RECH			LOV_ELEMENT_COLONNE.FL_RECH%TYPE,
  LOV_TAILLE		LOV_ELEMENT_COLONNE.TAILLE%TYPE
  );
  -- table de record type LOV --
  TYPE TYPE_TAB_COL_LOV IS TABLE OF TYPE_COL_LOV  INDEX BY BINARY_INTEGER;

  -- Durée d'attente du timer en millisecondes --
  GN$Duree_timer   NUMBER(5) := 800 ;

  -- Help screens path --
  -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --
  -- Replace with your own machine/port/virtual directory --
  -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --
  GC$Help_Path   VARCHAR2(256) := 'http://machine:port/forms90/html'  ;


   -- procedure d enregistrement des colonnes LOV --
   PROCEDURE P_Sauv_Col_LOV( PT_COL_LOV IN TYPE_TAB_COL_LOV ) ;

   -- Procedure de RAZ des valeurs de reception LOV --
   PROCEDURE RAZ_Valeurs_LOV ;

   -- Procedure de MAJ des valeurs de reception LOV --
   PROCEDURE MAJ_Valeurs_LOV( PR_COL_LOV IN TYPE_REC_LOV ) ;

   -- Fonction de recuperation des valeurs de reception LOV --
   FUNCTION GET_Valeurs_LOV RETURN TYPE_REC_LOV ;

   -- Test de l'existence d'une valeur pour la validation par LOV --
   FUNCTION Controle_valeur ( PC$Select IN VARCHAR2 ) RETURN PLS_INTEGER ;

   FUNCTION Get_Duree_Timer RETURN NUMBER ;

   FUNCTION Get_Help_Path RETURN VARCHAR2 ;

END;

Le type TYPE_TAB_LOV définit une table d'enregistrements composés de 9 champs de type Varchar2(512) qui alimentera l'écran GEN_LOV

La procédure P_Sauv_col_Lov permet d'enregistrer les préférences utilisateur

La procédure RAZ_Valeurs_Lov efface le tableau des valeurs de retour

La procédure MAJ_Valeurs_LOV renseigne le tableau des valeurs de retour

La procédure GET_Valeurs_LOV lit le tableau des valeurs de retour

La fonction Controle_Valeur permet de valider un item en vérifiant que la valeur de celui-ci appartient bien à la LOV

La fonction Get_Duree_Timer permet à l'écran GEN_LOV de récupérer le temps d'attente en millisecondes pour le timer.( Vous pouvez donc régler ce délai en fonction de votre environnement dans les spécifications du package sans intervenir dans l'écran GEN_LOV)

La fonction Get_Help_Path permet à l'écran GEN_LOV de récupérer le chemin d'accès aux fichiers d'aide en ligne

6. Liste et mise en place du matériel fourni

Copier et décompresser le fichierforms_lov.zip (790 Ko) dans un répertoire de votre station de travail


!!! Lisez le fichier install.htm !!!

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Cet article s'applique à la version 9i et 10g d'Oracle Forms