Vue locale (langage)

De Wiki1000
(Différences entre les versions)
(Opérateur portant sur une référence)
(Vue avec sous requêtes)
 
(37 révisions intermédiaires par un utilisateur sont masquées)
Ligne 45 : Ligne 45 :
 
   <date_operator> ::= year|month|quarter|week|day|dayofyear|dayofweek|hour|minute|second
 
   <date_operator> ::= year|month|quarter|week|day|dayofyear|dayofweek|hour|minute|second
 
   <join_operator> ::= join
 
   <join_operator> ::= join
   <attribute_directive> ::=  primary | orderby | orderby desc  
+
   <attribute_directive> ::=  primary | orderby | orderby desc | over | notInSelect
 
   <where_def> ::= [ <expression> ]
 
   <where_def> ::= [ <expression> ]
  
Ligne 314 : Ligne 314 :
 
</source>
 
</source>
  
====Vue avec jointure====
+
====Vue avec jointure sur une classe====
 +
 
 +
<pre>
 +
Type
 +
  myView = class(myClass)
 +
    vp1:joinClass1 = join(A,B);
 +
    vp2:JoinClass2 = join(A,B,W);
 +
    vp3:JoinClass3 = join(W);
 +
    ....
 +
  end;
 +
</pre>
 +
 
 +
{|class="wikitable"
 +
|-
 +
!Paramètre
 +
!Usage
 +
|-
 +
|A
 +
|Attribut de la classe join (joinClass)
 +
|-
 +
|B
 +
|Chemin à partir de la classe base (myView)
 +
|-
 +
|W
 +
|Clause Where sur la classe join
 +
|}
 +
 
 +
La clause Where peut être exprimée avec les préfixes :
 +
 
 +
{|class="wikitable"
 +
|-
 +
|self
 +
|Préfixe de la classe de base
 +
|-
 +
|?
 +
|Préfixe de la classe Join
 +
|-
 +
|xx
 +
|alias d'une jointure de classe
 +
|}
 +
 
 +
{{tip|Il est possible de créer un produit cartésien entre deux classes en utilisant une jointure avec une clause where toujours vraie. }}
 +
 
 +
{{tip|Les jointures seront générées dans l'ordre de leur déclaration dans la vue. }}
  
 
<source lang="delphi">
 
<source lang="delphi">
Ligne 356 : Ligne 399 :
 
</source>
 
</source>
  
Dans cette exemple le modèle est celui-ci :
+
Dans cet exemple le modèle est celui-ci :
  
 
[[image:view-join-2.jpg]]
 
[[image:view-join-2.jpg]]
Ligne 370 : Ligne 413 :
 
* ValidationEtat.EtatPossible.EtatMetier est le chemin issu de la classe jointe
 
* ValidationEtat.EtatPossible.EtatMetier est le chemin issu de la classe jointe
 
* EtatNF est le chemin issu de la classe de la vue.
 
* EtatNF est le chemin issu de la classe de la vue.
 +
 +
 +
'''Exemple, vue locale avec produit cartésien, jointure par clause where et sous requêtes'''
 +
 +
<source lang="delphi">
 +
//procedure RubriqueParExerciceDetail;
 +
Type
 +
  vueSolde = viewof(TCumulPeriodeCompte)
 +
  codeCompte:string = CompteGeneral.codeCompte;
 +
  datePeriode:TDatetime = Periode.dateDebut;
 +
  value:Currency = sumDiff(debitTenue,creditTenue);
 +
  oidExercice:TOID = Periode.oidexercice;
 +
  [(typeLot=1)]
 +
  end;
 +
 +
  vueSelection = viewOf(TSelectionCompte)
 +
  vc:TCompteGeneral = join('(codeCompte>=self.compteInferieur) and (codeCompte<=self.compteSuperieur)');
 +
  vp:TPeriode = join('(1=1)');
 +
  ve:TExercice = join(oid,vp.oidexercice);
 +
  ve1:TExercice = join('(?.dateDebut = DateAdd(dpyear,ve.dateDebut,-1))');
 +
  //
 +
  idCompteGeneral:TOID = vc.oid primary;
 +
  idRubrique:TOID = oidRubriqueCompte primary;
 +
  idPeriode:TOID = vp.oid primary;
 +
  idExercice:TOID = vp.oidexercice;
 +
  idExerciceN1:TOID = ve1.oid;
 +
  //
 +
  codeRubrique:string = RubriqueCompte.code orderby;
 +
  libelleRubrique:string = RubriqueCompte.Caption;
 +
  codeCompte:string = vc.codeCompte orderby;
 +
  libelleCompte:string = vc.Caption;
 +
  libellePeriode:string = vp.Caption;
 +
  //
 +
  datePeriode:TDatetime = vp.dateDebut orderby desc;
 +
  year:Integer = year(vp.dateDebut);
 +
  month:Integer = month(vp.dateDebut);
 +
  valueN0:currency = VueSolde.select('value','(oidExercice=self.idExercice) and  (codeCompte=self.codeCompte) and (datePeriode<=self.datePeriode)','',true,[]);
 +
  valueN1:currency = VueSolde.select('value','(oidExercice=self.idExerciceN1) and  (codeCompte=self.codeCompte) and (datePeriode<=DateAdd(dpYear,self.datePeriode,-1))','',true,[]);
 +
end;
 +
 +
var Sel:TSelector; inst:vueSelection; S,stag:string;
 +
begin
 +
  Sel  := vueSelection.CreateSelector('(codeRubrique=%1) and (year=2022) and (month=3)','',True,['SIG.L02']);
 +
 +
  S := ''; stag := '';
 +
  forEach inst in Sel.AsCursor do
 +
  begin
 +
    S := S+stag+inst.codeCompte;
 +
    stag := ',';
 +
  end;
 +
  showMessage(S);
 +
end;
 +
</source>
 +
 +
{{tip|Notez l'opérateur SQL DateAdd() qui peut être utilisé dans la partie littérale d'une expression}}
 +
 +
====Vue avec jointures liées====
 +
{{version11}}
 +
 +
<source lang="delphi">
 +
Type
 +
  VueValideur = viewOf(TPieceTaxable)
 +
  vp1: TValideurPossible = join(ValidationEtat.EtatPossible.EtatMetier,EtatMetier);
 +
  vp2: TValideurPossible = join(ValidationEtat.RegleValidation,RegleValidation);
 +
  gcv: TGroupeContactValidation = leftjoin(TGroupeValidation,vp2.ContactEtablissement);
 +
  aId1:TOID = vp1.oid;
 +
  aId2:TOID = vp2.oid;
 +
  //
 +
  ...
 +
  [ (aId1=aId2) and ... ]
 +
  end;
 +
</source>
 +
 +
Dans cet exemple :
 +
 +
* vp1 et vp2 sont deux jointures qui coincident sur le même tuple.
 +
* La coincidence des deux jointures est réalisée par le clause where (aId1=aId2)
 +
* gcv est une jointure sur le tuple défini par vp1 et vp2
 +
 +
====Vue avec sous requêtes====
 +
 +
{{version11}}
 +
 +
Il est possible de générer une sous requête liée à la requête principale en utilisant la méthode SELECT d'un sélecteur.
 +
 +
La sous requêtes doit être liée à la requête principale en utilisant l'opérateur self dans la clause Where du SELECT.
 +
 +
Une sous requêtes peut être utilisée soit dans la liste des colonnes, soit dans la clause Where du selecteur.
 +
 +
'''Utilisation dans les colonnes :'''
 +
<source lang="delphi">
 +
Type
 +
  Vue1 = viewOf(MyClass)
 +
  sub1:TMoney = sum(...);
 +
  id1:TOID = ....;
 +
  ....
 +
  end;
 +
 +
  Vue2 = viewOf(MyClass)
 +
  sum1:TMoney = sum(...);
 +
  sum2:TMoney = Vue1.Select('sub1','(id1=self.id2)','',true,[]);
 +
  id2:TOID = ...;
 +
  ....
 +
  end;
 +
 +
var sel:TSelector;
 +
begin
 +
  sel := Vue2.CreateSelector('','',true,[]);
 +
  //
 +
  ...
 +
end;
 +
</source>
 +
 +
'''Utilisation dans la clause Where :'''
 +
<source lang="delphi">
 +
Type
 +
  Vue1 = viewOf(MyClass)
 +
  sub1:TMoney = sum(...);
 +
  id1:TOID = ....;
 +
  ....
 +
  end;
 +
 +
  Vue2 = viewOf(MyClass)
 +
  sum1:TMoney = sum(...);
 +
  id2:TOID = ...;
 +
  ....
 +
  end;
 +
 +
var sel:TSelector;
 +
begin
 +
  sel := Vue2.CreateSelector('(sum1>%1)','',true,[
 +
    Vue1.Select('sub1','(id1=self.id2)','',true,[])
 +
  ]);
 +
  //
 +
  ...
 +
end;
 +
</source>
 +
 +
'''Avec des paramètres :'''
 +
 +
Il est possible de paramétrer une sous requête en utilisant les paramètres de la requête principale :
 +
 +
<source lang="delphi">
 +
Type
 +
  Vue1 = viewOf(MyClass)
 +
  sub1:TMoney = sum(...);
 +
  id1:TOID = ....;
 +
  col1:string = ...;
 +
  col2:Integer = ...;
 +
  ....
 +
  end;
 +
 +
  Vue2 = viewOf(MyClass)
 +
  sum1:TMoney = sum(...);
 +
  sum2:TMoney = Vue1.Select('sub1','(id1=self.id2) and (col=%1) and (col2=%2)','',true,[]);
 +
  id2:TOID = ...;
 +
  ....
 +
  end;
 +
 +
var sel:TSelector;
 +
begin
 +
  sel := Vue2.CreateSelector('','',true,['valueCol1',1,....]);
 +
  //
 +
  ...
 +
end;
 +
</source>
 +
 +
====Vue avec interface (Union)====
 +
{{version11}}
 +
 +
Il est possible d'utiliser une interface pour générer une union de plusieurs vues locales supportant cette interface
 +
 +
Exemple :
 +
 +
<source lang="delphi">
 +
Type
 +
  ISoldeCompte = interface
 +
    credit:Currency;
 +
    debit:Currency;
 +
    typeLot:Integer;
 +
    codeCompte:string;
 +
    captionCompte:string;
 +
    sensCompte:Integer;
 +
    norme:string;
 +
  end;
 +
 +
  VueSoldeComptePeriode = viewOf(TCumulPeriodeCompte,ISoldeCompte)
 +
    credit:Currency = creditTenue;
 +
    debit:Currency = debitTenue;
 +
    typeLot:Integer = typeLot;
 +
    codeCompte:string = compteGeneral.codeCompte;
 +
    captionCompte:string = compteGeneral.Caption;
 +
    sensCompte:Integer = compteGeneral.sensPrivilegie;
 +
    norme:string = normeComptable.code;
 +
    dateFin:Tdatetime = Periode.dateFin notInSelect;
 +
    [dateFin < GetDate]
 +
  end;
 +
 +
  VueSoldeEcriture = viewOf(TEcriture,VueSoldeComptePeriode)
 +
    credit:Currency = credit:TCValue;
 +
    debit:Currency = debit:TCValue;
 +
    typeLot:Integer = piece.lot.typeLot;
 +
    codeCompte:string = compteGeneral.codeCompte;
 +
    captionCompte:string = compteGeneral.Caption;
 +
    sensCompte:Integer = compteGeneral.sensPrivilegie;
 +
    norme:string = piece.normeComptable.code;
 +
    eDate:Tdatetime = eDate notInSelect;
 +
    [eDate >= GetValue('begin Result := TFacadeInitGeneral.GetPreviousPeriodEndDate(Date); end;')]
 +
  end;
 +
 +
  VueSoldeCompte = viewOf(ISoldeCompte,VueSoldeComptePeriode,VueSoldeEcriture)
 +
    solde:Currency = sumSens(credit,debit,sensCompte);
 +
    typeLot:Integer = typeLot;
 +
    codeCompte:string= codeCompte;
 +
    captionCompte:string = captionCompte;
 +
    sensCompte:Integer = sensCompte;
 +
    norme:string= norme notInSelect;
 +
  end; 
 +
 +
var ls:TSelector; inst:VueSoldeCompte; doc:TxmlhtmlMailDocument; Table:ThtmlTable; ANorme1,ANorme2:string;
 +
begin
 +
  ls := VueSoldeCompte.CreateSelector('(codeCompte like %1) and (typeLot=%2) and ((norme=%3)or(norme=%4))','',true,[
 +
    _StrLike(prefixeCompte),
 +
    typeLot.Value,
 +
    ANorme1,
 +
    ANorme2
 +
    ]);
 +
 +
  ...
 +
end;
 +
</source>
 +
 +
 +
====Vue utilisant une CTE (Commun table expression)====
 +
 +
{{version11}}
 +
 +
Il est possible de générer une requête CTE :
 +
* En utilisant une directive "over" dans la définition d'une colonne
 +
* En positionant la propriété useCTE sur le sélecteur.
 +
 +
Le code SQL généré sera
 +
 +
<pre>
 +
With CTE AS (
 +
)
 +
SELECT * from CTE
 +
</pre>
 +
 +
Lorsqu'une CTE est utilisée la clause Where du sélecteur s'applique sur résultat de la CTE.
 +
 +
<source lang="delphi">
 +
Type
 +
  Vue1 = viewOf(MyClass)
 +
  sub1:TMoney = sum(...);
 +
  id1:TOID = ....;
 +
  ....
 +
  end;
 +
 +
  Vue2 = viewOf(MyClass)
 +
  sum1:TMoney = sum(...);
 +
  sum2:TMoney = Vue1.Select('sub1','(id1=self.id2)','',true,[]);
 +
  id2:TOID = ...:
 +
  end;
 +
 +
var sel:TSelector;
 +
begin
 +
  sel := Vue2.CreateSelector('(sum1 > sum2)','',true,[]);
 +
  sel.UseCTE := True; 
 +
  //
 +
  ...
 +
end;
 +
</source>
 +
 +
===Directive d'attribut===
 +
 +
{{version11}}
 +
 +
{|class="wikitable"
 +
|-
 +
!Directive
 +
!Action
 +
|-
 +
|notInSelect
 +
|L'attribut ne sera pas généré dans clause select
 +
|-
 +
|over
 +
|L'attribut est généré par rapport à la requête CTE
 +
|}
 +
 +
===Directive primary===
 +
 +
{{version11}}
 +
 +
Une vue peut contenir plusieurs directives '''primary''' de type oid
 +
 +
Dans ce cas l'identifiant d'un objet de la vue sera une liste identifiants.
 +
 +
===Directive orderby===
 +
 +
{{version11}}
 +
 +
Une vue peut contenir plusieurs directives '''orderby'''
 +
 +
Dans ce cas l'ordre de tri sera défini par la liste des attributs, dans l'ordre de leur déclaration dans la vue.
  
 
===Opérateurs===
 
===Opérateurs===
 +
====Opérateur portant sur une colonne====
 +
{{version11}}
 +
{|class="wikitable"
 +
|-
 +
!Opérateur
 +
!Arguments
 +
!Action
 +
!Opération
 +
|-
 +
|IsNull(ope1,ope2)|isNull
 +
|2
 +
|Retourne la valeur de la colonne 2 si la valeur de la colonne 1 est nulle
 +
|case A is NULL then B else A
 +
|}
 +
 +
'''Exemple d'utilisation de isNull'''
 +
 +
<source lang="delphi">
 +
Type
 +
  VueValideur = viewOf(TPieceTaxable)
 +
  vp1: TValideurPossible = join(ValidationEtat.EtatPossible.EtatMetier,EtatMetier);
 +
  vp2: TValideurPossible = join(ValidationEtat.RegleValidation,RegleValidation);
 +
  gcv: TGroupeContactValidation = leftjoin(TGroupeValidation,vp2.ContactEtablissement);
 +
  aId1:TOID = vp1.oid;
 +
  aId2:TOID = vp2.oid;
 +
  aIdVP:TOID = vp2.oidValideurPrecedent;
 +
  aIdDV:TOID = oiddernierValideur;
 +
  aIdCV:TOID = vp2.oidContactEtablissement;
 +
  // contact établissement valideur, peut être membre du groupe de validation ou le valideur défini par la règle
 +
  aIdCE:TOID = ISNULL(gcv.oidTContactEtablissement,vp2.oidContactEtablissement);
 +
  // personne
 +
  Mail:string = ISNULL(gcv.TContactEtablissement+eMail,vp2.ContactEtablissement.eMail);
 +
  //
 +
  [ (aId1=aId2) ... ]
 +
  end;
 +
</source>
 +
 
====Opérateur portant sur un type numérique====
 
====Opérateur portant sur un type numérique====
  
Ligne 379 : Ligne 764 :
 
!Arguments
 
!Arguments
 
!Action
 
!Action
 +
!Opération
 
|-
 
|-
 
|sum (view ope)|sum
 
|sum (view ope)|sum
 
|1
 
|1
 
|Effectue la somme de l'attribut
 
|Effectue la somme de l'attribut
 +
|sum(A)
 
|-
 
|-
 
|min (view ope)|min
 
|min (view ope)|min
 
|1
 
|1
|Effectue la somme de l'attribut
+
|Retourne le minimum de l'attribut
 +
|min(A)
 
|-
 
|-
 
|max (view ope)|max
 
|max (view ope)|max
 
|1
 
|1
 
|Retourne le max de l'attribut
 
|Retourne le max de l'attribut
 +
|max(A)
 
|-
 
|-
 
|add (view ope)|add
 
|add (view ope)|add
 
|2
 
|2
 
|Retourne la somme de deux attributs
 
|Retourne la somme de deux attributs
 +
|A+B
 
|-
 
|-
 
|sub (view ope)|sub
 
|sub (view ope)|sub
 
|2
 
|2
 
|Retourne la différence entre deux attributs
 
|Retourne la différence entre deux attributs
 +
|A-B
 +
|-
 +
|mul (view ope)|mul
 +
|2
 +
|Retourne la multiplication de deux attributs
 +
|A*B
 +
|-
 +
|div (view ope)|div
 +
|2
 +
|Retourne la divition de deux attributs
 +
|A/B
 +
|-
 +
|percent
 +
|2
 +
|Retourne le poucentage entre deux attributs
 +
|case when B=0 then 0 else (100*A / B) end
 
|-
 
|-
 
|sumdiff (view ope)|sumdiff
 
|sumdiff (view ope)|sumdiff
 
|2
 
|2
 
|Retourne la somme de la différence entre deux attributs
 
|Retourne la somme de la différence entre deux attributs
 +
|sum(A-B)
 +
|-
 +
|sumdiff2 (view ope)|sumdiff2
 +
|3
 +
|Retourne la somme de la différence entre trois attributs
 +
|sum(A+B-C)
 
|-
 
|-
 
|mindiff (view ope)|mindiff
 
|mindiff (view ope)|mindiff
 
|2
 
|2
 
|Retourne le min de la différence entre deux attributs
 
|Retourne le min de la différence entre deux attributs
 +
|min(A-B)
 
|-
 
|-
 
|maxdiff (view ope)|maxdiff
 
|maxdiff (view ope)|maxdiff
 
|2
 
|2
 
|Retourne le max de la différence entre deux attributs
 
|Retourne le max de la différence entre deux attributs
 +
|max(A-B)
 
|-
 
|-
 
|sumconcat (view ope)|sumconcat
 
|sumconcat (view ope)|sumconcat
 
|2
 
|2
 
|Retourne la somme de la somme entre deux attributs
 
|Retourne la somme de la somme entre deux attributs
 +
|sum(A+B)
 
|-
 
|-
 
|minconcat (view ope)|minconcat
 
|minconcat (view ope)|minconcat
 
|2
 
|2
 
|Retourne la min de la somme entre deux attributs
 
|Retourne la min de la somme entre deux attributs
 +
|min(A+B)
 
|-
 
|-
 
|maxconcat (view ope)|maxconcat
 
|maxconcat (view ope)|maxconcat
 
|2
 
|2
 
|Retourne le max de la somme entre deux attributs
 
|Retourne le max de la somme entre deux attributs
 +
|max(A+B)
 
|-
 
|-
 
|count (view ope)|count
 
|count (view ope)|count
 
|1
 
|1
|Compte le nombre d'attribut
+
|Compte le nombre de lignes
 +
|count(*)
 +
|}
 +
 
 +
{{version900}}
 +
{|class="wikitable"
 +
|-
 +
!Opérateur
 +
!Arguments
 +
!Action
 +
!Opération
 +
|-
 +
|sumDiffP
 +
|2
 +
|Retourne la somme de la différence si elle positive et 0 sinon.
 +
|case sum(A-B)>0 then sum(A-B) else 0
 +
|-
 +
|sumDiffA
 +
|2
 +
|Retourne la valeur absolue de la différence.
 +
|ABS(sum(A-B))
 +
|-
 +
|sumDiffS
 +
|2
 +
|Retourne le signe de la différence
 +
|case sum(A-B)>0 then 1 else 0
 +
|}
 +
 
 +
{{version11}}
 +
{|class="wikitable"
 +
|-
 +
!Opérateur
 +
!Arguments
 +
!Action
 +
!Operation
 +
|-
 +
|sum (view ope)|sum
 +
|1,2,3
 +
|Effectue la somme des attributs
 +
|sum(A), sum(A+B),sum(A+B+C)
 +
|-
 +
|sumCase
 +
|3
 +
|Somme de l'attribut suivant une condition
 +
|sum(case B=C then A else 0)
 +
|-
 +
|sumSign
 +
|3
 +
|Somme signée de l'attribut suivant une condition
 +
|sum(case B=C then A else -A)
 +
|-
 +
|sumSens
 +
|3
 +
|Somme suivant le sens comptable (A=Credit, B=Débit, C=Sens, Sens=1=Débit)
 +
|sum(case C=1 then B-A else A-B)
 +
|}
 +
 
 +
====Opérateur portant sur une chaine====
 +
 
 +
{|class="wikitable"
 +
|-
 +
!Opérateur
 +
!Arguments
 +
!Action
 +
!Opération
 +
|-
 +
|concat
 +
|2
 +
|Concaténation de deux attributs chaîne
 +
|concat (A,B)
 
|}
 
|}
  
Ligne 437 : Ligne 923 :
 
!Action
 
!Action
 
|-
 
|-
|count (view ope)|count
+
|count
 
|1
 
|1
 
|Compte les éléments de la vue
 
|Compte les éléments de la vue
Ligne 505 : Ligne 991 :
 
|Réalise une jointure sur une référence
 
|Réalise une jointure sur une référence
 
|}
 
|}
 +
 +
====Opérateur DateAdd====
 +
 +
{{version11}}
 +
 +
DateAdd est un opérateur SQL pouvant être utilisé dans la partie littérale d'une expression.
 +
 +
<pre>
 +
dateAdd(dppart, colomn, number)
 +
</pre>
 +
 +
'''Exemple:'''
 +
<source lang="delphi">
 +
Type
 +
  vueSelection = viewOf(TSelectionCompte)
 +
  vc:TCompteGeneral = join('(codeCompte>=self.compteInferieur) and (codeCompte<=self.compteSuperieur)');
 +
  vp:TPeriode = join('(1=1)');
 +
  ve:TExercice = join(oid,vp.oidexercice);
 +
  ve1:TExercice = join('(?.dateDebut = DateAdd(dpyear,ve.dateDebut,-1))');
 +
  ....
 +
  end;
 +
</source>
 +
 +
====Opérateur GetValue====
 +
 +
{{version11}}
 +
 +
GetValue est un opérateur script pouvant être utilisé dans la partir littérale d'une expression.
 +
 +
<pre>
 +
  GetValue('expression')
 +
</pre>
 +
 +
'''Exemple :'''
 +
<source lang="delphi">
 +
  VueSoldeEcriture = viewOf(TEcriture,VueSoldeComptePeriode)
 +
    credit:Currency = credit:TCValue;
 +
    debit:Currency = debit:TCValue;
 +
    typeLot:Integer = piece.lot.typeLot;
 +
    codeCompte:string = compteGeneral.codeCompte;
 +
    captionCompte:string = compteGeneral.Caption;
 +
    sensCompte:Integer = compteGeneral.sensPrivilegie;
 +
    norme:string = piece.normeComptable.code;
 +
    eDate:Tdatetime = eDate notInSelect;
 +
    [eDate >= GetValue('begin Result := TFacadeInitGeneral.GetPreviousPeriodEndDate(Date); end;')]
 +
  end;
 +
</source>
  
 
===Agrégat portant sur un montant===
 
===Agrégat portant sur un montant===
Ligne 554 : Ligne 1 087 :
 
|sum (Value)
 
|sum (Value)
 
|}
 
|}
 +
 +
===Vue de modèle utilisant une vue locale===
 +
 +
{{version11}}
 +
 +
Les vues locales permettent d'exprimer des requêtes complexes qui ne peuvent pas être définies par une vue de modèle.
 +
 +
D'un autre coté, les vues définies dans le modèle peuvent être utilisées dans les interfaces et réutilisées dans le code métier.
 +
 +
Il est possible de définir une vue de modèle utilisant une vue locale pour exprimer la requêtes et bénéficier ainsi des avantages des deux types de vue.
 +
 +
Pour cela:
 +
 +
* Définissez une vue de modèle sur la classe désirée.
 +
* Ajouter les attributs supportés par la vue sans définir d'alias.
 +
* Ajouter une méthode de classe GetSelector retournant un sélecteur d'une vue locale.
 +
 +
'''Exemple :'''
 +
 +
<source lang="delphi">
 +
unit CptRubriques;
 +
interface
 +
 +
Type
 +
  TVueRubriqueCompte = Class(TSelectionCompte) as strView
 +
    {$O  modified="2023-09-26T08:15:16" label="Vue des comptes d'une rubrique" options=cloView viewOf=TSelectionCompte viewOrderBy="codeRubrique,codeCompte" viewPrimaryKey="oidCompteGeneral,oidRubrique"}
 +
  public
 +
    Class Function GetSelector():TSelector;
 +
    property codeCompte: String;
 +
    property codeRubrique: String;
 +
    property CompteGeneral: Ref of TCompteGeneral;
 +
    property libelleCompte: String;
 +
    property libelleRubrique: String;
 +
    property oidCompteGeneral: TOID;
 +
    property oidRubrique: TOID;
 +
    property oidSelectionCompte: TOID;
 +
    property Rubrique: Ref of TRubrique;
 +
    property SelectionCompte: Ref of TSelectionCompte;
 +
    property sensCompte: Enum(SensPrivilegie);
 +
    property sensMontant: Enum(SensRubriqueCpt);
 +
    property typeCollectif: Enum(TypeCollectif);
 +
    property typeCompte: Enum(TypeCompte);
 +
    property typeSelection: Enum(TypeCompte);
 +
  end;
 +
 +
{! DIR TVueRubriqueCompte}
 +
{$PO TVueRubriqueCompte.codeCompte label="Code compte"}
 +
{$PO TVueRubriqueCompte.codeRubrique label="Code rubrique"}
 +
{$PO TVueRubriqueCompte.CompteGeneral label="Compte général"}
 +
{$PO TVueRubriqueCompte.libelleCompte label="Libellé compte"}
 +
{$PO TVueRubriqueCompte.libelleRubrique label="Libellé rubrique"}
 +
{$PO TVueRubriqueCompte.SelectionCompte label="Selecteur de compte"}
 +
{$PO TVueRubriqueCompte.sensCompte label="Sens privilégié du compte"}
 +
{$PO TVueRubriqueCompte.sensMontant label="Sens du montant"}
 +
{$PO TVueRubriqueCompte.typeCollectif label="Type collectif du compte"}
 +
{$PO TVueRubriqueCompte.typeCompte label="Type du compte"}
 +
{$PO TVueRubriqueCompte.typeSelection label="Type dans la selection"}
 +
{!END DIR}
 +
 +
 +
{! DOC TVueRubriqueCompte}
 +
{!END DOC}
 +
 +
 +
Implementation
 +
 +
{! METHODS TVueRubriqueCompte}
 +
Class Function TVueRubriqueCompte.GetSelector():TSelector;
 +
Type
 +
  vueSelection = viewOf(TSelectionCompte distinct)
 +
  vp:TCompteGeneral = join('(codeCompte>=self.compteInferieur) and (codeCompte<=self.compteSuperieur)');
 +
  oidSelectionCompte:TOID = oid;
 +
  oidCompteGeneral:TOID = vp.oid primary;
 +
  oidRubrique:TOID = oidRubriqueCompte primary;
 +
  _Caption:string = concat(RubriqueCompte.Caption,vp.Caption) caption;
 +
  codeRubrique:string = RubriqueCompte.code orderby;
 +
  codeCompte:string = vp.codeCompte orderby;
 +
  libelleCompte:string = vp.Caption;
 +
  libelleRubrique:string = RubriqueCompte.Caption;
 +
  sensMontant:Integer = sensMontant;
 +
  typeSelection:Integer = typeCompte;
 +
  sensCompte:Integer = vp.sensPrivilegie;
 +
  typeCollectif:Integer = vp.typeCollectif;
 +
  typeCompte:Integer = vp.typeCompte;
 +
  end;
 +
 +
begin
 +
  Result := vueSelection.CreateSelector('','',True,[]);
 +
end;
 +
 +
{!END METHODS}
 +
end.
 +
</source>
 +
 +
 +
  
 
Voir aussi :
 
Voir aussi :
Ligne 562 : Ligne 1 191 :
 
[[Category:Vue de classe]]
 
[[Category:Vue de classe]]
 
[[Category:Version650]]
 
[[Category:Version650]]
 +
[[Category:Version11]]

Version actuelle en date du 11 novembre 2023 à 09:08

version650-32x32.png

Sommaire


Les vues locales sont des type de données vues déclarées localement à l'intérieur d'une opération.

Par exemple le code suivant déclare une vue MyView et effectue une recherche sur cette vue :

function foo(const S:string):Integer;
Type
  MyView = viewof(ClassA)
  unCode:string = unCodeA;
  unEntier:Integer = refB.unEntierB;
  end;
 
var inst:MyView;
begin
  inst := MyView.Find('unCode=%1','',true,['B1']);
  if Assigned(inst) then
   begin
     ...
   end;
end

Le périmètre du type est limité à la procédure, il n'est donc pas possible de passer les objets de la vue en paramètre à d'autres fonctions (pour cela utilisez une vue globale).

La syntaxe pour définir une vue locale :

  BNF style grammar : 

  <nom_vue> ::= ViewOf(<class_dec>) [<attributes>] end 
  <class_dec> ::= <class_names> | <class_name> <class_dec>
  <class_names> ::= <class_name>| [<class_name> ,]
  <class_name> ::= identifier
  <class_dec> ::= distinct
  <attributes> ::= <attribute_def> | <attribute_def> <where_def>
  <attribute_def> ::= <simple_attribute_def> | <simple_attribute_def> <attribute_directive> 
  <simple_attribute_def> ::= <attribute_dec> | <attribute_dec> = <attribute_ref>
  <attribute_dec> ::= <attribute_name> : <type_name>
  <attribute_ref> ::= <main_class_attribute_name> | <operator>(<main_class_attribute_name>)
  <operator> ::= <aggregate_operator> | <date_operator> | <join_operator>
  <aggregate_operator> ::= count|sum|max|min
  <date_operator> ::= year|month|quarter|week|day|dayofyear|dayofweek|hour|minute|second
  <join_operator> ::= join
  <attribute_directive> ::=  primary | orderby | orderby desc | over | notInSelect
  <where_def> ::= [ <expression> ]

  Type
    NomDeVue = ViewOf(NomDeClassePrincipale)
      Attribut : Type;
      Attribut : Type = AliasDe;
      Attribut : Type = operator(AliasDe);
      Attribut : Type = AliasDe primary;
      Attribut : Type = AliasDe orderby;
      Attribut : Type = AliasDe orderby desc;
      [ expression ]
    end;

Les vues peuvent utiles pour effectuer des traitement sur des classes complexes, par exemples :

Exemples

Curseur sur une classe vue

function foo(const S:string):Integer;
Type
  MyView = viewof(ClassA)
    newCode:string;
    unCode:string = unCodeA;
    unEntier:Integer = refB.unEntierB;
  end;
 
var inst:MyView; cursor:MyViewCursor
begin
  Result := 0;
  cursor := MyView.CreateCursorWhere(''unCode=%1'','''',true,[S]);
  foreach inst in cursor do
   begin
     Result := Result + inst.unEntier;
   end;
end;

Vue avec jointure externe

function ViewExternalJoin(const S:string):Boolean;
Type
  MyView = viewof(ClassA)
    newCode:string;
    unCodeAA:string = unCodeA;
    unCodeBB:string = refB+unCodeB;
  end;
var inst:MyView;
begin
  inst := MyView.Find('unCodeAA=%1','',true,[S]);
  if Assigned(inst) and (inst.unCodeAA=S)
     then Result := True
     else Result := False;
end;

Vue sur une interface

function foo(const S:string):Integer;
Type
  MyView = viewof(InterfaceA, ClassA1, ClassA2)
    unCode:string = unCodeA primary;
    ....
  end;
 
begin
  ...
end;

Vue sur des combinaisons uniques d'attributs

function foo(const S:string):Integer;
Type
  MyView = viewof(ClassA distinct)
    unCode:string = unCodeA primary;
    unEntier:Integer = refB.unEntierB;
  end;
 
begin
  ...
end;

Vue avec agrégats

function foo(const S:string):Integer;
Type
  MyView = viewof(ClassA)
    unCode:string = unCodeA primary;
    unEntier:Integer = sum(unEntier);
  end;
 
begin
  ...
end;

Vue avec agrégats sur un montant

Type
  myView = viewof(WFClasseX)
   mysum:TMoney = sum(credit) orderby;
  end;
 
var sel:TSelector; inst:MyView; S,stag:string;
begin
  sel := MyView.CreateSelector('','',true,[]);
 
  S := ''; stag := '';
  foreach inst in Sel.AsCursor do
   begin
     S := S+stag+Formatfloat('0.00',inst.mysum.Value);
     stag := ',';
   end;
  showmessage(S);
 
  Result := FALSE;
end;
select sum(t0.credit) "mysum",t0.credit_CodeDevise "mysum_CodeDevise" from dbo.WFCLASSEX t0
group by t0.credit_CodeDevise
order by sum(t0.credit)

Vue avec agrégats sur un attribut enfant

Type
  myView = viewof(WFClasseX)
   mysum:TMoney = sum(credit:TCValue) orderby;
  end;
begin
  ...
end;
select sum(t0.credit_TCValue) "mysum" from dbo.WFCLASSEX t0
order by sum(t0.credit_TCValue)

Vue avec un opérateur de date

function foo(const S:string):Integer;
Type
  MyView = viewof(ClassC distinct)
    unCode:string = unCodeC primary;
    unMois:Integer = month(uneDate);
  end;
 
begin
  ...
end;

Vue avec un opérateur de date (diff)

function foo(iDayDiff):string;
Type
  MyView = viewof(ClassC distinct)
    unCode:string = unCodeC primary;
    DayDiff:Integer = DayDiff(uneDateStart,uneDateEnd);
  end;
 
begin
  inst := MyView.Find('DayDiff >= %1','',true,[iDayDiff]);
    if Assigned(inst)
       then Result := inst.unCode
       else Result := 'Not found';
end;

Vue avec référence

function foo(const S:string):Integer;
Type
  MyView = viewof(ClassA)
    unCodeAA:string = unCodeA;
    refB:reference = refB;
  end;
 
begin
  ...
end;
function foo(const S:string):Integer;
Type
  MyView = viewof(ClassA)
    unCodeAA:string = unCodeA;
    refB:ClassB = refB;
  end;
 
begin
  ...
end;

Vue avec variable référence

function foo(const S:string):Integer;
Type
  MyView = viewof(ClassA)
    unCodeAA:string = unCodeA;
    refB:ClassB;
  end;
 
begin
  ...
end;

Vue avec filtre

function foo(const S:string):Integer;
Type
  MyView = viewof(ClassA)
    unCodeAA:string = unCodeA;
    unCodeBB:string = refB.unCodeB;
    [ unCodeA='A1' ]
  end;
 
begin
  ...
end;

Vue avec traversée de liste

View-list-1.jpg

function _Concat(const S:string):string;
Type
  MyView = viewof(ClassF)
    unCodeF:string = unCodeF;
    unCodeG:string = refFG.unCodeG;
    unCodeH:string = refFG.listH.unCodeH;
  end;
 
var ls:MyViewList; stag:string; idx:integer;
begin
  ls := MyView.CreateListWhere('unCodeG=%1','','unCodeH',true,-1,[S]);
  Result := ''; stag := '';
  for idx:=0 to ls.Count-1 do
   begin
     Result := Result+stag+ls.Refs[idx].unCodeH;
     stag := ',';
   end;
end;

Vue avec jointure sur une classe

Type
  myView = class(myClass)
    vp1:joinClass1 = join(A,B);
    vp2:JoinClass2 = join(A,B,W);
    vp3:JoinClass3 = join(W);
    ....
  end;
Paramètre Usage
A Attribut de la classe join (joinClass)
B Chemin à partir de la classe base (myView)
W Clause Where sur la classe join

La clause Where peut être exprimée avec les préfixes :

self Préfixe de la classe de base
? Préfixe de la classe Join
xx alias d'une jointure de classe
Tip-20px.png Tip : Il est possible de créer un produit cartésien entre deux classes en utilisant une jointure avec une clause where toujours vraie.
Tip-20px.png Tip : Les jointures seront générées dans l'ordre de leur déclaration dans la vue.
//Procedure expensePendings(req:Tjson; var res:TObject);
Type
  ExpenseView = viewOf(TNoteFrais)
   vp: TValideurPossible = join(ValidationEtat.EtatPossible.EtatMetier, EtatNF);
   aManager:string = vp.ContactEtablissement.oidutilisateur;
   //
   aDate:TDatetime = nDate;
   aRef:string = referencePiece;
   aReason:string = Caption;
   aAmountOrg:TMoney = MontantTTC;
   aAmountAct:TMoney = MontantRetenu;
   aQuantity:TQuantity = Quantite;
   aUser:string = Salarie.Operateur.oidutilisateur;
   aType:string = FraisSalarie.Caption;
   aMode:Integer = FraisSalarie.modeRemboursement;
   aAmountMax:TMoney = FraisSalarie.montantPlafond;
   aStatus:Integer = Statut;
  end;
 
var json:TJson; ls:TSelector; indx,ctn:Integer; inst:ExpenseView;
    AWhere,AOrder:string; Args:Array[0..5] of variant;
begin
  json := TJson.Create('');
  res  := json;
  //
  AWhere := '(aManager=%1) and (aStatus=%2)';
  Args[0] := GlbUserName;
  Args[1] := StatutNF_AValider;
  AOrder := 'aUser,-aDate';
 
  indx := 0; ctn := 0; 
  ls := ExpenseView.CreateSelector(AWhere,AOrder,true,Args);
  foreachP inst in ls.AsCursor do
   begin
     . . . 
   end;
end;

Dans cet exemple le modèle est celui-ci :

View-join-2.jpg

La classe TEtatMetier est atteinte par deux chemins différents, un issu de la classe TValideurPossible et un issu de la classe TNoteFrais. La jointure est réalisée sur l'objet TEtatMetier.

   vp: TValideurPossible = join(ValidationEtat.EtatPossible.EtatMetier, EtatNF);
  • TValideurPossible est la classe qui va être jointe
  • vp défini un alias sur cette classe qui peut être ensuite utilisé dans la définition de la vue.
  • ValidationEtat.EtatPossible.EtatMetier est le chemin issu de la classe jointe
  • EtatNF est le chemin issu de la classe de la vue.


Exemple, vue locale avec produit cartésien, jointure par clause where et sous requêtes

//procedure RubriqueParExerciceDetail;
Type
  vueSolde = viewof(TCumulPeriodeCompte)
   codeCompte:string = CompteGeneral.codeCompte;
   datePeriode:TDatetime = Periode.dateDebut;
   value:Currency = sumDiff(debitTenue,creditTenue); 
   oidExercice:TOID = Periode.oidexercice; 
   [(typeLot=1)] 
  end;
 
  vueSelection = viewOf(TSelectionCompte) 
   vc:TCompteGeneral = join('(codeCompte>=self.compteInferieur) and (codeCompte<=self.compteSuperieur)');
   vp:TPeriode = join('(1=1)'); 
   ve:TExercice = join(oid,vp.oidexercice); 
   ve1:TExercice = join('(?.dateDebut = DateAdd(dpyear,ve.dateDebut,-1))');
  // 
   idCompteGeneral:TOID = vc.oid primary; 
   idRubrique:TOID = oidRubriqueCompte primary; 
   idPeriode:TOID = vp.oid primary;
   idExercice:TOID = vp.oidexercice; 
   idExerciceN1:TOID = ve1.oid;
   // 
   codeRubrique:string = RubriqueCompte.code orderby; 
   libelleRubrique:string = RubriqueCompte.Caption; 
   codeCompte:string = vc.codeCompte orderby;
   libelleCompte:string = vc.Caption; 
   libellePeriode:string = vp.Caption; 
   // 
   datePeriode:TDatetime = vp.dateDebut orderby desc;
   year:Integer = year(vp.dateDebut);
   month:Integer = month(vp.dateDebut);
   valueN0:currency = VueSolde.select('value','(oidExercice=self.idExercice) and  (codeCompte=self.codeCompte) and (datePeriode<=self.datePeriode)','',true,[]); 
   valueN1:currency = VueSolde.select('value','(oidExercice=self.idExerciceN1) and  (codeCompte=self.codeCompte) and (datePeriode<=DateAdd(dpYear,self.datePeriode,-1))','',true,[]); 
 end; 
 
var Sel:TSelector; inst:vueSelection; S,stag:string;
begin
  Sel   := vueSelection.CreateSelector('(codeRubrique=%1) and (year=2022) and (month=3)','',True,['SIG.L02']);
 
  S := ''; stag := ''; 
  forEach inst in Sel.AsCursor do
   begin
     S := S+stag+inst.codeCompte;
     stag := ','; 
   end; 
  showMessage(S); 
end;
Tip-20px.png Tip : Notez l'opérateur SQL DateAdd() qui peut être utilisé dans la partie littérale d'une expression

Vue avec jointures liées

Version11-32x32.png

 Type
  VueValideur = viewOf(TPieceTaxable)
   vp1: TValideurPossible = join(ValidationEtat.EtatPossible.EtatMetier,EtatMetier);
   vp2: TValideurPossible = join(ValidationEtat.RegleValidation,RegleValidation);
   gcv: TGroupeContactValidation = leftjoin(TGroupeValidation,vp2.ContactEtablissement); 
   aId1:TOID = vp1.oid;
   aId2:TOID = vp2.oid; 
   // 
   ...
   [ (aId1=aId2) and ... ] 
  end;

Dans cet exemple :

  • vp1 et vp2 sont deux jointures qui coincident sur le même tuple.
  • La coincidence des deux jointures est réalisée par le clause where (aId1=aId2)
  • gcv est une jointure sur le tuple défini par vp1 et vp2

Vue avec sous requêtes

Version11-32x32.png

Il est possible de générer une sous requête liée à la requête principale en utilisant la méthode SELECT d'un sélecteur.

La sous requêtes doit être liée à la requête principale en utilisant l'opérateur self dans la clause Where du SELECT.

Une sous requêtes peut être utilisée soit dans la liste des colonnes, soit dans la clause Where du selecteur.

Utilisation dans les colonnes :

Type
  Vue1 = viewOf(MyClass)
   sub1:TMoney = sum(...);
   id1:TOID = ....;
   ....
  end;
 
  Vue2 = viewOf(MyClass)
   sum1:TMoney = sum(...);
   sum2:TMoney = Vue1.Select('sub1','(id1=self.id2)','',true,[]);
   id2:TOID = ...;
   ....
  end;
 
var sel:TSelector;
begin
  sel := Vue2.CreateSelector('','',true,[]);
  //
  ... 
end;

Utilisation dans la clause Where :

Type
  Vue1 = viewOf(MyClass)
   sub1:TMoney = sum(...);
   id1:TOID = ....;
   ....
  end;
 
  Vue2 = viewOf(MyClass)
   sum1:TMoney = sum(...);
   id2:TOID = ...;
   ....
  end;
 
var sel:TSelector;
begin
  sel := Vue2.CreateSelector('(sum1>%1)','',true,[
    Vue1.Select('sub1','(id1=self.id2)','',true,[])
  ]);
  //
  ... 
end;

Avec des paramètres :

Il est possible de paramétrer une sous requête en utilisant les paramètres de la requête principale :

Type
  Vue1 = viewOf(MyClass)
   sub1:TMoney = sum(...);
   id1:TOID = ....;
   col1:string = ...;
   col2:Integer = ...;
   ....
  end;
 
  Vue2 = viewOf(MyClass)
   sum1:TMoney = sum(...);
   sum2:TMoney = Vue1.Select('sub1','(id1=self.id2) and (col=%1) and (col2=%2)','',true,[]);
   id2:TOID = ...;
   ....
  end;
 
var sel:TSelector;
begin
  sel := Vue2.CreateSelector('','',true,['valueCol1',1,....]);
  //
  ... 
end;

Vue avec interface (Union)

Version11-32x32.png

Il est possible d'utiliser une interface pour générer une union de plusieurs vues locales supportant cette interface

Exemple :

Type
  ISoldeCompte = interface
    credit:Currency;
    debit:Currency; 
    typeLot:Integer;
    codeCompte:string;
    captionCompte:string;
    sensCompte:Integer;
    norme:string;
  end; 
 
  VueSoldeComptePeriode = viewOf(TCumulPeriodeCompte,ISoldeCompte)
    credit:Currency = creditTenue;
    debit:Currency = debitTenue;
    typeLot:Integer = typeLot; 
    codeCompte:string = compteGeneral.codeCompte;
    captionCompte:string = compteGeneral.Caption;
    sensCompte:Integer = compteGeneral.sensPrivilegie; 
    norme:string = normeComptable.code; 
    dateFin:Tdatetime = Periode.dateFin notInSelect;
    [dateFin < GetDate] 
  end; 
 
  VueSoldeEcriture = viewOf(TEcriture,VueSoldeComptePeriode)
    credit:Currency = credit:TCValue;
    debit:Currency = debit:TCValue;
    typeLot:Integer = piece.lot.typeLot; 
    codeCompte:string = compteGeneral.codeCompte;
    captionCompte:string = compteGeneral.Caption; 
    sensCompte:Integer = compteGeneral.sensPrivilegie; 
    norme:string = piece.normeComptable.code; 
    eDate:Tdatetime = eDate notInSelect; 
    [eDate >= GetValue('begin Result := TFacadeInitGeneral.GetPreviousPeriodEndDate(Date); end;')] 
  end; 
 
  VueSoldeCompte = viewOf(ISoldeCompte,VueSoldeComptePeriode,VueSoldeEcriture)
    solde:Currency = sumSens(credit,debit,sensCompte);
    typeLot:Integer = typeLot;
    codeCompte:string= codeCompte;
    captionCompte:string = captionCompte; 
    sensCompte:Integer = sensCompte; 
    norme:string= norme notInSelect;
  end;   
 
var ls:TSelector; inst:VueSoldeCompte; doc:TxmlhtmlMailDocument; Table:ThtmlTable; ANorme1,ANorme2:string;
begin
  ls := VueSoldeCompte.CreateSelector('(codeCompte like %1) and (typeLot=%2) and ((norme=%3)or(norme=%4))','',true,[
    _StrLike(prefixeCompte),
    typeLot.Value,
    ANorme1,
    ANorme2 
    ]);
 
  ...
end;


Vue utilisant une CTE (Commun table expression)

Version11-32x32.png

Il est possible de générer une requête CTE :

  • En utilisant une directive "over" dans la définition d'une colonne
  • En positionant la propriété useCTE sur le sélecteur.

Le code SQL généré sera

With CTE AS (
)
SELECT * from CTE 

Lorsqu'une CTE est utilisée la clause Where du sélecteur s'applique sur résultat de la CTE.

Type
  Vue1 = viewOf(MyClass)
   sub1:TMoney = sum(...);
   id1:TOID = ....;
   ....
  end;
 
  Vue2 = viewOf(MyClass)
   sum1:TMoney = sum(...);
   sum2:TMoney = Vue1.Select('sub1','(id1=self.id2)','',true,[]);
   id2:TOID = ...:
  end;
 
var sel:TSelector;
begin
  sel := Vue2.CreateSelector('(sum1 > sum2)','',true,[]);
  sel.UseCTE := True;  
  //
  ... 
end;

Directive d'attribut

Version11-32x32.png

Directive Action
notInSelect L'attribut ne sera pas généré dans clause select
over L'attribut est généré par rapport à la requête CTE

Directive primary

Version11-32x32.png

Une vue peut contenir plusieurs directives primary de type oid

Dans ce cas l'identifiant d'un objet de la vue sera une liste identifiants.

Directive orderby

Version11-32x32.png

Une vue peut contenir plusieurs directives orderby

Dans ce cas l'ordre de tri sera défini par la liste des attributs, dans l'ordre de leur déclaration dans la vue.

Opérateurs

Opérateur portant sur une colonne

Version11-32x32.png

Opérateur Arguments Action Opération
isNull 2 Retourne la valeur de la colonne 2 si la valeur de la colonne 1 est nulle case A is NULL then B else A

Exemple d'utilisation de isNull

 Type
  VueValideur = viewOf(TPieceTaxable)
   vp1: TValideurPossible = join(ValidationEtat.EtatPossible.EtatMetier,EtatMetier);
   vp2: TValideurPossible = join(ValidationEtat.RegleValidation,RegleValidation);
   gcv: TGroupeContactValidation = leftjoin(TGroupeValidation,vp2.ContactEtablissement); 
   aId1:TOID = vp1.oid;
   aId2:TOID = vp2.oid; 
   aIdVP:TOID = vp2.oidValideurPrecedent;
   aIdDV:TOID = oiddernierValideur; 
   aIdCV:TOID = vp2.oidContactEtablissement; 
   // contact établissement valideur, peut être membre du groupe de validation ou le valideur défini par la règle
   aIdCE:TOID = ISNULL(gcv.oidTContactEtablissement,vp2.oidContactEtablissement); 
   // personne 
   Mail:string = ISNULL(gcv.TContactEtablissement+eMail,vp2.ContactEtablissement.eMail); 
   // 
   [ (aId1=aId2) ... ] 
  end;

Opérateur portant sur un type numérique

Opérateur Arguments Action Opération
sum 1 Effectue la somme de l'attribut sum(A)
min 1 Retourne le minimum de l'attribut min(A)
max 1 Retourne le max de l'attribut max(A)
add 2 Retourne la somme de deux attributs A+B
sub 2 Retourne la différence entre deux attributs A-B
mul 2 Retourne la multiplication de deux attributs A*B
div 2 Retourne la divition de deux attributs A/B
percent 2 Retourne le poucentage entre deux attributs case when B=0 then 0 else (100*A / B) end
sumdiff 2 Retourne la somme de la différence entre deux attributs sum(A-B)
sumdiff2 3 Retourne la somme de la différence entre trois attributs sum(A+B-C)
mindiff 2 Retourne le min de la différence entre deux attributs min(A-B)
maxdiff 2 Retourne le max de la différence entre deux attributs max(A-B)
sumconcat 2 Retourne la somme de la somme entre deux attributs sum(A+B)
minconcat 2 Retourne la min de la somme entre deux attributs min(A+B)
maxconcat 2 Retourne le max de la somme entre deux attributs max(A+B)
count 1 Compte le nombre de lignes count(*)

version900-32x32.png

Opérateur Arguments Action Opération
sumDiffP 2 Retourne la somme de la différence si elle positive et 0 sinon. case sum(A-B)>0 then sum(A-B) else 0
sumDiffA 2 Retourne la valeur absolue de la différence. ABS(sum(A-B))
sumDiffS 2 Retourne le signe de la différence case sum(A-B)>0 then 1 else 0

Version11-32x32.png

Opérateur Arguments Action Operation
sum 1,2,3 Effectue la somme des attributs sum(A), sum(A+B),sum(A+B+C)
sumCase 3 Somme de l'attribut suivant une condition sum(case B=C then A else 0)
sumSign 3 Somme signée de l'attribut suivant une condition sum(case B=C then A else -A)
sumSens 3 Somme suivant le sens comptable (A=Credit, B=Débit, C=Sens, Sens=1=Débit) sum(case C=1 then B-A else A-B)

Opérateur portant sur une chaine

Opérateur Arguments Action Opération
concat 2 Concaténation de deux attributs chaîne concat (A,B)

Opérateur portant sur OID

Opérateur Arguments Action
count 1 Compte les éléments de la vue

Opérateur portant sur une date

Ces opérateur prennent une date comme argument.

Opérateur Arguments Action
year 1 Retourne l'année de la date
quarter 1 Retourne le trimestre de la date
month 1 Retourne le mois de la date
dayofyear 1 Retourne le jour de l'année de la date
dayofweek 1 Retourne le jour de la semaine de la date
hour 1 Retourne le nombre d'heures de la date
minute 1 Retourne le nombre de minutes de la date
second 1 Retourne le nombre de secondes de la date
millisecond 1 Retourne le nombre de millisecondes de la date
daydiff 2 Retourne le nombre de jour entre deux dates

Opérateur portant sur une référence

Opérateur Arguments Action
join 2 Réalise une jointure sur une référence

Opérateur DateAdd

Version11-32x32.png

DateAdd est un opérateur SQL pouvant être utilisé dans la partie littérale d'une expression.

 dateAdd(dppart, colomn, number)

Exemple:

Type
  vueSelection = viewOf(TSelectionCompte) 
   vc:TCompteGeneral = join('(codeCompte>=self.compteInferieur) and (codeCompte<=self.compteSuperieur)');
   vp:TPeriode = join('(1=1)'); 
   ve:TExercice = join(oid,vp.oidexercice); 
   ve1:TExercice = join('(?.dateDebut = DateAdd(dpyear,ve.dateDebut,-1))');
   ....
  end;

Opérateur GetValue

Version11-32x32.png

GetValue est un opérateur script pouvant être utilisé dans la partir littérale d'une expression.

  GetValue('expression')

Exemple :

  VueSoldeEcriture = viewOf(TEcriture,VueSoldeComptePeriode)
    credit:Currency = credit:TCValue;
    debit:Currency = debit:TCValue;
    typeLot:Integer = piece.lot.typeLot; 
    codeCompte:string = compteGeneral.codeCompte;
    captionCompte:string = compteGeneral.Caption; 
    sensCompte:Integer = compteGeneral.sensPrivilegie; 
    norme:string = piece.normeComptable.code; 
    eDate:Tdatetime = eDate notInSelect; 
    [eDate >= GetValue('begin Result := TFacadeInitGeneral.GetPreviousPeriodEndDate(Date); end;')] 
  end;

Agrégat portant sur un montant

C'est le type de l'attribut défini dans la vue qui détermine le résultat de l'agrégation.

Les opération d'agrégation effectuent un groupement par devise et agrègent les valeurs de montant (en devise, tenue de compte et reporting). Les chaînes de conversion sont à vides et la date de cours est la date du jour.

Type Source Type Vue Opération
source:Money vue:Money = sum(source) sum(Value) group by CodeDevise
source:MoneyDT vue:Money = sum(source) sum(Value) group by CodeDevise
source:Money vue:MoneyDT = sum(source) ** ERREUR **
source:MoneyDT vue:MoneyDT = sum(source) sum(Value) group by CodeDevise
source:Money vue:Currency = sum(source) sum (Value)
source:MoneyDT vue:Currency = sum(source) sum (Value)
source:MoneyDT vue:Currency = sum(source:TCValue) sum (TCValue)
source:MoneyDT vue:Currency = sum(source:RPValue) sum (RPValue)
source:Currency vue:Currency = sum(source) sum (Value)

Vue de modèle utilisant une vue locale

Version11-32x32.png

Les vues locales permettent d'exprimer des requêtes complexes qui ne peuvent pas être définies par une vue de modèle.

D'un autre coté, les vues définies dans le modèle peuvent être utilisées dans les interfaces et réutilisées dans le code métier.

Il est possible de définir une vue de modèle utilisant une vue locale pour exprimer la requêtes et bénéficier ainsi des avantages des deux types de vue.

Pour cela:

  • Définissez une vue de modèle sur la classe désirée.
  • Ajouter les attributs supportés par la vue sans définir d'alias.
  • Ajouter une méthode de classe GetSelector retournant un sélecteur d'une vue locale.

Exemple :

unit CptRubriques;
interface
 
Type
  TVueRubriqueCompte = Class(TSelectionCompte) as strView
    {$O  modified="2023-09-26T08:15:16" label="Vue des comptes d'une rubrique" options=cloView viewOf=TSelectionCompte viewOrderBy="codeRubrique,codeCompte" viewPrimaryKey="oidCompteGeneral,oidRubrique"}
  public
    Class Function GetSelector():TSelector;
    property codeCompte: String;
    property codeRubrique: String;
    property CompteGeneral: Ref of TCompteGeneral;
    property libelleCompte: String;
    property libelleRubrique: String;
    property oidCompteGeneral: TOID;
    property oidRubrique: TOID;
    property oidSelectionCompte: TOID;
    property Rubrique: Ref of TRubrique;
    property SelectionCompte: Ref of TSelectionCompte;
    property sensCompte: Enum(SensPrivilegie);
    property sensMontant: Enum(SensRubriqueCpt);
    property typeCollectif: Enum(TypeCollectif);
    property typeCompte: Enum(TypeCompte);
    property typeSelection: Enum(TypeCompte);
  end;
 
{! DIR TVueRubriqueCompte}
{$PO TVueRubriqueCompte.codeCompte label="Code compte"}
{$PO TVueRubriqueCompte.codeRubrique label="Code rubrique"}
{$PO TVueRubriqueCompte.CompteGeneral label="Compte général"}
{$PO TVueRubriqueCompte.libelleCompte label="Libellé compte"}
{$PO TVueRubriqueCompte.libelleRubrique label="Libellé rubrique"}
{$PO TVueRubriqueCompte.SelectionCompte label="Selecteur de compte"}
{$PO TVueRubriqueCompte.sensCompte label="Sens privilégié du compte"}
{$PO TVueRubriqueCompte.sensMontant label="Sens du montant"}
{$PO TVueRubriqueCompte.typeCollectif label="Type collectif du compte"}
{$PO TVueRubriqueCompte.typeCompte label="Type du compte"}
{$PO TVueRubriqueCompte.typeSelection label="Type dans la selection"}
{!END DIR}
 
 
{! DOC TVueRubriqueCompte}
{!END DOC}
 
 
Implementation
 
{! METHODS TVueRubriqueCompte}
Class Function TVueRubriqueCompte.GetSelector():TSelector;
Type
  vueSelection = viewOf(TSelectionCompte distinct) 
   vp:TCompteGeneral = join('(codeCompte>=self.compteInferieur) and (codeCompte<=self.compteSuperieur)');
   oidSelectionCompte:TOID = oid; 
   oidCompteGeneral:TOID = vp.oid primary;
   oidRubrique:TOID = oidRubriqueCompte primary; 
   _Caption:string = concat(RubriqueCompte.Caption,vp.Caption) caption;
   codeRubrique:string = RubriqueCompte.code orderby; 
   codeCompte:string = vp.codeCompte orderby;
   libelleCompte:string = vp.Caption; 
   libelleRubrique:string = RubriqueCompte.Caption; 
   sensMontant:Integer = sensMontant; 
   typeSelection:Integer = typeCompte; 
   sensCompte:Integer = vp.sensPrivilegie;
   typeCollectif:Integer = vp.typeCollectif;
   typeCompte:Integer = vp.typeCompte; 
  end; 
 
begin
  Result := vueSelection.CreateSelector('','',True,[]);
end;
 
{!END METHODS}
end.



Voir aussi :





Whos here now:   Members 0   Guests 0   Bots & Crawlers 1
 
Outils personnels