Comparaison des versions

Légende

  • Ces lignes ont été ajoutées. Ce mot a été ajouté.
  • Ces lignes ont été supprimées. Ce mot a été supprimé.
  • La mise en forme a été modifiée.

Sommaire


...

Version Anglaise / English version

Une version anglaise de cette FAQ existe à l'adresse suivante : https://portal.hardis-group.com/x/-wkbIQ

An english version of this FAQ exists à the following address : https://portal.hardis-group.com/x/-wkbIQ


...

Aide

pour accéder à l'aide en ligne adelia, on peu accéder à l'aide d'un navigateur à l'adresse suivante : 

...

Plus précisément on pourra accéder directement aux :

...

Bloc de code
languageadelia
/* ___ Déclarations des variables _______________________________________________________ 
REF(A5_COD_ARTICLE) 			  w_COD_ARTICLE_1 										/* définir la variable w_COD_ARTICLE_1 de la même façon que la propriété A5_COD_ARTICLE
REF(A5_COD_ARTICLE HL_ART_ALCOOL) w_COD_ARTICLE_2 										/* définir la variable w_COD_ARTICLE_2 de la même façon que la propriété A5_COD_ARTICLE de l'entité HL_ART_ALCOOL
REF(w_COD_ARTICLE_2)			  w_COD_ARTICLE_3 										/* définir la variable w_COD_ARTICLE_3 de la même façon que la variable variable w_COD_ARTICLE_2 

/* ___ Déclarations des listes __________________________________________________________
LISTE LST_ART_ALC_1  *REF_MLD(HL_ART_ALCOOL)											/* définir une liste avec toutes les propriétés de l'entité HL_ART_ALCOOL
LISTE LST_ART_ALC_2  *REF_MLD(HL_ART_ALCOOL) *REF_MLD(HL_ART_LANGUE) 					/* définir une liste avec toutes les propriétés des entités HL_ART_ALCOOL et HL_ART_LANGUE
LISTE LST_ART_ALC_3  *REF_MLD(HL_ART_ALCOOL) *REF_MLD(HL_ART_LANGUE) w_COD_ARTICLE_1	/* définir une liste avec toutes les propriétés des entités HL_ART_ALCOOL et HL_ART_LANGUE et également la variable w_COD_ARTICLE_1

...

La taille de la variable peut auss aussi indiquée en :

  • kilobytes (* 1024) en ajoutant le suffixe "K" à la valeur (jusqu'à 8189K), ou bien
  • megabytes (* 1048576) en ajoutant le suffixe "M" à la valeur (jusqu'à 7M)

...

La taille totale de la variable numérique doit être comprise entre 1 et 63 .
La taille correspond au nombre total de chiffres (décimales comprises).
La valeur décimale est inclue incluse dans le nombre total de chiffres.
Comme le nombre de décimales est inclue inclus dans le nombre total de chiffre, le nombre de décimales sera inférieur ou égal au nombre total de chiffres.

...

1 - Définition

Pour définir a new une nouvelle constante, il suffiit d'aller dans menu Référentiel de l'éditeur L4G, séléctionner la ligne de menu Dictionnaire des constantes (ou bien d'appuyer sur F9).

...

Bloc de code
/* ___ Déclarations _____________________________________________________________________
NUM_E( 3,0) x 
NUM_E( 3,0) y 

/* ___ Code _____________________________________________________________________________
x  = 2 / 3                          /* x contiendra 0
y H= 2 / 3                          /* y contiendra 1

2 - Calcul du reste

To retrieves the remainder in a mathematical division we can use the remainder instruction. 
The instruction remainder must be placed immediately after the arithmetical expression of the Pour récupérer le reste d'une division, on peut utiliser l'ordre L4G reste
Cette ordre L4G doit être utilisé immédiatement après l'ordre de division.

Astuce
titleTip :

The Modulo predefined function can now be used instead of the remainder instruction La Fonction prédéfinie Modulo peut maintenant être utilisée à la place de l'instruction L4G reste !


Bloc de code
/* ___ DeclarationsDéclarations _____________________________________________________________________
NUM_E( 3,0) x 
NUM_E( 3,0) y 

/* ___ Code _____________________________________________________________________________
x  = 10 / 3                         /* x willcontiendra la containvaleur 3
remainderreste y                             /* y willcontiendra la containvaleur 1

3 - Calcul du Modulo

...


Pour calculer le modulo entre un numérateur et un dénominateur, on peut maintenant utiliser la fonction prédéfinie &modulo.
Cette fonction prédéfinie peut être utiilisée à la place lde l'instruction L4G reste.

...

To calculate the modulo between a numerator and its divisor we can use the &modulo predefined function .
This predefined function can be used instead of the remainder instruction. 


Bloc de code
/* ___ DeclarationsDéclarations _____________________________________________________________________
NUM_E( 3,0) x 
NUM_E( 3,0) y 

/* ___ Code _____________________________________________________________________________
x  = 10                          /* x willcontiendra la containvaleur 3
y  = &modulo(x;3)                /* y contiendra willla containvaleur 1


...

Squellette Adelia

...

1 - Programmes Visual

...

A visual program is constituted with a number of paragraph Un programme visual est constitué d'un certain nombre de paragraphes

  • DECL PGM. In this paragraph, we declare the global variables (or parameters, lists, cursors etc) of the programDans ce paragraphe, on déclare les variables globales (ou paramètres, listes, curseurs etc) du programme,
  • INIT PGM. This is the entry point of the program,
  • WIN DECLARATION . In this paragraph, we declare the variables (lists, cursors etc) only accessible from within the window paragraphs (Initialisation, Verification, Validation, Events),
  • WIN EVENTS . In those paragraph we will code what happens when a event is triggered for an object ,
  • INITIALIZATION . In this paragraph, we will add code to load data before displaying the window ,
  • VERIFICATION . In this paragraph, we will add code to verify the data entered in the window by a user,
  • VALIDATION . In this paragraph, we will add code to store the data in the database after verification .
  • PROCEDURES . Procedures can be added to do repetitive tasks or to cut the other paragraphs in more readable parts.
  • C'est le point d'entrée du programme,
  • FENETRE - DECLARATION. Dans ce paragraphe, on déclare les variables (listes, curseurs etc) accessibles seulement depuis les différents paragraphes de la fenêtre (Initialisation, Vérification, Validation, Evénements),
  • FENETRE - EVENEMENTS. Dans ce paragraphe on écrira le code correspondant à chaque événement qui pourra être déclenché sur un objet,
  • INITIALISATION. Dans ce paragraphe on écrira le code qui charge les données avant d'afficher la fenêtre,
  • VERIFICATION. Dans ce paragraphe on écrira le code qui vérifie les données saisies dans la fenêtre par un utilisateur,
  • VALIDATION . Dans ce paragraphe on écrira le code qui écrit les données dans la base après vérification.
  • PROCEDURES . Des procedures peuvent être créées pour effectuer des actions répétivies ou bien pour rendre le code plus modulaire et lisible.

Un squelette typique de code pourrait être A typical simple framework code would be the following :

Bloc de code
/* ___ DeclarationsDéclarations _____________________________________________________________________
DECL_PGM
   /* globalvariables variablesglobales, DS, listslistes, cursorscurseurs, parameters declarationsdéclarations de paramètres du programme

INIT_PGM
   INITIALIZEINITIALIER WIN_2205			/* callappeler thele paragraphparagraphe tode loadchargement thedes datadonnées
   EXECUTE EXECUTER   WIN_2205          /* showafficher thela windowfenêtre to the userà l'utilisateur

WIN_2205
   DECLARATION
      /* windowvariables variableslocales, DS, listslistes, cursors, parameters declarationscurseurs
   INITIALIZATIONINITIALISATION
      /* code toà executeexécuter beforeavant displayingd'afficher thela windowfenêtre
   WORK_WITH_EVENTSOBJETS
     OBJECTSEVENEMENTS_EVENTSOBJETS...
     BTN_VALIDATE
        LeftButtonClickBoutonGaucheClic
           VERIFY VERIFIER               /* callappeler le theparagraphe verificationde paragraphvérification
           VALIDER VALIDATE              /* appeler le callparagraphe thede validation
 paragraph
          TERMINER TERMINATE             /* fermer endla thefenêtre windowen process
cours (aller à VERIFICATION
l'odre suivant l'ordre INITIALISER)
   /* code to verify the data entered in the window by a userVERIFICATION
      /* code qui vérifie les données saisies par l'utilisateur
      SENDENVOYER_MSG *CLR_ALL        EFFACER_TOUT  /* cleareffacer theles errormessages messagesd'erreur
      ifsi [errorConditionconditionErreur forpour objectl'objet ZZ_JLP]
         preparepreparer_msg hl21734 ZZ_JLP
         init_msg ZZ_JLP
         anomalyanomalie      
      endfin
      ...
   VALIDATION
      /* code to store the data in the database after verification pour mettre à jour la base de données après la vérification des données saisies par l'utilisateur
      UPDMAJ_SQL orou CREATECREER_SQL orou ...

...


...

Procédures

1 -

...

Définition

Une procédure est un bloc de code appelable depuis un bloc du programme ou bien depuis l'exterieur du programme si la procédure est publique

...

A procedure is a block of code we can call from inside a program or from outside a program if the procedure is public.

2 -

...

Paramètres

3 -

...

Appeler une procédure 

...


...

Chaînes de caractère

1 -

...

Concaténer des variables

...

alphanumeriques

Pour concatener deux variables alphanumériques (ou plus) on utilisera les opérateurs // ou To concatenate two (or more variables) you can use the // or /// operator .

  • // est un opérateur qui va concaténer le contenu exact des deux variables (la taille exacte de l'opérande de gauche sera concaténée à la taille exacte de l'opérande de droite)
  • /// est un opérateur qui va éliminer les blancs qui sont en partie droite de l'opérande de gauche operator will exactly concatenate the two variables (lenght of left operator exactly concatenated to lenght of right operator)/// operator will eliminate the blanks on the right part of the left operator.


Bloc de code
/* ___ DeclarationsDéclarations _____________________________________________________________________
ALPHA( 10) wLeft 
ALPHA( 10) wRight
ALPHA( 20) wText1 
ALPHA( 20) wText2 
ALPHA( 20) wText3 

/* ___ Code _____________________________________________________________________________
wLeft  = 'Hello'
wRight = 'World' 
wText1 = wLeft //  wRight						/* wText1 = 'Hello     World     '
wText2 = wLeft /// wRight						/* wText2 = 'HelloWorld          '
wText3 = wLeft /// ' ' // wRight				/* wText3 = 'Hello World         '

2 -

...

Connaître la taille d'une chaîne de caractères

Pour connaître la taille d'une chaîne de caractères, il suffit d'utiliser la fonction prédéfinie &LONGUEUR_CHAINE

...

In order to split a string into different strings (to a list of strings in reality) according to a separator, you simply have to use the  SPLIT_STRING instruction :

Bloc de code
/* ___ DeclarationsDéclarations _____________________________________________________________________
alpha(num_bin_2  50) elementDay
list        lst_days elementDay stringLength
alpha(1000100) myDays myString

/* ___ Code _____________________________________________________________________________
myDaysmyString      = 'Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday'
split_string myDays ';' lst_days
	/* the list "lst_days" will contain 7 elements : 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'

3 - How to replace a part of a string

alpha beta'  
stringLength  = &longueur_chaine(myString)
    /* stringLength a pour valeur 10

3 - Découper une chaine de caractères par rapport à un séparateur

Afin de découper une chaine de caractères en différentes chaînes (en une liste de chaines en réalité) par rapport à un séparateur, il suffit d'utiliser l'instruction SCINDER_CHAINE In order to replace a substring in a string, you simply have to use the  SCAN_REPLACE  instruction :

Bloc de code
/* ___ DeclarationsDéclarations _____________________________________________________________________
alpha(1000  50) myDays
alpha(1000) myDaysModified
alpha(  56) mySearchString
alpha(  78) myReplacementStringelementDay
liste       lst_days elementDay
alpha(1000) myDays

/* ___ Code _____________________________________________________________________________
myDays              = 'Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday' 
mySearchStringscinder_chaine  myDays    = ';'
myReplacementString =lst_days ' , '	
myDaysModified    /* la = *blank
scan_replace myDays mySearchString myReplacementString myDaysModified
	/* the string myDaysModified will contain 'Sunday , Monday , Tuesday , Wednesday , Thursday , Friday , Saturday'

4 - How to add a "carriage return" in a string in order to have a return to the line in a screen.

liste "lst_days" contiendra 7 éléments : 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'

4 - Remplacer une partie de chaine de caractères

Afin de remplacer une partie de chaine de caractères, il suffit d'utiliser l'instruction RECH_REMPLACER :In order to add a "return" to an alphanumerical variable, you should create a "CR" (carriage return) + "LF" (line feed) string and add it to your alphanumerical variable.

Bloc de code
/* ___ DeclarationsDéclarations _____________________________________________________________________
ALPHAalpha(  11000) wCR myDays
ALPHAalpha(  11000) wLF myDaysModified
ALPHAalpha(  256) wCRLF mySearchString
ALPHAalpha(100  78) wText myReplacementString

/* ___ Code _____________________________________________________________________________
wCRmyDays = &CHAR_CONVERSION('0D') 
wLF = &CHAR_CONVERSION('0A') 
wCRLF =   wCR // wLF 
wText = 'Hello' /// wCRLF /// 'world'

z_display = wText 

The multi-line property of the text object should be checked if you want to see the line return.

Image Removed

Date, Time and Timestamp

1 - Calculating dates, time and timestamp values

In order to calculate Date, Time and Timestamps, we can use the following functions

  • &Calculate_Date
  • &Calculate_Time
  • &Calculate_Timestamp
Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday'
mySearchString      = ';'
myReplacementString = ' , '
myDaysModified      = *blank
rech_replacer myDays mySearchString myReplacementString myDaysModified
	/* la chaine myDaysModified contiendra 'Sunday , Monday , Tuesday , Wednesday , Thursday , Friday , Saturday'

5 - Ajouter un "retour chariot" dans une chaine de manière à avoir un retour à la ligne dans un champs d'un écran.

Afin d'ajouter un "retour" à une variable alphanumerique, il faudra créer une chaine alpha contenant le caractère "CR" (carriage return) et le caractère "LF" (line feed).

Bloc de code
/* ___ Déclarations 
Bloc de code
/* ___ Declarations _____________________________________________________________________
date_____
ALPHA(  1) wCR  
ALPHA(   myDate
date        myNewDate
time_t      MyTime
time_t      MyNewTime
timestamp   MyTimestamp
timestamp   MyNewTimestamp
1) wLF 
ALPHA(  2) wCRLF 
ALPHA(100) wText 

/* ___ Code _____________________________________________________________________________
myNewDatewCR = &calculateCONVERSION_dateCAR(myDate;1;'Y0D')                   /* add 1 Year to myDate
myNewDate
wLF = &calculateCONVERSION_dateCAR(myDate;-6;'M0A') 
wCRLF = wCR // wLF 
wText = 'Hello' /// wCRLF /// 'world'

z_display = wText 

La propriété Multiligne de l'objet texte devra être cochée si vous voulez pouvoir voir le retour à l'écran.

Image Added


...

Date, Time et Timestamp

1 - Effectuer des calculs sur des type date, time et timestamp

Afin d'effectuer des calculs sur des types Date, Time ou Timestamps, on utilisera les fonctions prédéfinies suivantes :

  • &Calcul_Date
  • &Calcul_Heure
  • &Calcul_Timestp


Bloc de code
/* ___ Déclarations _____________________________________________________________________
date      /* substract 6 Months to myDate
myNewDate = &calculate_date(myDate;40;'D')                  /* add 40 Days to myDate

myNewTime = &calculate_time(myTime;1;'H')      myDate
date        myNewDate
time     /* add 1 Hours to myTime
myNewTime = &calculate_time(myTime;-6;'M')MyTime
time        MyNewTime
timestamp   MyTimestamp
timestamp       MyNewTimestamp

/* substract___ 6 Minutes to myTime
myNewTimeCode _____________________________________________________________________________
myNewDate = &calculatecalcul_timedate(myTimemyDate;401;'SY')                      /* addajouter 401 Secondsannée toà myTimemyDate

myNewTimestampmyNewDate = &calculatecalcul_tmsdate(myTimestampmyDate;1-6;'Y M')         /* add 1 Year to myTimestamp
myNewTimestamp = &calculate_tms(myTimestamp;-6;'M ')        /* substract 6 Months myTimestamp
myNewTimestamp = &calculate_tms(myTimestamp            /* soustraire 6 mois à myDate
myNewDate = &calcul_date(myDate;40;'D ')                     /* addajouter 40 Daysjours toà myTimestampmyDate

myNewTimestampmyNewTime = &calculatecalcul_tmsheure(myTimestampmyTime;1;'H ')                     /* addajouter 1 Hoursheure toà myTimestampmyTime
myNewTimestampmyNewTime = &calculatecalcul_tmsheure(myTimestampmyTime;-6;'MIM')                    /* substractsoustraire 6 Minutesminutes toà myTimestampmyTime
myNewTimestampmyNewTime = &calculatecalcul_tmsheure(myTimestampmyTime;40;'S ')        /*   add 40 Seconds to myTimestamp
myNewTimestamp = &calculate_tms    /* ajouter 40 secondes à myTime

myNewTimestamp = &calcul_timestp(myTimestamp;-301;'MSY ')        /* substractajouter 301 Secondsannée to myTimestamp

2 - Calculating intervals between dates, time and timestamp values

In order to calculate intervals between Dates, Times and Timestamps, we can use the following functions

  • &Date_Interval
  • &Time_Interval
  • &Timestamp_Interval
Bloc de code
/* ___ Declarations _____________________________________________________________________
date à myTimestamp
myNewTimestamp = &calcul_timestp(myTimestamp;-6;'M ')       /* soustraire 6 mois à myTimestamp
myNewTimestamp = &calcul_timestp(myTimestamp;40;'D ')       myDate1
date/* ajouter 40 jours à myTimestamp
myNewTimestamp   myDate2
time_t  = &calcul_timestp(myTimestamp;1;'H ')    myTime1
time_t    /* ajouter myTime2
timestamp1 heure à myTimestamp1myTimestamp
timestampmyNewTimestamp   myTimestamp2
num_e(9,0)  myInterval1
num_e(9,0)  myInterval2
num_e(15,0) myInterval3

/* ___ Code _____________________________________________________________________________
myInterval1 = &date_interval(myDate1;myDate2= &calcul_timestp(myTimestamp;-6;'MI')       /* soustraire 6 minutes à myTimestamp
myNewTimestamp = &calcul_timestp(myTimestamp;40;'S ')       /* ajouter 40 secondes à myTimestamp
myNewTimestamp    /* number of days between myDate1 and myDate2 (can be a negative number if myDate1 if greater than myDate2)
myInterval2 = &time_interval(myTime1;myTime2= &calcul_timestp(myTimestamp;-30;'MS')      /* substraire 30 secondes à myTimestamp

2 - Calculer des intervales entre des types dates, time et timestamp

Afin de calculer des intervales entre des variables de type Date, Time and Timestamp, on utilisera les fonctions prédéfinies suivantes :

  • &Ecart_Dates
  • &Ecart_Heures
  • &Ecart_Timestps


Bloc de code
/* ___ Déclarations _____________________________________________________________________
date        myDate1
date        myDate2
time        myTime1
time        myTime2
timestamp   myTimestamp1
timestamp   myTimestamp2
num_e(9,0)  myInterval1
num_e(9,0)  myInterval2
num_e(15,0) myInterval3

/* ___ Code _____________________________________________________________________________
myInterval1 = &ecart_dates(myDate1;myDate2)                   /* nombre de jours entre myDate1 et myDate2 (la valeur peut être négative si myDate1 est plus grand que myDate2)
myInterval2 = &ecart_heures(myTime1;myTime2)                  /* nombre de secondes entre myTime1 et myTime2 (la valeur peut être négative si myTime1 est plus grand que myTime2)

      /* number of seconds between myTime1 and myTime2 (can be a negative number if myTime1 if greater than myTime2)

myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'Y ')   /* number of years between myTimestamp1 and myTimestamp2 (can be a negative number if myTimestamp1 if greater than myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'M ')   /* number of months between myTimestamp1 and myTimestamp2 (can be a negative number if myTimestamp1 if greater than myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'D ')   /* number of days between myTimestamp1 and myTimestamp2 (can be a negative number if myTimestamp1 if greater than myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'H ')   /* number of hours between myTimestamp1 and myTimestamp2 (can be a negative number if myTimestamp1 if greater than myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'MI')   /* number of minutes between myTimestamp1 and myTimestamp2 (can be a negative number if myTimestamp1 if greater than myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'SY ')   /* numbernombre ofd'années secondsentre between myTimestamp1 andet myTimestamp2 (canla bevaleur apeut negativeêtre numbernégative ifsi myTimestamp1 ifest plus greatergrand thanque myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'MSM ')   /* numbernombre ofde microsecondsmonths betweenentre myTimestamp1 andet myTimestamp2 (canla bevaleur apeut negativeêtre numbernégative ifsi myTimestamp1 ifest plus greatergrand thanque myTimestamp2)

Image

1 - Transforming an alpha variable to an image variable

If an image variable should contains a text, it is possible to transform the content of an alpha variable to an image variable in the following way : 

Bloc de code
/* ___ Declarations _____________________________________________________________________
alpha( 100) fileAlias
alpha(  10) fileMode
alpha(5000) myAlpha
image       myImage
num_bin_4   nb4ReturnCode

/* ___ Code _____________________________________________________________________________
myAlpha   = 'my text to be transformed to an image variable (2205)
fileAlias = 'myTransformation'
fileMode  = 'w'

load_dll   'VATOOLBX.DLL'
call_dll   'VATOOLBX.DLL' 'VaToolBxOpenFile' fileAlias myImage fileMode nb4ReturnCode
call_dll   'VATOOLBX.DLL' 'VaToolBxWriteString' fileAlias myAlpha nb4ReturnCode
call_dll   'VATOOLBX.DLL' 'VaToolBxCloseFile' fileAlias nb4ReturnCode
unload_dll 'VATOOLBX.DLL'

/* the myImage variable now contains the alpha text from the myAlpha variable.

2 - Transforming a image variable to an alpha variable 

If an Image variable contains only text, it is possible to transform the Image variable to an alpha variable with the following code :

myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'D ')   /* nombre de jours entre myTimestamp1 et myTimestamp2 (la valeur peut être négative si myTimestamp1 est plus grand que myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'H ')   /* nombre d'heures entre myTimestamp1 et myTimestamp2 (la valeur peut être négative si myTimestamp1 est plus grand que myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'MI')   /* nombre de minutes entre myTimestamp1 et myTimestamp2 (la valeur peut être négative si myTimestamp1 est plus grand que myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'S ')   /* nombre de secondes entre myTimestamp1 et myTimestamp2 (la valeur peut être négative si myTimestamp1 est plus grand que myTimestamp2)
myInterval3 = &tms_interval(myTimestamp1;myTimestamp2;'MS')   /* nombre de microsecondes entre myTimestamp1 et myTimestamp2 (la valeur peut être négative si myTimestamp1 est plus grand que myTimestamp2)

3 - Extraire des informations d'une variable de type Date

Afin d'extraire des informations d'une variable de type Date, on utilisera les fonctions prédéfinies suivantes :

  • &Date_Annee
  • &Date_Mois
  • &Date_Jour
  • &Date_Num


Bloc de code
/* ___ DeclarationsDéclarations _____________________________________________________________________
alpha( 100) fileAlias
alpha(  10) fileModedate        myDate
num_bin_4e(4,0)   fileSize
alpha(5000) myAlpha
image       myImage

num_bin_4   nb4ReturnCodemyYear
num_e(2,0)  myMonth
num_e(2,0)  myDay
num_e(8,0)  myDateNum

/* ___ Code _____________________________________________________________________________
fileAlias = 'myTransformation'
fileModemyYear   = 't'
fileSize  = 5000

load_dll&date_annee(myDate)     'VATOOLBX.DLL'
call_dll   'VATOOLBX.DLL' 'VaToolBxOpenFile' fileAlias myImage fileMode nb4ReturnCode
call_dll   'VATOOLBX.DLL' 'VaToolBxWriteString' fileAlias myAlpha nb4ReturnCode
call_dll   'VATOOLBX.DLL' 'VaToolBxReadFile' fileAlias myAlpha fileSize nb4ReturnCode
call_dll /* extrait 'VATOOLBX.DLL' 'VaToolBxCloseFile' fileAlias nb4ReturnCode
unload_dll 'VATOOLBX.DLL'

/* the myAlpha variable now contains the alpha text from the myImage variable.
/* the fileSize contains the real number of characters from the image variable.

Lists

1 - Declarations

A list can be declared with variables , or in reference to a logical entity , or in reference to another list , or a combination of those elements .

Bloc de code
/* ___ Lists declarations _______________________________________________________________
LIST LST_EXAMPLE    ELT_ONE ELT_TWO ELT_2205											/* defining a list with single elements defined previously, here ELT_ONE, ELT_TWO and ELT_2205 variables
LIST LST_ART_ALC_2  *REF_LDM(HL_ART_ALCOOL)												/* defining a list with all the properties of the HL_ART_ALCOOL ldm
LIST LST_ART_ALC_3  *REF_LDM(HL_ART_ALCOOL) *REF_LDM(HL_ART_LANGUE) 					/* defining a list with all the properties of the HL_ART_ALCOOL ldm and the HL_ART_LANGUE ldm
LIST LST_ART_ALC_4  *REF_LDM(HL_ART_ALCOOL) *REF_LDM(HL_ART_LANGUE) w_COD_ARTICLE_1		/* defining a list with all the properties of the HL_ART_ALCOOL ldm and the HL_ART_LANGUE ldm plus the w_COD_ARTICLE_1 variable
LIST LST_ART_ALC_5  *REF_L(LST_ART_ALC_4) ELT_2205		                           		/* defining a list with all the properties of the LST_ART_ALC_4 list plus the ELT_2205 variable

2 - List usage

1 - Add elements

A list is a structured object in memory with columns, it's like a table but in memory.

...

l'année de la date myDate (l'année sera au format SSAA)  
myMonth     = &date_mois(myDate)                              /* extrait le mois de la date myDate
myDay       = &date_jour(myDate)                              /* extrait le jour de la date myDate 
myDateNum   = &date_to_num(myDate)                            /* convertit la date myDate au format numérique (format SSAAMMJJ) 


...

Image

1 - Transformer une variable alpha en variable image

Il est possible de transformer le contenu d'une variable de type alphanumérique en type image de la façon suivante : 

Bloc de code
/* ___ Déclarations _____________________________________________________________________
alpha( 100) fileAlias
alpha(  10) fileMode
alpha(5000) myAlpha
image       myImage
num_bin_4   nb4ReturnCode

/* ___ Code _____________________________________

...

Elements are by default added at the end of the list (*END), but the also can be added 

  • at the beginning of the list (INSERT_ELT *BEGIN)
  • at the end of the list (INSERT_ELT *END)
  • before the current element (INSERT_ELT *BEFORE)
  • after the current element (INSERT_ELT *AFTER)
  • in the sort order of one (or more) column(s) (INSERT_ELT *SORT(...) )

By default, lines inserted in the list are not considered as modified, but we can tag them as modified when inserted if we want to retrieve later the modified elements. To do this, we can add the *CHANGE tag during the insertion.

Bloc de code
/* ___ Lists usage _______________________________________________________________
ELT_ONEmyAlpha   = 1
ELT_TWO  = 2
ELT_2205 = 2205
INSERT_ELT LST_EXAMPLE 

INSERT_ELT LST_EXAMPLE *BEGIN										/* to insert an element in the list at the start of the list 
INSERT_ELT LST_EXAMPLE *END											/* to insert an element in the list at the end of the list (as it is the default value, it can be omitted)
INSERT_ELT LST_EXAMPLE *BEFORE  									/* to insert an element in the list before the current element
INSERT_ELT LST_EXAMPLE *AFTER  										/* to insert an element in the list after the current element
INSERT_ELT LST_EXAMPLE *SORT(ELT_2205 *DESC, ELT_TWO *ASC)			/* to insert an element in the list sorted by ELT_2205 descending, then ELT_TWO ascending (*ASC is default so it can be omitted)

INSERT_ELT LST_EXAMPLE *CHANGE										/* to insert an element AND make it a changed element (could be retrieved by a READ_LST LST_EXAMPLE *CHANGE ... END_READ_LST

2 - Parse a list

In order to parse a list , we can use the READ_LST loop. 

'my text to be transformed to an image variable (2205)
fileAlias = 'myTransformation'
fileMode  = 'w'

charger_dll   'VATOOLBX.DLL'
appeler_dll   'VATOOLBX.DLL' 'VaToolBxOpenFile' fileAlias myImage fileMode nb4ReturnCode
appeler_dll   'VATOOLBX.DLL' 'VaToolBxWriteString' fileAlias myAlpha nb4ReturnCode
appeler_dll   'VATOOLBX.DLL' 'VaToolBxCloseFile' fileAlias nb4ReturnCode
decharger_dll 'VATOOLBX.DLL'

/* la variable myImage contient le texte initialement contenu dans la variable myAlpha.

2 - Transformer une variable image en variable alpha

Si une variable de type Image contient seulement du texte, il est possible de transformer la variable de type Image en type alpha de la façon suivante :

Bloc de code
/* ___ Déclarations _____________________________________________________________________
alpha( 100) fileAlias
alpha(  10) fileMode
num_bin_4   fileSize
alpha(5000) myAlpha
image       myImage

num_bin_4   nb4ReturnCode

/* ___ Code _____________________________________________________________________________
fileAlias = 'myTransformation'
fileMode  = 't'
fileSize  = 5000  

charger_dll   'VATOOLBX.DLL' 
appeler_dll   'VATOOLBX.DLL' 'VaToolBxOpenFile'    fileAlias myImage fileMode nb4ReturnCode 
appeler_dll   'VATOOLBX.DLL' 'VaToolBxReadFile'    fileAlias myAlpha fileSize nb4ReturnCode 
appeler_dll   'VATOOLBX.DLL' 'VaToolBxCloseFile'   fileAlias                  nb4ReturnCode
decharger_dll 'VATOOLBX.DLL'

/* la variable myAlpha contient le texte alpha initialement contenu dans la variable myImage.
/* la variable fileSize contient le nombre de caractères lu de la variable myImage.


...

Listes

1 - Déclarations

Une liste peut être declarée avec des variables , en référence à une entité logique , en reference à une autre liste , ou encore une combination de ces éléments .Inside a parsing loop we are on one element and we can modify it (with CHANGE_ELT) or delete it (with DELETE_ELT)

Bloc de code
/* ___ ListsDéclarations de usagelistes _______________________________________________________________
READ_LST LST_EXAMPLE 

  /* 
LISTE LST_EXAMPLE    ELT_ONE is filled with the value of the first line on the first iteration of the list, same forELT_TWO ELT_2205											/* définir une liste avec des éléments simples définis auparavant, ici les variables ELT_ONE, ELT_TWO andet ELT_2205
LISTE  ...
  IF ...
    DELETE_ELT LST_EXAMPLELST_ART_ALC_2  *REF_MLD(HL_ART_ALCOOL)											/* définir weune canliste deleteavec thetoutes currentles elementpropriétés 
de  END
  IF ...
    ELT_ONE = ELT_ONE + 1
    CHANGE_ELT LST_EXAMPLEl'entité HL_ART_ALCOOL
LISTE LST_ART_ALC_3  *REF_MLD(HL_ART_ALCOOL) *REF_MLD(HL_ART_LANGUE) 						/* wedéfinir une canliste changeavec thetoutes valuesles ofpropriétés thedes current element if we modify one (or more) of his columns
    CHANGE_ELT LST_EXAMPLE	*SELECT				/* when changing an element we can add the tag SELECTED or UNSELECTED to the element
  END 
END_READ_LST

/* ___ We can parse for a graphical list the elements selected by the user ______
READ_LST LST_GRAPHICAL *SELECT
	...
END_READ_LST

/* ___ We can parse for a graphical list the elements modified by the user or by a program if it sets the *CHANGE tag during the insertion ___
READ_LST LST_GRAPHICAL *CHANGE
	...
END_READ_LSTentités HL_ART_ALCOOL et HL_ART_LANGUE
LISTE LST_ART_ALC_4  *REF_MLD(HL_ART_ALCOOL) *REF_MLD(HL_ART_LANGUE) w_COD_ARTICLE_1	/* définir une liste avec toutes les propriétés des entités HL_ART_ALCOOL et HL_ART_LANGUE, plus la variable w_COD_ARTICLE_1
LISTE LST_ART_ALC_5  *REF_L(LST_ART_ALC_4) ELT_2205		                           		/* définir une liste avec toutes les propiétés de la liste LST_ART_ALC_4, plus la variable ELT_2205

2 - Utilisation des listes

1 - Ajouter des éléments

Une liste est un objet mémoire structuré composé de colonnes, c'est similaire à une table, mais en mémoire.

Pour insérer des données dans une liste, il suffit de renseigner la valeur des variables colonnes de la liste, puis d'ajouter un élément à la list avec l'ordre L4G INSERER_ELT

Les éléments sont par défaut ajoutés à la fin de la liste (*FIN), mais on peut aussi les ajouter ...

  • au début de la liste (INSERER_ELT *DEBUT)
  • à la fin de la liste (INSERER_ELT *FIN)
  • avant l'élément courant (INSERER_ELT *AVANT)
  • après l'élément courant (INSERER_ELT *APRES)
  • trié suivant une (ou plusieurs) colonne(s) (INSERER_ELT *TRI(...) )

Par default, les lignes insérées dans la liste ne sont pas considérées comme modifiées, mais on peut les indiquer comme modifées au moment de l'insertion si on veut retrouver plus tard ces éléments modifiés. Pour ce faire, il suffit d'ajouter *MODIF à l'ordre INSERER_ELTWe can also use more manual loop with READ_F_ELT (read first element) and READ_NX_ELT (read next element).We can also use READ_L_ELT (read last element) and READ_PR_ELT (read previous element).

Bloc de code
/* ___ Lists usageListes - exemples d'utilisation ___________________________________________
ELT_ONE  = 1
ELT___________________
READ_FTWO  = 2
ELT_2205 = 2205
INSERER_ELT LST_EXAMPLE 	

INSERER_ELT LST_EXAMPLE *DEBUT										/* wepour tryinsérer toun readélément theau firstdébut elementde of the list (if it exists)
DO_WHILE &CODE_LST(la liste
INSERER_ELT LST_EXAMPLE) = *NORMAL*FIN										/* did the last operation on the list end successfully ?
  ...
  READ_NX pour insérer un élément à la fin de la liste (comme c'est la valeur par défaut *FIN peut être omis)
INSERER_ELT LST_EXAMPLE *AVANT  									/* trypour toinsérer readun theélément nextdans elementla ofliste the list
REDO

READ_L_avant l'élément courant
INSERER_ELT LST_EXAMPLE *APRES  									/* wepour tryinsérer toun readélément thedans lastla elementliste ofaprès the list (if it exists)
DO_WHILE &CODE_LST(LST_EXAMPLE) = *NORMALl'élément courant
INSERER_ELT LST_EXAMPLE *TRI(ELT_2205 *DESC, ELT_TWO *ASC)			/* didpour theinsérer lastun operationélément ondans thela listliste endtrié successfully ?
  ...
  READ_PR_ELT LST_EXAMPLE						/* try to read the next element of the list
REDO

3 - Parse a list using indexes

...

par ELT_2205 descendant, puis ELT_TWO ascendant (*ASC est la valeur défaut, peut être omis)

INSERER_ELT LST_EXAMPLE *MODIF										/* pour insérer un élément dans la liste ET en faire initialement un élément modifié (qui pourra être relu par LECTURE_LST LST_EXAMPLE *MODIF ...)

2 - Parcourir une liste

Afin de parcourir une liste, on pourra utiliser la boucle LECTURE_LST ... FIN_LECTURE_LST

Dans la boucle de parcours d'une liste on est positionné sur un élément et on peut modifier (avec MODIFIER_ELT) ou supprimer (avec SUPPRIMER_ELT) l'élément courant.

Bloc de code
/* ___ Liste - utilisations _

...

Bloc de code
/* ___ Lists declarations _______________________________________________________________
LIST       __ 
LECTURE_LST LST_EXAMPLE 

  /* ELT_ONE ELT_TWO ELT_2205		/* defining a list with single elements defined previously, herecontient la valeur de la première ligne de la liste (pour la colonne ELT_ONE), de même pour ELT_TWO andet ELT_2205 variables
LIST_INDEX MY_INDEX
  ...
  SI ...
    SUPPRIMER_ELT LST_EXAMPLE ELT_2205					/* on peut supprimer /* we define the MY_INDEX index that will index the LST_EXAMPLE list on the ELT_2205 column

/* ___ Lists usage _______________________________________________________________
ELT_2205 = 67											/* we set the value we want to reach in the list
READ_ELT MY_INDEX 										/* we try to read the first element of the list with the value 67 in the column ELT_2205
IF &CODE_LST(MY_INDEX) = *NORMAL						/* did the find the element with the searched value ?
  ...													/* if yes, then we are on the element, we can use it, modify it or delete it.
END

ELT_2205 = 67
READ_F_ELT MY_INDEX 									/* reads the first element that is greater or equal to the column value of the index
DO_WHILE &CODE_LST(MY_INDEX) = *NORMAL
  ...
  READ_NX_ELT MY_INDEX
REDO

DELETE_INDEX MY_INDEX		l'élément courant
  FIB
  SI ...
    ELT_ONE = ELT_ONE + 1
    MODIFIER_ELT LST_EXAMPLE					/* on peut modifier les valeurs de l'élément courant en modifiant une (ou plusieurs) des colonnes qui le composent     
	MODIFIER_ELT LST_EXAMPLE	*SELECT			/* en modifiant un élément on peut ajouter l'attribut SELECT ou DESELECT 
  FIN 
FIN_LECTURE_LST

/* ___ Pour une liste graphique, on peut parcourir les éléments sélectionnés par l'utilisateur ___
LECTURE_LST LST_GRAPHICAL *SELECT
	... 
FIN_LECTURE_LST  

/* ___ Pour une liste graphique, on peut parcourir les éléments modifiés par l'utilisateur ou par programme si l'attribut *MODIF a été spécifié au moment de l'insertion ___
LECTURE_LST LST_GRAPHICAL *MODIF
	...
FIN_LECTURE_LST

On peut aussi utiliser une boucle manuelle avec LIRE_P_ELT (lire le premier élément) et LIRE_AV_ELT (lire l'élément suivant).

On peut également utililser LIRE_D_ELT (lire le denier élément) and LIRE_AR_ELT (lire l'élément précédent).

Bloc de code
/* ___ Liste - utilisations ______________________________________________________ 
LIRE_P_ELT LST_EXAMPLE 							/* deletelecture the index if it's not needed anymore, to free the memory used by the index

An index is first created when the first read is done on on it (with READ_ELT or READ_F_ELT).

When an index is not needed more, we can destroy it (to release memory) with the  DELETE_INDEX instruction

4 - Operations on lists

...

Bloc de code
/* ___ Lists usage _______________________________________________________________
CLEAR_LST LST_EXAMPLE							/* clear the list specified
COPY_LST  LST_ONE LST_TWO   du premier élément de la liste (s'il existe)
TANT_QUE &CODE_LST(LST_EXAMPLE) = *NORMAL		/* est-ce que l'opération a réussi ?
  ...
  LIRE_AV_ELT LST_EXAMPLE						/* lecture de l'élément suivant (s'il existe)
REFAIRE

LIRE_D_ELT LST_EXAMPLE 							/* lecture du dernier élément de la liste (s'il existe) 
TANT_QUE &CODE_LST(LST_EXAMPLE) = *NORMAL		/* est-ce que l'opération a réussi ?
  ...
  LIRE_AR_ELT LST_EXAMPLE						/* copylecture thede contentl'élément of the list LST_ONE in the list LST_TWO, 
												/* the two lists are identical at the end of the instruction, 
												/* the two lists must have the same structure
INSERT_LST LST_ONE LST_TWO						/* add the content of the first list to the second list
												/* by default the elements are added at the end, but we can specify *BEGIN, *END, *BEFORE, *AFTER
INSERT_LST LST_ONE LST_TWO *BEGIN				/* add the content of the first list at the start of the second list 
INSERT_LST LST_ONE LST_TWO *END					/* add the content of the first list at the end of the second list 
INSERT_LST LST_ONE LST_TWO *BEFORE				/* add the content of the first list just before the current element of the second list 
INSERT_LST LST_ONE LST_TWO *AFTER				/* add the content of the first list just before the current element of the second list 

SORT_LST LST_EXAMPLE ELT_2205 *DESC, ELT_ONE	/* sort the list on the ELT_2205 colum in descending order and then on ELT_ONE column ascending

SQL

1 - Null values

When reading information from the database, we sometimes have to deal with NULL values.

For example if you want to search for the AVERAGE (or MIN, MAX etc) value of a column, sometimes your *COND(condition) will return no line or you have null values for the specified columns.

And sometime you have to know that there is no value.

To do this we have to use indicators.

précédent (s'il existe)
REDO

3 - Parcourir une liste en utilisant des indexs

Afin de parcourir une liste pour chercher un élément (ou à partir d'un élément), on peut crééer et ustiliser des listes indexées (avec l'instruction INDEX_LIST).

On pourra alors utiliser les instructions LIRE_ELT (pour lire un élément) ou LIRE_P_ELT (pour accéder au premier élément supérieur ou égal à la valeur de l'index).

Bloc de code
/* ___ Déclarations de listes ____________________________________________________
LISTE       LST_EXAMPLE    ELT_ONE ELT_TWO ELT_2205		/* définit une liste avec 3 "colonnes" précédemment déclarés, ici les variables ELT_ONE, ELT_TWO et ELT_2205
INDEX_LISTE MY_INDEX       LST_EXAMPLE ELT_2205		    /* définit l'index MY_INDEX qui va indexer la liste LST_EXAMPLE sur la colonne ELT_2205

/* ___ Liste - utilisations ______________________________________________________ 
ELT_2205 = 67											/* valeur qu'on veut atteindre dans la liste
LIRE_ELT MY_INDEX 										/* on essaie de lire le premier élément de la list qui contiendrait la valeur 67 dans la colonne ELT_2205
SI &CODE_LST(MY_INDEX) = *NORMAL						/* a-t-on trouvé ?
  ...													/* si oui, alors on est positionné sur l'élément, on peut l'utiliser, le modifier ou le supprimer.
FIN

ELT_2205 = 67
LIRE_P_ELT MY_INDEX 									/* lire le premier élément dont la valeur de colonne LT_2205 est supérieure ou égale à la valeur positionnée pour l'index (67)
TANT_QUE &CODE_LST(MY_INDEX) = *NORMAL                  /* est-ce que la dernière opération sur l'index a réussi ?
  ...
  LIRE_AV_ELT MY_INDEX
REFAIRE

DETRUIRE_INDEX MY_INDEX
Bloc de code
/* ___ Declarations _____________________________________________________________________
num_bin_2   wIndAverage
num_e( 8,2) wAverageValue
num_bin_2   wIndMax
num_e( 8,2) wMaxValue

/* ___ Code _____________________________________________________________________________
chain_sql employee *col(	average(age) 	:wAverageValue 	:wIndAverage, 	-
							max(age) 		:wMaxValue 		:wIndMax 		- 
				   *cond( name='milkwater')										/* searchsupprimer forl'index thesi averageon andne max age of employees with name equals to "milkwater" 
if wIndAverage = -1 
	/* no value for the average
else
	/* ...
end
if wIndMax = -1 
	/* no value for the maximum
else
	/* ...
end

2 - Locked records

One or several lines in a table can be locked. This is caused by a process which modified records in a table without committing the changes. The consequence is that no other process can modify the lines before the first commit or rollback was executed. Even a locked record can not be modified, it can be read by another database user.

With the reserved world *LOCKED, it is possible in Adelia to check if a record is locked. It needs to be used after a database modification statement (UPD_SQL or DELETE).

  • *LOCKED = '1' : record is locked 
  • *LOCKED = '0' : record is not locked (we can use the constant _RECORD_LOCKED instead of the value '1')
Remarque
titleAttention

By default Oracle waits an infinite amount of time after an update (or delete) operation if the record is locked.
It would answer only after the record has been released.
To change this behavior, we must use the 'VaToolBxSetTimeOut' method of the VaToolBx library (see example below)

Bloc de code
/* ___ Code _____________________________________________________________________________

/* ___ Force Oracle to answer after a certain amount of time, even if the record is locked ______________________________
/* ___ Here we will have an answer after 5 seconds maximum. _____________________________________________________________
/* ___ The 'P' parameter means all the queries submitted during the session will have this timeout delay ________________
/* ___ A 'T' parameter would mean that only the next query submitted during the session would have this timeout delay ___

call_dll 'VATOOLBX.DLL' 'VaToolBxSetTimeOut' 5 'P' returnCodeBool

/* ___ Try to do an update to a database record ___

upd_sql employee age = age + 1 - 
				   *cond( name='milkwater')										 
if *locked = _RECORD_LOCKED
	/* the record(s) is(are) locked 
else
	/* the record(s) is(are) not locked and has been updated
end

Random values

In order to generate random values, we can use 2 functions of the VaToolBx package in Adelia.

  • VaToolBxSeedRand
  • VaToolBxRandom

1 - VaToolBxSeedRand

The VaToolBxSeedRand function is used to reset the pseudo-random number generator, which is used by the VaToolBxRandom function. 

2 - VaToolBxRandom

The VaToolBxRandom function is used to generate random values.
The result is a NUM_BIN_4 number between -2147483648 and 2147483647.
To have a value between 0 and X you can use  &ABSOLUTE_VALUE and &MODULO functions (see the example above)

3 - Example

...

l'utilise plus, pour libérer la mémoire qu'il utilise

Un index est créé au moment où on l'utilise pour la première fois en lecture.

Quand un index n'a plus d'utiliité dans le programme, on peut le détruire (pour libérer de la mémoire) avec l'instruction DETRUIRE_INDEX.

4 - Operations sur les listes

Pour vider une liste , on utilisera l'instruction L4G VIDER_LST,

Pour copier une liste dans une autre liste, on utilisera l'instruction L4G COPIER_LST,

Pour inserer une liste dans une autre liste, on utilisera l'instruction L4G INSERER_LST

Pour trier une liste , on utilisera l'instruction L4G TRIER_LST.

Bloc de code
/* ___ Utlisation de listes ______________________________________________________
VIDER_LST   LST_EXAMPLE								/* efface la liste,
COPIER_LST  LST_ONE LST_TWO   						/* copier le contenu de la liste LST_ONE dans la liste LST_TWO, 
													/* les deux listes sont identiquesà la fin de l'opération, 
													/* les deux listes doivent avoir la même structure,
INSERER_LST LST_ONE LST_TWO							/* ajoute le contenu de la première liste à la seconde liste,
													/* par défaut les éléments sont ajoutés à la fin de la liste de destination, mais on peut spécifier *DEBUUT, *FIN, *AVANT, *APRES
INSERER_LST LST_ONE LST_TWO *DEBUT					/* ajoute le contenu de la première liste au début de la seconde liste
INSERER_LST LST_ONE LST_TWO *FIN		      		/* ajoute le contenu de la première liste à la fin de la seconde liste
INSERER_LST LST_ONE LST_TWO *AVANT					/* ajoute le contenu de la première liste avant l'élément courant de la seconde liste 
INSERER_LST LST_ONE LST_TWO *APRES					/* ajoute le contenu de la première liste après l'élément courant de la seconde liste 

TRIER_LST   LST_EXAMPLE ELT_2205 *DESC, ELT_ONE		/* trier la liste sur la colonne ELT_2205 en ordre décroissant et sur la colonne ELT_ONE par ordre croissant


...

SQL

1 - Valeurs nulles

Quand on lit des informations en provenance de la base de données, on doit parfois gérer des valeurs NULLES.

Par exemple si on veut gérer les valeurs MOYENNE (ou MIN, MAX etc) des colonnes, parfois le *COND(condition) ne retourne aucune ligne ou bien on peut avoir des valeurs nulles dans les colonnes spécifiées.

Et parfois il est important de savoir qu'il n'y a pas de valeur.

Pour faire celà, on utilisera des indicateurs.

Bloc de code
/* ___ Declarations _____________________________________________________________________
num_bin_2   wIndAverage
num_e( 8,2) wAverageValue
num_bin_2   wIndMax
num_e( 8,2) wMaxValue

/* ___ Code _____________________________________________________________________________
lire_sql employee *col(	moyenne(age) 	:wAverageValue 	:wIndAverage, 	-
							max(age) 		:wMaxValue 		:wIndMax 	- 
				   *cond( name='milkwater')										/* recherche de la moyenne et du max des ages des employés dont le nom est égal à "milkwater" 
si wIndAverage = -1 
	/* pas de valeur pour la moyenne
sinon
	/* ...
fin
si wIndMax = -1 
	/* pas de valeur pour le maximum
sinon
	/* ...
fin

2 - Enregistrements verrouillés

Une ou plusieurs lignes d'une table peuvent être verrouillées. Ceci peut être dû à un processus qui a modifié des éléments sans pour autant avoir validé (commit) les modifications. En conséquence, aucun autre processus ne pourra modifier les lignes avant qu'une instruction VALIDER_MAJ (ou ANNULER_MAJ) n'ait été exécutée.
Si un enregistrement verrouillé, alors il ne pourra pas être modifié. Par contre il pourra être lu par un autre utilisateur.

Le mot reservé *BLOQUE permet de vérifier si un enregistrement est verrouillé. On le consulte après un accès modifiant la base de données (MAJ_SQL ou SUPPRIMER_SQL etc..).

  • *BLOQUE = '1' : l'enregistrement est verrouillé 
  • *BLOQUE = '0' : l'enregistrement n'est pas verrouillé (on peut également utiliser la constante _RECORD_LOCKED à la place de la valeur '1')


Remarque
titleAttention

Par défaut Oracle attend un temps "infini" après une opération de mise à jour/suppression si un enregistrement est verrouillé.
La main sera rendue au programme seulement lorsque l'enregistrement aura été libéré.
Pour changer ce comportement, on utilisera la méthode 'VaToolBxSetTimeOut' de la VaToolBx library (cf exemple ci-dessous)


Bloc de code
/* ___ Code _____________________________________________________________________________

/* ___ Forcer Oracle à répondre après un certain délai, même si l'enregistrment est verrouillé __________________________
/* ___ Dans l'exemple qui suit, une réponse sera fournie après 5 secondes au maximum. ___________________________________
/* ___ Le paramètre 'P' indique que toutes les requêtes soumises durant la session utiliseront ce délai _________________
/* ___ Le paramètre 'T' indiquerait que seule la requête suivante aurait ce délai _______________________________________

appeler_dll 'VATOOLBX.DLL' 'VaToolBxSetTimeOut' 5 'P' returnCodeBool

/* ___ Tentative de mise à jour d'un enregistrement ___

maj_sql employee age = age + 1 - 
				   *cond( name = 'milkwater')										 
if *bloque = '1'
	/* l'enregistrement est verrouillé 
else
	/* l'(les) enregistement(s) ne sont pas bloqués et ont été mis à jour
end


...

Valeurs aléatoires

Pour générer des valeurs aléatoires, on peut utliiser les deux fonctions suivantes de la VaToolBx.

  • VaToolBxSeedRand
  • VaToolBxRandom

1 - VaToolBxSeedRand

La fonction VaToolBxSeedRand est utilisée pour réinitialiser le générateur de nombre pseudo-aléatoire, lequel est utilisé par la fonction VaToolBxRandom

2 - VaToolBxRandom

La fonction VaToolBxRandom est utilisée pour generater une valeur aléatoire.
Le resultat est un nombre de type NUM_BIN_4 compris entre -2147483648 et 2147483647.
Pour avoir une valeur comprise entre 0 et X on peut utiliser les fonctions &VALEUR_ABSOLUE et &MODULO (voir l'example ci-dessous)

3 - Example

Ancre
randomExample
randomExample

Example to retrieve a value between 1 and 10 :

Bloc de code
/* ___ Declarations _____________________________________________________________________
num_e(6,0) wTime
num_bin_4  wSeedValue
num_bin_4  wRandomValue

/* ___ Code _____________________________________________________________________________

/* ___ Generate a seed value ____________________________________________________________
time 		 wTime
wSeedValue = wTime
call_dll 'vatoolbx.dll' 'VaToolBxSeedRand' wSeedValue 

/* ___ Generate a random value 

...

Example to retrieve a value between 1 and 10 :

Bloc de code
/* ___ Declarations _____________________________________________________________________
num_e(6,0) wTime
num_bin_4  wSeedValue
num_bin_4call_dll 'vatoolbx.dll' 'VaToolBxRandom'   wRandomValue

/* ___ Code Calculate a value between 1 and 10 _____________________________________________________________________
wRandomValue = &absolute_value(wRandomValue)
wRandomValue = &modulo(wRandomValue;10)
wRandomValue = wRandomValue + 1


...

Dynamic program call

We can use the CALL instruction to call a dynamic program, with static or even dynamic parameters

1 - Dynamic call examples

Bloc de code
/* ___ Declarations ________

/* ___ Generate a seed value ____________________________________________________________
time 		 wTime
wSeedValue = wTime
call_dll 'vatoolbx.dll' 'VaToolBxSeedRand' wSeedValue 
alpha(  10)  wProgramObjectFileName
alpha( 128)  wProgramPublicProcedureName
alpha(1000)  wParameters
num_e( 2,0)  myParameterNum01
num_e( 2,0)  myParameterNum02

/* ___ Generate a random value Code ___________________________________________________________________________________
call_dll 'vatoolbx.dll' 'VaToolBxRandom'   wRandomValue
call myProgram
call myProgram.myProcedure
myParameterNum01= 22
call myProgram.myProcedure2 myParameterNum01
myParameterNum01= 22
myParameterNum02= 05
call myProgram.myProcedure2 myParameterNum01 myParameterNum02

/* ___ CalculateDynamic aprogram value between 1 and 10 name _____________________________________________________________
wRandomValuewProgramObjectFileName = &absolute_value(wRandomValue)
wRandomValue = &modulo(wRandomValue;10)
wRandomValue = wRandomValue + 1

Dynamic program call

We can use the CALL instruction to call a dynamic program, with static or even dynamic parameters

1 - Dynamic call examples

Bloc de code
/* ___ Declarations'mypgm'
call &wProgramObjectFileName 

wProgramObjectFileName      = 'mypgm'
call &wProgramObjectFileName.myProcedure

/* ___ Dynamic program name and public procedure name ___________________________________
wProgramObjectFileName      = 'mypgm'
wProgramPublicProcedureName = 'myProcedure'
call &wProgramObjectFileName.&wProgramPublicProcedureName

wProgramObjectFileName      = 'mypgm'
wProgramPublicProcedureName = 'myProcedure2'
myParameterNum01            = 22
call &wProgramObjectFileName.&wProgramPublicProcedureName myParameterNum

/* ___ Dynamic program name, procedure name and parameters _______________________________
alpha(  10)  wProgramObjectFileName
alpha( 128)  wProgramPublicProcedureName
alpha(
wProgramObjectFileName      = 'mypgm'
wProgramPublicProcedureName = 'myProcedure2'
wParameters                 = '22 05'
call &wProgramObjectFileName.&wProgramPublicProcedureName &wParameters


...

Users's attribute

User session can be used to store and retrieve values.

Avertissement
titleWarning

It is only available in client part of a cloud generated program (not in a server part or in a server program or in a windows program).

1 - Set an attribute value

To set a session private attribute value, we simply have to use the  VaToolBxCloudSetUserAttribute fonction of the vaToolBx library :

Bloc de code
1000)  wParameters
num_e( 2,0)  myParameterNum01
num_e( 2,0)  myParameterNum02

/* ___ Code ________Declarations _____________________________________________________________________
call myProgram
call myProgram.myProcedure
myParameterNum01= 22
call myProgram.myProcedure2 myParameterNum01
myParameterNum01= 22
myParameterNum02= 05
call myProgram.myProcedure2 myParameterNum01 myParameterNum02

alpha( 50) wAttributeName
alpha(256) wAttributeValue

/* ___ Dynamic program name ________________Code _____________________________________________
wProgramObjectFileName = 'mypgm'
call &wProgramObjectFileName 

wProgramObjectFileName      = 'mypgm'
call &wProgramObjectFileName.myProcedure

/* ___ Dynamic program name and public procedure name ___________________________________
wProgramObjectFileNamewAttributeName      = 'mypgm'
wProgramPublicProcedureName = 'myProcedure'
call &wProgramObjectFileName.&wProgramPublicProcedureName

wProgramObjectFileName      = 'mypgm'
wProgramPublicProcedureName = 'myProcedure2'
myParameterNum01            = 22
call &wProgramObjectFileName.&wProgramPublicProcedureName myParameterNum

/* ___ Dynamic program name, procedure name and parameters ______________________________
wProgramObjectFileNamemyLabel'							/* Label 
wAttributeValue = 'xxxyyyzzz'						/* Value to be stored under the user session (must be alpha value)
call_dll 'VaToolBx' 'VaToolBxCloudSetUserAttribute' wAttributeName  -
                            = 'mypgm'
wProgramPublicProcedureName = 'myProcedure2'
wParameters                 = '22 05'
call &wProgramObjectFileName.&wProgramPublicProcedureName &wParameters

Users's attribute

User session can be used to store and retrieve values.

Avertissement
titleWarning

It is only available in client part of a cloud generated program (not in a server part or in a server program or in a windows program).

...

 wAttributeValue

The scope of this setting is limited to the current session (logout / logon will destroy all values).

2 - Retrieve an attribute value

To set retrieve a session private attribute value, we simply have to use the  VaToolBxCloudSetUserAttribute VaToolBxCloudGetUserAttribute fonction of the vaToolBx library :

Bloc de code
/* ___ Declarations _____________________________________________________________________
alpha( 50) wAttributeName
alpha(256) wAttributeValue
num_bin_4  wAttributeLength

/* ___ Code _____________________________________________________________________________
wAttributeName   = 'myLabel'							/* Label 
wAttributeValue  = *blank
wAttributeLength = 'xxxyyyzzz'256								/* ValueSize to be stored under of the user session (must be alpha value)wAttributeValue variable
call_dll 'VaToolBx' 'VaToolBxCloudSetUserAttributeVaToolBxCloudGetUserAttribute' wAttributeName   -
                                                    wAttributeValue  -
                                                    wAttributeLength
if *return_code = *normal
   /* wAttributeValue

The scope of this setting is limited to the current session (logout / logon will destroy all values).

...

 contains the value previously saved
end

3 - Delete an attribute value

To retrieve delete a session private attribute value, we simply have to use the  VaToolBxCloudGetUserAttribute VaToolBxCloudSetUserAttribute fonction of the vaToolBx library with a blank value :

Bloc de code
/* ___ Declarations _____________________________________________________________________
alpha( 50) wAttributeName
alpha(256) wAttributeValue
num_bin_4  wAttributeLength

/* ___ Code _____________________________________________________________________________
wAttributeName   = 'myLabel'							/* Label 
wAttributeValue  = *blank
wAttributeLength = 256								/* * Size ofblank to delete the label from the wAttributeValueuser's variablesession
call_dll 'VaToolBx' 'VaToolBxCloudGetUserAttributeVaToolBxCloudSetUserAttribute' wAttributeName   -
                                                    wAttributeValue  -
                                                    wAttributeLength
if *return_code = *normal
      /* wAttributeValue contains the value previously saved
end

3 - Delete an attribute value

To delete a session private attribute value, we simply have to use the  VaToolBxCloudSetUserAttribute fonction of the vaToolBx library with a blank value :

 wAttributeValue


...

Management Rules

Management rules (MR) can be used if we don't want to repeat the same code on different parts of the code.
The management rule can have parameters and must be seen as a text that will be parsed inside the code.

1 - Parameters

The parameter 1 of the MR will be placed in place of the :01 value etc.
The :01 (:xx) value can be present multiple times inside the MR.
The :01 (:xx) value can be placed anywhere in the code, even to replace an Adelia order or part of it.

code
Bloc de code
titleExamples of code of a Management Rule
/* ___ DeclarationsManagement Rule "My___________Beautiful_MR" __________________________________________________________
alpha( 50) wAttributeName
alpha(256) wAttributeValue

/* ___ Code ________Declarations _____________________________________________________________________
wAttributeName  = 'myLabel'							/* Label 
wAttributeValue = *blank							/* *blank to delete the label from the user's session
call_dll 'VaToolBx' 'VaToolBxCloudSetUserAttribute' wAttributeName  -
                   _____
decl alpha( 50)                                 wAttributeValue

Management Rules

Management rules (MR) can be used if we don't want to repeat the same code on different parts of the code.
The management rule can have parameters and must be seen as a text that will be parsed inside the code.

1 - Parameters

The parameter 1 of the MR will be placed in place of the :01 value etc.
The :01 (:xx) value can be present multiple times inside the MR.
The :01 (:xx) value can be placed anywhere in the code, even to replace an Adelia order or part of it.

Bloc de code
titleExamples of code of a Management Rule
/* ___ Management Rule "My_Beautiful_MR" w:01_val
decl ref(cli_usr_:02 client) wCli_usr_:02
decl num_e(9,0)              sqlcode_mr

/* ___ Code _____________________________________________________________________________
wcli_usr_:02  = :03							
if wcli_usr_:02 = *blank 
	wcli_usr_:02 = *user
end
upd_sql client cli_usr_:02 = :wcli_usr_:02
sqlcode_mr = *sqlcode
:06 insert_mr BOL_TRC_:05('*DEBUG';'my beautiful MR, sqlCode : '//sqlcode_mr ;1)
:04 = sqlcode______

mr 

2 - Usage

To use a MR, we simply have to insert it with the INSERT_MR order

Bloc de code
titleExamples of code of insertion of a Management Rule
/* ___ DeclarationsCode _____________________________________________________________________
decl alpha( 50)              w:01_val
decl ref(cli_usr_:02 client) wCli_usr_:02
decl num_e(9,0)              sqlcode_mr

/* _____ Code _________________
insert_mr my_beautiful_mr(test;cre;'milkwater';mrReturnCode;C; )
insert_mr my_beautiful_mr(test;maj;*blank;mrReturnCode;S;*)


...

Graphical objects

1 - get an object from his object name

In order to get the handle of an object from the name of the object it's possible to use the predefined function &GET_OBJECT :

Bloc de code
titleExamples of code
/* ___ Declarations ___________________________________________________
wcli_usr_:02  = :03							
if wcli_usr_:02 = *blank 
	wcli_usr_:02 = *user
end
upd_sql client cli_usr_:02 = :wcli_usr_:02
sqlcode_mr = *sqlcode
:06 insert_mr BOL_TRC_:05('*DEBUG';'my beautiful MR, sqlCode : '//sqlcode_mr ;1)
:04 = sqlcode_mr 

2 - Usage

To use a MR, we simply have to insert it with the INSERT_MR order

Bloc de code
titleExamples of code of insertion of a Management Rule
_______________
graphic_object(colonne) colObjVar

/* ___ Code _____________________________________________________________________________
insert_mr my_beautiful_mr(test;cre;'milkwater';mrReturnCode;C; )
insert_mr my_beautiful_mr(test;maj;*blank;mrReturnCode;S;*)

Graphical objects

1 - get an object from his object name

In order to get the handle of an object from the name of the object it's possible to use the predefined function &GET_OBJECT :

colObjVar = &get_object('col_01')
colObjVar:visibility = *true


...

Classes

Les classes sont utilisées notament pour consommer ou produire des services web

1 - JSON

Pour générer ou bien utiliser le format suivant dans un fichier JSON


Bloc de code
{
...
   "BarCodeList":[
      "2205",
      "2206",
      "2207"
   ]
...
}

Il faudra effectuer la déclaration suivante dans la définition de la classe Adelia MA_CLASSE :

Bloc de code
titleclasse MA_CLASSE
*attributs
{
...
alpha(   32)                BarCodeList()          *ser_nom('BarCodeList');
...
}

Puis le code adelia suivant pour pouvoir générer des données dans ce élément :

Bloc de code
alpha(   32)                BarCodeList()          *ser_nom('BarCodeList');
Bloc de code
titleExamples of code
/* ___ Declarations _____________________________________________________________________
graphic_object(colonne) colObjVar

/* ___ Code _____________________________________________________________________________
colObjVar = &get_object('col_01')
colObjVar:visibility = *true



...

Resources

Ressources are typically used to import "external" objects in the adelia environment.
The advantage to import an object in the adelia environment is that we don't need any more the external object to use it.
It will be saved also with the backup of the environment.

...

Avertissement

The image variable must contains text. It can be for example an image variable containing XML..


Bloc de code
/* ___ Declarations _____________________________________________________________________
image wImage

Bloc de code
/* ___ Declarations Code _____________________________________________________________________________
insert_mr bol______________________
image wImage

/* ___ Code _____________________________________________________________________________
insert_mr bol_trc_imagea('*DEBUG';'my text ';wImage;1)

BOL database scripts

1 - Set new PAPG values

PAPG example :

trc_imagea('*DEBUG';'my text ';wImage;1)


...

BOL database scripts

1 - Set new PAPG values

PAPG example :

Bloc de code
-- Create program configuration option MYCONFIG
delete from wms.hlxprop where XPCPRG = 'MYCONFIG';
insert into wms.hlxprop values('MYCONFIG', 'My configuration', 'MYCONFIG', '007', '011', '0', '0', 0);

delete from wms.hlpgpap where GKCPRG = 'MYCONFIG';
insert into wms.hlpgpap values('MYCONFIG',' ','1','0',' ');

delete from wms.hlpapdp where GJCPRG = 'MYCONFIG';
insert into wms.hlpapdp values('MYCONFIG',1,'Code',3,' ',' ',' ')
Bloc de code
-- Create program configuration option MYCONFIG
delete from wms.hlxprop where XPCPRG = 'MYCONFIG';
insert into wms.hlxprophlpapdp values('MYCONFIG', 'My configuration', 4,'Designation',100,' ',' ',' ');
insert into wms.hlpapdp values('MYCONFIG',104, '007Active',1,' '011,', '0,', '0', 0);

delete from wms.hlpgpap where GKCPRG = 'MYCONFIG';
insert into wms.hlpgpap values('MYCONFIG',' ','1','0',' ');

delete from wms.hlpapdp where GJCPRG = 'MYCONFIG';
insert into wms.hlpapdp values('MYCONFIG',1,'Code',3,' ',' ',' ');
insert into wms.hlpapdp values('MYCONFIG',4,'Designation',100,' ',' ',' ');
insert into wms.hlpapdp values('MYCONFIG',104,'Active',1,' ',' ',' ');

BOL REST services

1 - Call swagger REST API page

The url address of the swagger REST API page is :

Image Removed

2 - Generate the JWT token

To generate the JWT token, you'll have to access to the following url, but replace XXX with your reflex login and YYY with your reflex password

Image Removed

3 - Apply the JWT token

To apply the JWT token to the rest call, press the Authorize button on top of the REST API page.

Image Removed

Then enter "JWT" , a space character AND the token generated for your user/pass informations.

Image Removed

 ');


...

BOL REST services

1 - Call swagger REST API page

The url address of the swagger REST API page is :

Image Added

2 - Generate the JWT token

To generate the JWT token, you'll have to access to the following url, but replace XXX with your reflex login and YYY with your reflex password

Image Added

3 - Apply the JWT token

To apply the JWT token to the rest call, press the Authorize button on top of the REST API page.

Image Added

Then enter "JWT" , a space character AND the token generated for your user/pass informations.

Image Added

Then press Authorize button.


...

REFLEX REST services web

1 - Swagger et visualisation des web services spécifiques

Afin de pouvoir visualiser ses services web spécifiques dans l'interface de swagger, il faudra modifier le fichier de configuration wsRestConf.properties présent dans le répertoires de configuration reflex web (C:\Hardis\Reflex\conf en version windows)

On ajoutera la valeur ",com.hardis.reflex" à la ligne correspondant à la clef "SWAGGER2FEATURE.resourcePackage"

Bloc de code
titlewsRestConf.properties
...
SWAGGER2FEATURE.resourcePackage=com.hardis.reflex.publicapi,com.hardis.adelia.webservice,com.hardis.reflex
...

2 - Swagger et chapitres

Afin de regrouper les web services par types de services sans avoir à mettre tous les services (procédures) dans le même programme, il suffira d'ajouter dans le code de configuration "sw_configurer *service _ws_rest_swag_description ..." pour que le service soit ajouté à un groupe de web services.

Par exemple afin de regrouper des services web de test sous le chapitre "XXX - Web services de test (STUB)", il faudra écrire le code suivant dans le paragraphe DECL_PGM du programme contenant le(s) service(s) :

Bloc de code
titlewsRestConf.properties
DECL_PGM
...
sw_configurer *service _ws_rest_swag_description 'XXX - Web services de test (STUB)'
...

De cette façon, une fois le(s) service(s) généré(s), on verra le chapitre suivant dans swagger :

Image AddedThen press Authorize button.