Version 2025 r2 (release note)

De Wiki1000

Modèle:Version2025r1

Sommaire


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
  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;
  • Paramètre de type classe
Les paramètres de type classe peuvent être passé directement
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;

Json

  • Opérateur In
Un json de type structure supporte l'opérateur In
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;


  • Getter et Setter
Un json de type structure supporte l'accès direct aux valeur des membres
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;
  • Constructeur implicite
Un paramètre TJson peut être instancié à partir d'une chaine de caractère
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;


  • 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
//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;

Modèle

Classes

  • Méthode AllocOID
class function AllocOID:TOID;
  • Alloue un oid de la classe
Peut être utile dans les tests unitaires
  • Méthode ToJson()
procedure ToJson(SA:variant);
  • 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

procedure dbgClear();
Vide la trace
procedure dbgEnable(value:boolean);
Active / désactive la trace

Vue locale

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

Exemple:

Type
  vue1 = viewOf(ClassA)
   p1:TEnum(enumName) = ...;
   oidRef:TOID = oidrefB;
   ..
   idRefB:TOID = oidrefB notInSelect;
   [ (idRefB=%ArgRefB) and ....]
  end;
  • Une vue locale peut contenir des attributs non mappés dans la définition.

Exemple:

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;
  • Paramètre de type de donnée
Type
  vue1 = viewOf(ClassA)
   p1:TEnum(enumName) = ...;
  end;
  • Qualifier d'attribut NotInGroupBy
Type
  vue1 = viewOf(ClassA)
   p1:string = expression('...') notInGroupBy;
  end;
  • Héritage de vue locale
Type
  vue1 = viewOf(ClassA)
   p1:string = ...;
   [...]
  end;
 
  vue2 = viewOf(vue1)
   p1:string = ...;
   [inherited and (...)]
  end;

Exemple:

//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;
  • Scope de vue locale

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

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;
  • 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"

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;
  • Expression de Sous requête

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

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;

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

TsqlOperation

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

  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;
  • 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:

 // 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;

ToJson()

procedure ToJson(SA:TJsonArray);

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

Exemple:

//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;

UpdateFrom()

function updateFrom(sel:TSelector; iMatchedProps:Array of string; iUpdatedProps:Array of string; iUpdatedValue:Array of variant):Integer;

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

Exemple :

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;
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
;

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

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;




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