« Version 2025 r2 (release note) » : différence entre les versions

De Wiki1000
 
(22 versions intermédiaires par le même utilisateur non affichées)
Ligne 3 : Ligne 3 :


''' PREVIEW '''
''' PREVIEW '''
==Langage==
* Valeur par défaut de paramètre
: Il est possible de définir des valeurs par défaut aux paramètres des méthodes
<source lang="delphi">
  MyClass = Class(TitObject)
    Procedure TestDeffParams;
    Procedure TestDefParamBool(p1:string; p2:boolean=true);
    Procedure TestDefParamJson(p1:string; p2:TJson=nil);
    Procedure TestDefParamJson2(p1:string; p2:TJson='{a:false}');
    Procedure TestDefParamEnum(p1:string; p2:Integer=WFCAState_Etat2);
    Procedure TestDefParamMulti(p1:string; p2:string='a'; p3:string='b');
    Function TestDefParamOne(p1:string='a'):string;
    Function TestDefParamFunc(p1:string='a'):string;
  end;
Procedure MyClass.TestDeffParams;
var V:string;
begin
  V := TestDefParamFunc('c');
  ShowMessage(V);
 
  TestDefParamOne;
  TestDefParamOne();
  TestDefParamOne('x');
 
  TestDefParamMulti('a');
  TestDefParamMulti('a','1');
  TestDefParamMulti('a','1','2');
 
  TestDefParamBool('a');
  TestDefParamBool('a',false);
  TestDefParamBool('a',true);
 
  TestDefParamJson2('b');
  TestDefParamJson2('b','{a:true}');
  TestDefParamEnum('c');
  TestDefParamEnum('c',WFCAState_Final);
end;
</source>
* Paramètre de type classe
: Les paramètres de type classe peuvent être passé directement
<source lang="delphi">
Type
  MyClass1 = class
    class procedure foo(rg:TRegClass);
  end;
  MyClass2 = class
    ....
  end;
  MyClass3 = class
    procedure oldbar();
    procedure newbar();
  end;
class procedure MyClass1.foo(rg:TRegClass);
begin
  // => MyClass2
  showMessage(rg.aClassName);
end;
procedure MyClass3.oldbar();
var rg:TRegClass;
begin
  ModelManager.FindClass('MyClass2');
  myClass1.foo(rg);
end;
procedure MyClass3.newbar();
begin
  myClass1.foo(MyClass2);
end;
</source>
==Json==
* Opérateur In
: Un json de type structure supporte l'opérateur In
<source lang="delphi">
Procedure TestJson;
function _foo(p:TJson):boolean;
begin
  Result := false;
  if 'a' in p then
    begin
      Result := True;
    end;
end;
var js:TJson;
begin
  js := TJson.Create('{a:true}');
  if _foo(js) then showMessage('ok') else showMessage('nok');
end;
</source>
* Getter et Setter
: Un json de type structure supporte l'accès direct aux valeur des membres
<source lang="delphi">
Procedure TestJson;
function _foo(p:TJson):boolean;
begin
  Result := false;
  if 'a' in p then
    begin
      Result := p['a'];
    end;
end;
var js:TJson;
begin
  js := TJson.Create('{a:true}');
  js['b'] := False;
  js['a'] := not js['b'];
  if _foo(js) then showMessage('ok') else showMessage('nok');
end;
</source>
* Constructeur implicite
: Un paramètre TJson peut être instancié à partir d'une chaine de caractère
<source lang="delphi">
Procedure TestJson;
function _foo(p:TJson):boolean;
begin
  Result := false;
  if 'a' in p then
    begin
      Result := p['a'];
    end;
end;
begin
  if _foo('{a:true}') then showMessage('ok') else showMessage('nok');
end;
</source>
* Enumérateurs
: Un json de type strutucture supporte l'énumérateur sur les clés
: Un json de type tableau supporte l'énumérateur sur les éléments
<source lang="delphi">
//Procedure TestJson;
procedure _enumValues(p:TJson);
var i:Integer; V:Variant;
begin
  forEach V in p index i do
    begin
      showMessageFmt('%d:%s',[i,V]);
    end;
end;
procedure _enumKeys(p:TJson);
var i:Integer; Key,Keys,stag:string;
begin
  Keys := ''; stag := '';
  forEach key in p index i do
    begin
      Keys := Keys+stag+inttostr(i)+':'+key;
      stag := ',';
    end;
  showMessage(Keys);
end;
begin
  _enumKeys('{a:true, b:false}');
  _enumValues('[{a:true, b:false},{a:false, b:true}]');
end;
</source>
==Modèle==
===Classes===
* Méthode AllocOID
<source lang="delphi">class function AllocOID:TOID;</source>
* Alloue un oid de la classe
: Peut être utile dans les tests unitaires
* Méthode ToJson()
<source lang="delphi">procedure ToJson(SA:variant);</source>
* Sérialize l'objet en json
: SA peut être un TJsonArray ou un TJsonStruct
===Classes SQL===
* Options de rôle : NoRefIndex
* Options de rôle : NoForeignKey


==Script==
==Script==
===Trace===
<source lang="delphi">procedure dbgClear();</source>
: Vide la trace
<source lang="delphi">procedure dbgEnable(value:boolean);</source>
: Active / désactive la trace


===Vue locale===
===Vue locale===
* Une vue locale peut contenir des attributs "oidXXX" sans définir le rôle
'''Exemple:'''
<source lang="delphi">
Type
  vue1 = viewOf(ClassA)
  p1:TEnum(enumName) = ...;
  oidRef:TOID = oidrefB;
  ..
  idRefB:TOID = oidrefB notInSelect;
  [ (idRefB=%ArgRefB) and ....]
  end;
</source>
* Une vue locale peut contenir des attributs non mappés dans la définition.
'''Exemple:'''
<source lang="delphi">
Type
  vue1 = viewOf(ClassA)
    ACount:Integer = count(oid)
    oidRef:TOID;
    codeRef:string;
    libelleRef:string;
  ..
  [  ...]
  end;
var sel:TSelector;
begin
  sel := vue1.createSelector();
  case iGroupBy of
  'refB':
    begin
      sel.AddColumn('oidrefB','oidRef');
      sel.AddColumn('refB.code','codeRef');
      sel.AddColumn('refB.Caption','libelleRef');
    end;
  'refC':
    begin
      sel.AddColumn('oidrefC','oidRef');
      sel.AddColumn('refC.code','codeRef');
      sel.AddColumn('refC.Caption','libelleRef');
    end;
  end;
end;
</source>


* Paramètre de type de donnée
* Paramètre de type de donnée
Ligne 14 : Ligne 278 :
   vue1 = viewOf(ClassA)
   vue1 = viewOf(ClassA)
   p1:TEnum(enumName) = ...;
   p1:TEnum(enumName) = ...;
  end;
</source>
* Qualifier d'attribut NotInGroupBy
<source lang="delphi">
Type
  vue1 = viewOf(ClassA)
  p1:string = expression('...') notInGroupBy;
   end;
   end;
</source>
</source>
Ligne 28 : Ligne 301 :
   vue2 = viewOf(vue1)
   vue2 = viewOf(vue1)
   p1:string = ...;
   p1:string = ...;
   [inherited]
   [inherited and (...)]
  end;
</source>
 
'''Exemple:'''
 
<source lang="delphi">
//function GetSelector(iGroupBy:string; iFilter:TJsonArray):TSelector;
Type
  // défini une classe de base avec tous les filtres
  //
  vueEcritureLettrage = viewOf(TEcriture)
    lettrable:boolean = compteGeneral.lettrable notInSelect;
    idEtablissement:TOID = piece.oidEtablissement notInSelect;
    idCompteGeneral:TOID = oidCompteGeneral notInSelect;
    idRoleTiers:TOID = oidroleTiers notInSelect;
    [(lettrable=true)
      and ((oidLettrageEcriture='') or (dateLettrage=0))
      and (typeEcriture<>0)
      and (piece.lot.origineLot<>0)
      and (eDate>=%ArgDateInf)
      and (eDate<=%ArgDateSup)
      and (idEtablissement=%ArgEtablissement)
      and (idCompteGeneral=%ArgCompteGeneral)
      and (idRoleTiers=%ArgRoleTiers)
    ]  
   end;
   end;
  // Hérite de tous les filtres
  //
  vueEcritureLettrageGroupBy = viewOf(vueEcritureLettrage)
    dateMin:TDatetime = min(eDate);
    dateMax:TDatetime = max(eDate);
    ACount:Integer = count(oid);
    credit:Currency = sum('credit:TCValue');
    debit:Currency = sum('debit:TCValue');
    solde:Currency = sumDiff(debit,credit);
    [inherited]
  end;
begin
  Result := vueLettrageGroupBy.CreateSelector('','',True,[]);
end;
</source>
</source>


* Scope de vue locale
* Scope de vue locale


Une vue locale peut être référencée en dehors de la méthode ou elle est définie.
Une vue locale peut être référencée en dehors de la méthode elle est définie.


<source lang="delphi">
<source lang="delphi">
Ligne 59 : Ligne 373 :


Une expression existe peut être utilisée dans les filtres comme une valeur logique
Une expression existe peut être utilisée dans les filtres comme une valeur logique
Note : Une expression Exists() est beaucoup plus rapide qu'un "Count<>0"


<source lang="delphi">
<source lang="delphi">
Ligne 71 : Ligne 387 :
   [(bb=true) and (....)]
   [(bb=true) and (....)]
   end;
   end;
</source>
* Expression de Sous requête
Une expression peut être définie par une sous requête
<source lang="delphi">
Type
  VueTauxADate = ViewOf(TTauxADate)
    idTVA : TOid = oidTVA;
    tDate : Date = tDate;
    taux : float = taux;
  end;
  vueMontantTVA = viewOf(TEcriture)
    dateEcriture:TDatetime=eDate notInSelect;
    oidTVA:TOID = ProfilTVA.oidTVA notInSelect;
    oidPiece:TOID = oidPiece;
    montantTVAReel:Currency = vueTauxADate.select('taux * self.montant_TCValue /100','(tDate<=self.dateEcriture)and(idTVA=self.oidTVA)','',True,[]);
    montantTVAReel_CodeDevise:string = montantTVAReel:CodeDevise;
  end;
</source>
</source>


==Sélecteur==
==Sélecteur==


* lastOpeStamp, lastAffectedStamp
* lastOpeStamp, lastOpeAffected, lastOpeFirstOID
: Attributs mis à jour par la dernière opération assembliste.
: Attributs mis à jour par la dernière opération assembliste.
* operationId, operation
: Permet d'enregistrer les opérations dans la table TdbfLogOpe
: S'applique à CopyTo()


* RmvParameter()
* RmvParameter()
Ligne 84 : Ligne 425 :
: Permet de créer des objets à partir d'un sélecteur
: Permet de créer des objets à partir d'un sélecteur


* CopyTo, Update, UpdateFrom  
* CopyTo, Update, UpdateFrom
: Fonctionne sur les classes de stéréotype SQL
: Fonctionne sur les classes de stéréotype SQL


===UpdateFrom===
* InsertInto
: Permet de créer une table temporaire à partir d'un sélecteur
: Réalise un select ... into TEMPTABLE from ...
 
===TsqlOperation===
 
Classe SQL définie par le framework et permettant d'enregistrer les opérations du sélecteur
 
<source lang="delphi">
  TsqlOperation = Class(TsqlObject)
  public
    class procedure CleanOpe(iOpeId:string);
    //
    property action: StringS[128];
    property id: SQLIdentity;
    property oidSourceObject: TOID;
    property oidTargetObject: TOID;
    property opeId: StringS[128];
    property operation: StringS[128];
    property SourceObject: Ref(roGeneric,roNotExternal,roNoForeignKey,roNoRoleIndex) of TitObject;
    property TargetObject: Ref(roGeneric,roNotExternal,roNoForeignKey,roNoRoleIndex) of TitObject;
  end;
</source>
 
* opeId, operationId
: Un identifiant unique (guid) identifiant l'ensemble des opérations
 
* opération
: Nom de l'opération dans l'ensemble des opérations
 
* action
: Action de l'opération
: Par exemple INSERT pour un CopyTo
 
* oidSourceObject
: identifiant de l'objet source dans l'opération
: Par exemple l'objet source de la copie pour un CopyTo
 
* oidTargetObject
: identifiant de l'objet cible dans l'opération
: Par exemple l'objet copié par un CopyTo
 
'''Exemple d'utilisation:'''
 
<source lang="delphi">
 
// Créer des écritures a partir des réglements
//
procedure  _doCreateEcritureReglements(iOidPiece:string; iOpeId:string);
var sel:TSelector;
begin
  sel := vueEcritureReglement.CreateSelector('(oidBordereau=%1)','',True,[oidBordereauReglement]);
  sel.AddParameter('ArgBordereau',oidBordereauReglement);
  sel.Operation := 'EcrReg';
  sel.OpeId := iOpeId;
  //
  sel.CopyTo('TEcriture',['oidpiece','eDate','sens','sensProrata','regimeTVA','typeEcriture'],[
    iOidPiece,
    BordereauReglement.dateReglement,
    sens_credit,
    sens_credit,
    regimeTVA_Encaissements,
    typeEcriture_Brouillard
  ]);
end;
 
Type
  vueUpdateReglement = viewOf(TReglement)
  vl:TsqlOperation = join('(opeId=%ArgOpeId) and (operation=%ArgOperation) and (oidSourceObject=self.oid)');
  oidEcriture:TOID = oidEcriture;
  oidTargetEcriture:TOID = vl.oidTargetObject;
  oidBordereau:TOID = oidBordereauReglement;
  end;
 
// Met à jour l'oidEcriture créée sur les réglements correspondants
..
procedure _doUpdateReglementsEcriture(iOidPiece:string; iOpeId:string);
var sel:TSelector;
begin
  sel := vueUpdateReglement.CreateSelector('(oidBordereau=%1)','',True,[oidBordereauReglement]);
  sel.AddParameter('ArgOpeId',iOpeId);
  sel.AddParameter('ArgOperation','EcrReg');
  //
  sel.Update(['oidEcriture'],['oidTargetEcriture']);
end;
 
begin
  aOpeId := CreateGuid;
  withP long transaction do
  begin
    aOidPiece := _doCreatePiece();
    _doCreateEcritureReglements(aOidPiece,aOpeId);
    _doUpdateReglementsEcriture(aOidPice,aOpeId);
    ...
    TsqlOperation.CleanOpe(aOpeId);
  end;
end;
 
</source>
 
===ToJson()===
 
<source lang="delphi">procedure ToJson(SA:TJsonArray);</source>
 
Sérialize tous les objets retournés par le sélecteur au format JSon comptabible avec les tables react
 
'''Exemple:'''
 
<source lang="delphi">
 
//procedure GetData(SRows:TJsonArray);
Type
  myView = viewOf(...)
  ...
  end;
 
var sel:TSelector;
begin
  // Selector to retreive the data
  //
  sel := myView.CreateSelector('','',True,[]);
  sel.ToJson(SRows);
end;
</source>
 
===UpdateFrom()===


<source lang="delphi">
<source lang="delphi">
Ligne 144 : Ligne 611 :
;
;
</pre>
</pre>
==Table temporaire==
* TDatabase.AllocTempTable(JobId:string)
: Génère un nom de table temporaire
* TDatabase.DropTempTables(JobId:string)
: Supprime (drop) les tables temporaires
<source lang="delphi">
Type
  vue = viewOf(...)
  end;
var sel:TSelector; aJob,aTempTable1,aTempTable2,aTempTable3,aTempTable4:string; keepTables:boolean;
begin
  Result := FALSE;
  aJob := 'ANA';
  keepTables := False;
  sel := vueUnion.CreateSelector('','',True,[]);
  sel.useCTE := True;
  sel.NoShare := True;
  sel.NoFrameworks := True;
  sel.NoOrderBy := True;
  sel.AnyWhere := True;
  try
    // Add the maxLevel by oidGCA to the temp table
    aTempTable1 := ClassManager.DefDatabase.AllocTempTable(aJob);
    sel.InsertInto(aTempTable1,['maxLevel'],['Expression(max(level) over(partition by oidGroupeCumulAnalytique))']);
    //showMessageFmt('%s : %d',[aTempTable1, sel.lastOpeAffected]);
    //
    sel := vueCumulExtCols.CreateSelector('','',True,[]);
    sel.SourceTableName := aTempTable1;
    aTempTable2 := ClassManager.DefDatabase.AllocTempTable(aJob);
    sel.InsertInto(aTempTable2,[],[]);
    //showMessageFmt('%s : %d',[aTempTable2, sel.lastOpeAffected]);
    sel := vueCumulFlat.CreateSelector('','',True,[]);
    sel.SourceTableName := aTempTable2;
   
    aTempTable3 := ClassManager.DefDatabase.AllocTempTable(aJob);
    sel.InsertInto(aTempTable3,[],[]);
    //showMessageFmt('%s : %d',[aTempTable3, sel.lastOpeAffected]);
    sel := vueCumulFlatMontant.CreateSelector('','',True,[]);
    sel.SourceTableName := aTempTable3;
    sel.AddParameter('ArgDeviseTC','EUR');
    aTempTable4 := ClassManager.DefDatabase.AllocTempTable(aJob);
    sel.InsertInto(aTempTable4,[],[]);
    //showMessageFmt('%s : %d',[aTempTable4, sel.lastOpeAffected]);
  finally
  if not KeepTables then ClassManager.DefDatabase.DropTempTables(aJob);
  end;
</source>
==Updater==
Classe technique permettant de mettre à jour un attribut sur un ensemble d'objet.
'''Exemple : Mise à jour des compteurs qui ne peuvent pas être déterminés en SQL'''
<source lang="delphi">
Type
  // Should returns all attributes part of the counter
  //
  vueNumeroPiece = viewOf(TPiece)
  pDate:TDatetime = pDate;
  numero:TCounter = numero;
  end;
procedure _doUpdateNumeroPiece(iOidPiece:string);
var sel:TSelector; vueNP:vueNumeroPiece; upd:TUpdater;
begin
  upd := TPiece.CreateUpdater('numero');
  //
  sel := vueNumeroPiece.CreateSelector('(oid=%1)','',True,[iOidPiece]);
  forEach vueNP in sel.AsCursor do
    begin
      vueNP.numero.AllocValue;
      upd.AddValue(vueNP.OID,vueNP.numero.value);
    end;
  //
  upd.Execute;
end;
begin
 
end;
</source>


[[Category:Version 2025 R2]]
[[Category:Version 2025 R2]]
[[Category:Release note]]
[[Category:Release note]]

Dernière version du 22 mai 2025 à 08:04

Modèle:Version2025r1

PREVIEW

Langage

  • Valeur par défaut de paramètre
Il est possible de définir des valeurs par défaut aux paramètres des méthodes

<source lang="delphi">

 MyClass = Class(TitObject)
   Procedure TestDeffParams;
   Procedure TestDefParamBool(p1:string; p2:boolean=true);
   Procedure TestDefParamJson(p1:string; p2:TJson=nil);
   Procedure TestDefParamJson2(p1:string; p2:TJson='{a:false}');
   Procedure TestDefParamEnum(p1:string; p2:Integer=WFCAState_Etat2);
   Procedure TestDefParamMulti(p1:string; p2:string='a'; p3:string='b');
   Function TestDefParamOne(p1:string='a'):string;
   Function TestDefParamFunc(p1:string='a'):string;
 end;

Procedure MyClass.TestDeffParams; var V:string; begin

 V := TestDefParamFunc('c'); 
 ShowMessage(V); 
  
 TestDefParamOne;
 TestDefParamOne(); 
 TestDefParamOne('x'); 
  
 TestDefParamMulti('a'); 
 TestDefParamMulti('a','1'); 
 TestDefParamMulti('a','1','2'); 
  
 TestDefParamBool('a'); 
 TestDefParamBool('a',false); 
 TestDefParamBool('a',true); 
  
 TestDefParamJson2('b');
 TestDefParamJson2('b','{a:true}'); 
 TestDefParamEnum('c');
 TestDefParamEnum('c',WFCAState_Final); 

end; </source>

  • Paramètre de type classe
Les paramètres de type classe peuvent être passé directement

<source lang="delphi"> Type

 MyClass1 = class
   class procedure foo(rg:TRegClass);
 end;
 MyClass2 = class
   ....
 end;
 MyClass3 = class
   procedure oldbar();
   procedure newbar();
 end;

class procedure MyClass1.foo(rg:TRegClass); begin

 // => MyClass2
 showMessage(rg.aClassName);

end;

procedure MyClass3.oldbar(); var rg:TRegClass; begin

 ModelManager.FindClass('MyClass2');
 myClass1.foo(rg);

end;

procedure MyClass3.newbar(); begin

 myClass1.foo(MyClass2);

end; </source>

Json

  • Opérateur In
Un json de type structure supporte l'opérateur In

<source lang="delphi"> Procedure TestJson;

function _foo(p:TJson):boolean;
begin
  Result := false; 
  if 'a' in p then
   begin
     Result := True;
   end; 
end; 

var js:TJson; begin

 js := TJson.Create('{a:true}'); 
 if _foo(js) then showMessage('ok') else showMessage('nok');

end; </source>


  • Getter et Setter
Un json de type structure supporte l'accès direct aux valeur des membres

<source lang="delphi"> Procedure TestJson;

function _foo(p:TJson):boolean;
begin
  Result := false; 
  if 'a' in p then
   begin
     Result := p['a'];
   end; 
end; 

var js:TJson; begin

 js := TJson.Create('{a:true}'); 
 js['b'] := False; 
 js['a'] := not js['b']; 
 if _foo(js) then showMessage('ok') else showMessage('nok');

end; </source>

  • Constructeur implicite
Un paramètre TJson peut être instancié à partir d'une chaine de caractère

<source lang="delphi"> Procedure TestJson;

function _foo(p:TJson):boolean;
begin
  Result := false; 
  if 'a' in p then
   begin
     Result := p['a'];
   end; 
end; 

begin

 if _foo('{a:true}') then showMessage('ok') else showMessage('nok');

end; </source>


  • Enumérateurs
Un json de type strutucture supporte l'énumérateur sur les clés
Un json de type tableau supporte l'énumérateur sur les éléments

<source lang="delphi"> //Procedure TestJson;

procedure _enumValues(p:TJson);
var i:Integer; V:Variant;
begin
  forEach V in p index i do
   begin
     showMessageFmt('%d:%s',[i,V]); 
   end; 
end; 
procedure _enumKeys(p:TJson);
var i:Integer; Key,Keys,stag:string; 
begin
  Keys := ; stag := ;
  forEach key in p index i do
   begin
     Keys := Keys+stag+inttostr(i)+':'+key;
     stag := ','; 
   end; 
  showMessage(Keys); 
end; 

begin

 _enumKeys('{a:true, b:false}'); 
 _enumValues('[{a:true, b:false},{a:false, b:true}]'); 

end; </source>

Modèle

Classes

  • Méthode AllocOID

<source lang="delphi">class function AllocOID:TOID;</source>

  • Alloue un oid de la classe
Peut être utile dans les tests unitaires
  • Méthode ToJson()

<source lang="delphi">procedure ToJson(SA:variant);</source>

  • Sérialize l'objet en json
SA peut être un TJsonArray ou un TJsonStruct

Classes SQL

  • Options de rôle : NoRefIndex
  • Options de rôle : NoForeignKey

Script

Trace

<source lang="delphi">procedure dbgClear();</source>

Vide la trace

<source lang="delphi">procedure dbgEnable(value:boolean);</source>

Active / désactive la trace

Vue locale

  • Une vue locale peut contenir des attributs "oidXXX" sans définir le rôle

Exemple:

<source lang="delphi"> Type

 vue1 = viewOf(ClassA)
  p1:TEnum(enumName) = ...;
  oidRef:TOID = oidrefB;
  ..
  idRefB:TOID = oidrefB notInSelect;
  [ (idRefB=%ArgRefB) and ....]
 end;

</source>

  • Une vue locale peut contenir des attributs non mappés dans la définition.

Exemple:

<source lang="delphi"> Type

 vue1 = viewOf(ClassA)
   ACount:Integer = count(oid)
   oidRef:TOID;
   codeRef:string;
   libelleRef:string;
  ..
  [  ...]
 end;

var sel:TSelector; begin

 sel := vue1.createSelector();
 case iGroupBy of
  'refB':
    begin
      sel.AddColumn('oidrefB','oidRef'); 
      sel.AddColumn('refB.code','codeRef'); 
      sel.AddColumn('refB.Caption','libelleRef'); 
    end;
  'refC':
    begin
      sel.AddColumn('oidrefC','oidRef'); 
      sel.AddColumn('refC.code','codeRef'); 
      sel.AddColumn('refC.Caption','libelleRef'); 
    end;
 end; 

end; </source>

  • Paramètre de type de donnée

<source lang="delphi"> Type

 vue1 = viewOf(ClassA)
  p1:TEnum(enumName) = ...;
 end;

</source>

  • Qualifier d'attribut NotInGroupBy

<source lang="delphi"> Type

 vue1 = viewOf(ClassA)
  p1:string = expression('...') notInGroupBy;
 end;

</source>

  • Héritage de vue locale

<source lang="delphi"> Type

 vue1 = viewOf(ClassA)
  p1:string = ...;
  [...]
 end;
 vue2 = viewOf(vue1)
  p1:string = ...;
  [inherited and (...)]
 end;

</source>

Exemple:

<source lang="delphi"> //function GetSelector(iGroupBy:string; iFilter:TJsonArray):TSelector; Type

 // défini une classe de base avec tous les filtres
 //
 vueEcritureLettrage = viewOf(TEcriture)
   lettrable:boolean = compteGeneral.lettrable notInSelect; 
   idEtablissement:TOID = piece.oidEtablissement notInSelect; 
   idCompteGeneral:TOID = oidCompteGeneral notInSelect; 
   idRoleTiers:TOID = oidroleTiers notInSelect; 
   [(lettrable=true) 
     and ((oidLettrageEcriture=) or (dateLettrage=0)) 
     and (typeEcriture<>0)
     and (piece.lot.origineLot<>0)
     and (eDate>=%ArgDateInf) 
     and (eDate<=%ArgDateSup) 
     and (idEtablissement=%ArgEtablissement) 
     and (idCompteGeneral=%ArgCompteGeneral)
     and (idRoleTiers=%ArgRoleTiers)
   ] 
 end;
 // Hérite de tous les filtres
 //
 vueEcritureLettrageGroupBy = viewOf(vueEcritureLettrage)
   dateMin:TDatetime = min(eDate);
   dateMax:TDatetime = max(eDate); 
   ACount:Integer = count(oid); 
   credit:Currency = sum('credit:TCValue'); 
   debit:Currency = sum('debit:TCValue'); 
   solde:Currency = sumDiff(debit,credit); 
   [inherited] 
 end; 

begin

 Result := vueLettrageGroupBy.CreateSelector(,,True,[]);

end; </source>

  • Scope de vue locale

Une vue locale peut être référencée en dehors de la méthode où elle est définie.

<source lang="delphi"> procedure Class1.foo; Type

 vue1 = viewOf(ClassA)
  p1:string = ...;
 end;

begin

 ...

end;

procedure Class2.bar; Type

 vue2 = viewOf(class1.foo.vue1)
  p1:string = ...;
 end;

begin

 ...

end; </source>

  • Expression Exists()

Une expression existe peut être utilisée dans les filtres comme une valeur logique

Note : Une expression Exists() est beaucoup plus rapide qu'un "Count<>0"

<source lang="delphi"> Type

 vue1 = viewOf(ClassA)
  id:string = ...;
 end;
 vue2 = viewOf(ClassB)
  id:string = ...;
  bb:boolean = vue1.Exists('(id=self.id)',True,[]) notInSelect;
  [(bb=true) and (....)]
 end;

</source>

  • Expression de Sous requête

Une expression peut être définie par une sous requête

<source lang="delphi"> Type

 VueTauxADate = ViewOf(TTauxADate)
   idTVA : TOid = oidTVA;
   tDate : Date = tDate;
   taux : float = taux; 
 end;
 vueMontantTVA = viewOf(TEcriture)
   dateEcriture:TDatetime=eDate notInSelect;
   oidTVA:TOID = ProfilTVA.oidTVA notInSelect; 
   oidPiece:TOID = oidPiece; 
   montantTVAReel:Currency = vueTauxADate.select('taux * self.montant_TCValue /100','(tDate<=self.dateEcriture)and(idTVA=self.oidTVA)',,True,[]); 
   montantTVAReel_CodeDevise:string = montantTVAReel:CodeDevise; 
 end; 

</source>

Sélecteur

  • lastOpeStamp, lastOpeAffected, lastOpeFirstOID
Attributs mis à jour par la dernière opération assembliste.
  • operationId, operation
Permet d'enregistrer les opérations dans la table TdbfLogOpe
S'applique à CopyTo()
  • RmvParameter()
Permet de retirer un paramètre qui a été ajouté par AddParameter()
  • Amélioration de CopyTo
Permet de créer des objets à partir d'un sélecteur
  • CopyTo, Update, UpdateFrom
Fonctionne sur les classes de stéréotype SQL
  • InsertInto
Permet de créer une table temporaire à partir d'un sélecteur
Réalise un select ... into TEMPTABLE from ...

TsqlOperation

Classe SQL définie par le framework et permettant d'enregistrer les opérations du sélecteur

<source lang="delphi">

 TsqlOperation = Class(TsqlObject)
 public
   class procedure CleanOpe(iOpeId:string);
   //
   property action: StringS[128];
   property id: SQLIdentity;
   property oidSourceObject: TOID;
   property oidTargetObject: TOID;
   property opeId: StringS[128];
   property operation: StringS[128];
   property SourceObject: Ref(roGeneric,roNotExternal,roNoForeignKey,roNoRoleIndex) of TitObject;
   property TargetObject: Ref(roGeneric,roNotExternal,roNoForeignKey,roNoRoleIndex) of TitObject;
 end;

</source>

  • opeId, operationId
Un identifiant unique (guid) identifiant l'ensemble des opérations
  • opération
Nom de l'opération dans l'ensemble des opérations
  • action
Action de l'opération
Par exemple INSERT pour un CopyTo
  • oidSourceObject
identifiant de l'objet source dans l'opération
Par exemple l'objet source de la copie pour un CopyTo
  • oidTargetObject
identifiant de l'objet cible dans l'opération
Par exemple l'objet copié par un CopyTo

Exemple d'utilisation:

<source lang="delphi">

// Créer des écritures a partir des réglements
//
procedure  _doCreateEcritureReglements(iOidPiece:string; iOpeId:string);
var sel:TSelector; 
begin
  sel := vueEcritureReglement.CreateSelector('(oidBordereau=%1)',,True,[oidBordereauReglement]); 
  sel.AddParameter('ArgBordereau',oidBordereauReglement); 
  sel.Operation := 'EcrReg'; 
  sel.OpeId := iOpeId; 
  // 
  sel.CopyTo('TEcriture',['oidpiece','eDate','sens','sensProrata','regimeTVA','typeEcriture'],[
   iOidPiece,
   BordereauReglement.dateReglement, 
   sens_credit,
   sens_credit, 
   regimeTVA_Encaissements,
   typeEcriture_Brouillard 
  ]); 
end;


Type

 vueUpdateReglement = viewOf(TReglement)
  vl:TsqlOperation = join('(opeId=%ArgOpeId) and (operation=%ArgOperation) and (oidSourceObject=self.oid)'); 
  oidEcriture:TOID = oidEcriture; 
  oidTargetEcriture:TOID = vl.oidTargetObject; 
  oidBordereau:TOID = oidBordereauReglement; 
 end; 
// Met à jour l'oidEcriture créée sur les réglements correspondants
..
procedure _doUpdateReglementsEcriture(iOidPiece:string; iOpeId:string);
var sel:TSelector; 
begin
  sel := vueUpdateReglement.CreateSelector('(oidBordereau=%1)',,True,[oidBordereauReglement]); 
  sel.AddParameter('ArgOpeId',iOpeId); 
  sel.AddParameter('ArgOperation','EcrReg'); 
  //
  sel.Update(['oidEcriture'],['oidTargetEcriture']); 
end; 

begin

 aOpeId := CreateGuid;
 withP long transaction do
  begin
    aOidPiece := _doCreatePiece();
    _doCreateEcritureReglements(aOidPiece,aOpeId);
    _doUpdateReglementsEcriture(aOidPice,aOpeId); 
    ...
    TsqlOperation.CleanOpe(aOpeId);
  end;

end;

</source>

ToJson()

<source lang="delphi">procedure ToJson(SA:TJsonArray);</source>

Sérialize tous les objets retournés par le sélecteur au format JSon comptabible avec les tables react

Exemple:

<source lang="delphi">

//procedure GetData(SRows:TJsonArray); Type

 myView = viewOf(...)
  ...
 end; 

var sel:TSelector; begin

 // Selector to retreive the data
 // 
 sel := myView.CreateSelector(,,True,[]);
 sel.ToJson(SRows); 

end; </source>

UpdateFrom()

<source lang="delphi"> function updateFrom(sel:TSelector; iMatchedProps:Array of string; iUpdatedProps:Array of string; iUpdatedValue:Array of variant):Integer; </source>

Permet de mettre à jour une classe à partir d'un sélecteur et d'une colonne de correspondance.

Exemple :

<source lang="delphi"> Type

 // Update the temp table 
 vueTemp = viewOf(TempLettrage)
   reference1:string = reference1;
   reference2:string = reference2;
   modeLettrage:Integer = modeLettrage; 
 end;
  
 vueRef1 = viewOf(TempLettrage)
   //ACount:Integer = count(id);
   ATotal:Currency = sumSign(montant:TCValue,sens,'1');
   reference1:string = reference1; 
   [(modeLettrage=0) and (reference1<>)] 
 end; 

var selT,selG:TSelector; begin

 withP long transaction do
   begin
    // for updating the temp table on "match" 
    selT := vueTemp.CreateSelector(,,True,[]);
    // Lettrage sur reference 1 
    selG := vueRef1.CreateSelector('(ATotal=0)',,True,[]);
    selG.useCTE := True; 
    selT.UpdateFrom(selG,['reference1'],['modeLettrage'],[1]); 
   end;

end; </source>

with CTE as (
select sum(case when t0.sens=1 then ISNULL(t0.montant_TCValue, 0) else -ISNULL(t0.montant_TCValue, 0) end)  as "ATotal",t0.reference1  as "reference1"
from dbo.TEMPLETTRAGE t0 WITH (NOLOCK)
where ((t0.modeLettrage = 0) and (t0.reference1 IS NOT NULL))
group by t0.reference1
)
merge into dbo.TEMPLETTRAGE tm0 using (
SELECT  *
FROM CTE
Where (ATotal = 0.0000)
) tm1 on (tm1.reference1=tm0.reference1)
when matched then update set
tm0.modeLettrage = 1
;

Table temporaire

  • TDatabase.AllocTempTable(JobId:string)
Génère un nom de table temporaire
  • TDatabase.DropTempTables(JobId:string)
Supprime (drop) les tables temporaires

<source lang="delphi"> Type

 vue = viewOf(...)
 end;

var sel:TSelector; aJob,aTempTable1,aTempTable2,aTempTable3,aTempTable4:string; keepTables:boolean; begin

 Result := FALSE;
 aJob := 'ANA'; 
 keepTables := False; 
 sel := vueUnion.CreateSelector(,,True,[]);
 sel.useCTE := True; 
 sel.NoShare := True;
 sel.NoFrameworks := True; 
 sel.NoOrderBy := True; 
 sel.AnyWhere := True; 
 try
   // Add the maxLevel by oidGCA to the temp table 
   aTempTable1 := ClassManager.DefDatabase.AllocTempTable(aJob);
   sel.InsertInto(aTempTable1,['maxLevel'],['Expression(max(level) over(partition by oidGroupeCumulAnalytique))']); 
   //showMessageFmt('%s : %d',[aTempTable1, sel.lastOpeAffected]); 
   //
   sel := vueCumulExtCols.CreateSelector(,,True,[]); 
   sel.SourceTableName := aTempTable1; 
   aTempTable2 := ClassManager.DefDatabase.AllocTempTable(aJob);
   sel.InsertInto(aTempTable2,[],[]); 
   //showMessageFmt('%s : %d',[aTempTable2, sel.lastOpeAffected]); 
   sel := vueCumulFlat.CreateSelector(,,True,[]);
   sel.SourceTableName := aTempTable2; 
    
   aTempTable3 := ClassManager.DefDatabase.AllocTempTable(aJob);
   sel.InsertInto(aTempTable3,[],[]); 
   //showMessageFmt('%s : %d',[aTempTable3, sel.lastOpeAffected]); 
   sel := vueCumulFlatMontant.CreateSelector(,,True,[]); 
   sel.SourceTableName := aTempTable3; 
   sel.AddParameter('ArgDeviseTC','EUR'); 
   aTempTable4 := ClassManager.DefDatabase.AllocTempTable(aJob);
   sel.InsertInto(aTempTable4,[],[]); 
   //showMessageFmt('%s : %d',[aTempTable4, sel.lastOpeAffected]); 
 finally
 if not KeepTables then ClassManager.DefDatabase.DropTempTables(aJob); 
 end; 

</source>

Updater

Classe technique permettant de mettre à jour un attribut sur un ensemble d'objet.

Exemple : Mise à jour des compteurs qui ne peuvent pas être déterminés en SQL

<source lang="delphi"> Type

 // Should returns all attributes part of the counter
 //
 vueNumeroPiece = viewOf(TPiece)
  pDate:TDatetime = pDate;
  numero:TCounter = numero; 
 end; 
procedure _doUpdateNumeroPiece(iOidPiece:string);
var sel:TSelector; vueNP:vueNumeroPiece; upd:TUpdater;
begin
  upd := TPiece.CreateUpdater('numero'); 
  // 
  sel := vueNumeroPiece.CreateSelector('(oid=%1)',,True,[iOidPiece]);
  forEach vueNP in sel.AsCursor do
   begin
     vueNP.numero.AllocValue;
     upd.AddValue(vueNP.OID,vueNP.numero.value); 
   end; 
  //
  upd.Execute; 
end; 

begin

end;

</source>