Par défaut, les valeurs d'un type structuré sont alignées sur des limites de mot ou de double-mot afin de disposer d'un accès plus rapide. Quand vous déclarez un type structuré, vous pouvez spécifier le mot réservé packed pour implémenter le stockage compressé des données. Par exemple :
type TNombres = packed array[1..100] of Real;
L'utilisation de packed ralentit l'accès aux données et, dans le cas d'un tableau de caractères, nuit à la compatibilité (pour plus d'informations, voir Gestion de la mémoire).
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionSetLength(ArrayTifs, nbTifs)
SetLengh(monRec.tabHT, Length(monRec.tabHT)+1)
type TMonRec = record x: integer; tabHt: TRealDynArray; ... end; const DefaultRec: TMonRec = (); // tout à nil var MonTab: array of TMonRec; SetLength(MonTab, 20); for i := 0 to 19 do MonTab[i] := DefaultRec; //ou peut etre FillChar / ZeroMem, mais dépend de l'alignement de ton tableau
unit Unite_coherence; interface uses cyDocER, cyDERUtils, Math; type recValeurs = packed record Valeur: Extended; ExpressionIndex: Integer; end; recSyntheseFloat = packed record AssociatedExpressionKeywordIndex: Integer; ExpressionIndex: Integer; Valeur: Extended; // Dans le cas oú l' on a plusieurs valeurs : Valeurs: Array of recValeurs; LengthValeurs: Integer; end; RecSyntheseDoc = packed record // "packed" evite erreur de manipulation de la taille des arrays ... NumFacture: String; DateFacture: TDate; TVAIntracom: String; NumSiret: String; Telephone: String; Fax: String; EMail: String; Website: String; NumClient: String; NumFacture_ExpressionIndex: Integer; DateFacture_ExpressionIndex: Integer; TVAIntracom_ExpressionIndex: Integer; NumSiret_ExpressionIndex: Integer; Telephone_ExpressionIndex: Integer; Fax_ExpressionIndex: Integer; EMail_ExpressionIndex: Integer; Website_ExpressionIndex: Integer; NumClient_ExpressionIndex: Integer; Somme_MontantsTVA: Array of recSyntheseFloat; TauxTVA: Array of recSyntheseFloat; TotalTVA: Array of recSyntheseFloat; Somme_MontantsHT: Array of recSyntheseFloat; TotalHT: Array of recSyntheseFloat; RemiseHT: Array of recSyntheseFloat; FraisDePort: Array of recSyntheseFloat; // Hors taxe! (Somme montants HT + frais de port = Total hors taxe) Somme_MontantsTTC: Array of recSyntheseFloat; TotalTTC: Array of recSyntheseFloat; DebitAnterieur: Array of recSyntheseFloat; NetAPayer: Array of recSyntheseFloat; // Variable de gestion de la taille des tableaux : LengthSomme_MontantsTVA: Integer; LengthTauxTVA: Integer; LengthTotalTVA: Integer; LengthSomme_MontantsHT: Integer; LengthTotalHT: Integer; LengthRemiseHT: Integer; LengthFraisDePort: Integer; LengthSomme_MontantsTTC: Integer; LengthTotalTTC: Integer; LengthDebitAnterieur: Integer; LengthNetAPayer: Integer; // Résultat de la cohérence : IndexRsltSomme_MontantsTVA: Integer; IndexRsltTauxTVA: Integer; IndexRsltTotalTVA: Integer; IndexRsltSomme_MontantsHT: Integer; IndexRsltTotalHT: Integer; IndexRsltRemiseHT: Integer; IndexRsltFraisDePort: Integer; IndexRsltSomme_MontantsTTC: Integer; IndexRsltTotalTTC: Integer; IndexRsltDebitAnterieur: Integer; IndexRsltNetAPayer: Integer; end; const cOCRElementNumFacture = 1; cOCRElementDate = 2; cOCRElementTVAIntracom = 3; cOCRElementNumSiret = 4; cOCRElementTelephone = 5; cOCRElementFax = 6; cOCRElementEMail = 7; cOCRElementWebsite = 8; cOCRElementNomFournisseur = 9; // Seulement par patron ! cOCRElementNumClient = 10; cOCRElementNumerique = 100; cOCRElementNetAPayer = 101; cOCRElementMontantTTC = 102; // Plusieurs lignes cOCRElementTotalTTC = 103; cOCRElementDebitAnterieur = 104; cOCRElementMontantHT = 201; // Plusieurs lignes cOCRElementTotalHT = 202; cOCRElementRemiseHT = 203; cOCRElementTauxTVA = 301; // Plusieurs lignes cOCRElementMontantTVA = 302; // Plusieurs lignes cOCRElementTotalTVA = 303; cOCRElementFraisDePort = 401; cOCRElementARejeter = 999; // Mots clés à rejeter function ValeursEgales(Valeur1, Valeur2: Extended): Boolean; procedure Initialise_SyntheseDoc(var aRecSyntheseDoc: RecSyntheseDoc); function Localiser_recSyntheseFloat(TableauRecSyntheseFloat: Array of recSyntheseFloat; AssociatedExpressionKeywordIndex: Integer): Integer; procedure Executer_CoherenceDoc(var aRecSyntheseDoc: RecSyntheseDoc; UnDocument: TcyDocER); implementation uses f_prin; function Arrondir(Valor: Double; Decimais: Integer): Double; var Negativo: Boolean; ParteDec, Precisao_Inv : Double; begin // Exemplo com Valor 130.144999 e decimais 2 : Negativo := Valor < 0; if Negativo then Valor := Abs(Valor); Precisao_Inv := Power(10, Decimais); // Precisao_Inv = 100 ... RESULT := Int(Valor); // RESULT = 130 ... ParteDec := (Valor - RESULT) * Precisao_Inv; // x = 14.4999 ... RESULT := RESULT + (Int(ParteDec) / Precisao_Inv); // Recortar os digitos decimais que queremos ... // RESULT = 130.14 ... // Ver se temos que arredondar para cima : if ParteDec - Int(ParteDec) >0.4999999 // Quando x 0.5, o delphi dá-lhe outro valor de tipo 0.4999999999 ... then RESULT := RESULT + (1 / Precisao_Inv); if Negativo then RESULT := (-1) * RESULT; end; function ValeursEgales(Valeur1, Valeur2: Extended): Boolean; begin Result := Abs(Valeur1-Valeur2) <= 0.01; end; procedure Initialise_SyntheseDoc(var aRecSyntheseDoc: RecSyntheseDoc); begin aRecSyntheseDoc.NumFacture := ''; aRecSyntheseDoc.DateFacture := 0; aRecSyntheseDoc.TVAIntracom := ''; aRecSyntheseDoc.NumSiret := ''; aRecSyntheseDoc.Telephone := ''; aRecSyntheseDoc.Fax := ''; aRecSyntheseDoc.EMail := ''; aRecSyntheseDoc.Website := ''; aRecSyntheseDoc.NumClient := ''; aRecSyntheseDoc.NumFacture_ExpressionIndex := -1; aRecSyntheseDoc.DateFacture_ExpressionIndex := -1; aRecSyntheseDoc.TVAIntracom_ExpressionIndex := -1; aRecSyntheseDoc.NumSiret_ExpressionIndex := -1; aRecSyntheseDoc.Telephone_ExpressionIndex := -1; aRecSyntheseDoc.Fax_ExpressionIndex := -1; aRecSyntheseDoc.EMail_ExpressionIndex := -1; aRecSyntheseDoc.Website_ExpressionIndex := -1; aRecSyntheseDoc.NumClient_ExpressionIndex := -1; // Taille des tableaux : SetLength(aRecSyntheseDoc.Somme_MontantsTVA, 0); SetLength(aRecSyntheseDoc.TauxTVA, 0); SetLength(aRecSyntheseDoc.TotalTVA, 0); SetLength(aRecSyntheseDoc.Somme_MontantsHT, 0); SetLength(aRecSyntheseDoc.TotalHT, 0); SetLength(aRecSyntheseDoc.RemiseHT, 0); SetLength(aRecSyntheseDoc.Somme_MontantsTTC, 0); SetLength(aRecSyntheseDoc.TotalTTC, 0); SetLength(aRecSyntheseDoc.DebitAnterieur, 0); SetLength(aRecSyntheseDoc.NetAPayer, 0); // Variables des tableaux : aRecSyntheseDoc.LengthSomme_MontantsTVA := 0; aRecSyntheseDoc.LengthTauxTVA := 0; aRecSyntheseDoc.LengthTotalTVA := 0; aRecSyntheseDoc.LengthSomme_MontantsHT := 0; aRecSyntheseDoc.LengthTotalHT := 0; aRecSyntheseDoc.LengthRemiseHT := 0; aRecSyntheseDoc.LengthFraisDePort := 0; aRecSyntheseDoc.LengthSomme_MontantsTTC := 0; aRecSyntheseDoc.LengthTotalTTC := 0; aRecSyntheseDoc.LengthDebitAnterieur := 0; aRecSyntheseDoc.LengthNetAPayer := 0; // Résultat de la cohérence : aRecSyntheseDoc.IndexRsltSomme_MontantsTVA := -1; aRecSyntheseDoc.IndexRsltTauxTVA := -1; aRecSyntheseDoc.IndexRsltTotalTVA := -1; aRecSyntheseDoc.IndexRsltSomme_MontantsHT := -1; aRecSyntheseDoc.IndexRsltTotalHT := -1; aRecSyntheseDoc.IndexRsltRemiseHT := -1; aRecSyntheseDoc.IndexRsltFraisDePort := -1; aRecSyntheseDoc.IndexRsltSomme_MontantsTTC := -1; aRecSyntheseDoc.IndexRsltTotalTTC := -1; aRecSyntheseDoc.IndexRsltDebitAnterieur := -1; aRecSyntheseDoc.IndexRsltNetAPayer := -1; end; function Localiser_recSyntheseFloat(TableauRecSyntheseFloat: Array of recSyntheseFloat; AssociatedExpressionKeywordIndex: Integer): Integer; var i: Integer; begin Result := -1; for i := 0 to length(TableauRecSyntheseFloat) - 1 do if TableauRecSyntheseFloat[i].AssociatedExpressionKeywordIndex = AssociatedExpressionKeywordIndex then begin Result := i; Break; end; end; procedure Executer_CoherenceDoc(var aRecSyntheseDoc: RecSyntheseDoc; UnDocument: TcyDocER); // Total TTC = Total HT + Total TVA : // Total TTC = Total HT + Somme montants TVA : // Total TTC = Somme montants HT + Total TVA : // Total TTC = Somme montants HT + Somme montants TVA : function Valider_TotalTTC(ValeurTotalTTC: Extended): Boolean; var tht, ttva, mht, mtva: Integer; begin Result := false; if ValeurTotalTTC = 0 then Exit; for tht := 0 to aRecSyntheseDoc.LengthTotalHT - 1 do begin for ttva := 0 to aRecSyntheseDoc.LengthTotalTVA - 1 do if ValeursEgales(ValeurTotalTTC, aRecSyntheseDoc.TotalHT[tht].Valeur + aRecSyntheseDoc.TotalTVA[ttva].Valeur) then begin Result := True; aRecSyntheseDoc.IndexRsltTotalHT := tht; aRecSyntheseDoc.IndexRsltTotalTVA := ttva; Exit; end; for mtva := 0 to aRecSyntheseDoc.LengthSomme_MontantsTVA - 1 do if ValeursEgales(ValeurTotalTTC, aRecSyntheseDoc.TotalHT[tht].Valeur + aRecSyntheseDoc.Somme_MontantsTVA[mtva].Valeur) then begin Result := True; aRecSyntheseDoc.IndexRsltTotalHT := tht; aRecSyntheseDoc.IndexRsltSomme_MontantsTVA := mtva; Exit; end; end; for mht := 0 to aRecSyntheseDoc.LengthSomme_MontantsHT - 1 do begin for ttva := 0 to aRecSyntheseDoc.LengthTotalTVA - 1 do if ValeursEgales(ValeurTotalTTC, aRecSyntheseDoc.Somme_MontantsHT[mht].Valeur + aRecSyntheseDoc.TotalTVA[ttva].Valeur) then begin Result := True; aRecSyntheseDoc.IndexRsltSomme_MontantsHT := mht; aRecSyntheseDoc.IndexRsltTotalTVA := ttva; Exit; end; for mtva := 0 to aRecSyntheseDoc.LengthSomme_MontantsTVA - 1 do if ValeursEgales(ValeurTotalTTC, aRecSyntheseDoc.Somme_MontantsHT[mht].Valeur + aRecSyntheseDoc.Somme_MontantsTVA[mtva].Valeur) then begin Result := True; aRecSyntheseDoc.IndexRsltSomme_MontantsHT := mht; aRecSyntheseDoc.IndexRsltSomme_MontantsTVA := mtva; Exit; end; end; end; function Valider_TauxTVA(IndexMontantsHT, IndexMontantsTVA, IndexTauxTVA: Integer): Boolean; var i, m, NbMontants: Integer; begin Result := true; NbMontants := aRecSyntheseDoc.Somme_MontantsHT[IndexMontantsHT].LengthValeurs; if aRecSyntheseDoc.Somme_MontantsTVA[IndexMontantsTVA].LengthValeurs <> NbMontants then begin Result := false; Exit; end; if IndexTauxTVA <> -1 then if aRecSyntheseDoc.TauxTVA[IndexTauxTVA].LengthValeurs < NbMontants then begin Result := false; Exit; end; // Vérifier si le taux est ok pour chaque montant HT et chaque montant TVA : if IndexTauxTVA = -1 then begin Result := false; for i := 0 to aRecSyntheseDoc.LengthTauxTVA - 1 do if Valider_TauxTVA(IndexMontantsHT, IndexMontantsTVA, i) then begin Result := true; aRecSyntheseDoc.IndexRsltTauxTVA := i; end; end else for m := 0 to NbMontants-1 do if not ValeursEgales(aRecSyntheseDoc.Somme_MontantsHT[IndexMontantsHT].Valeurs[m].Valeur * (aRecSyntheseDoc.TauxTVA[IndexTauxTVA].Valeurs[m].Valeur/100), aRecSyntheseDoc.Somme_MontantsTVA[IndexMontantsTVA].Valeurs[m].Valeur) then Result := false; end; var s, s2, n, t, t2, t3, f, d, aExpressionIndex, aAssociatedExpressionKeywordIndex: Integer; ValeurMax, TmpExtended: Extended; UneCoherenceTrouvee: Boolean; Retours: Integer; I: Integer; _TotalHT, _TotalTVA, _TotalTTC: Extended; label RelancerCoherence; begin // *** Initialisations *** // Retours := 0; // Ajouter 0 aux frais de port : Inc(aRecSyntheseDoc.LengthFraisDePort); Setlength(aRecSyntheseDoc.FraisDePort, aRecSyntheseDoc.LengthFraisDePort); aRecSyntheseDoc.FraisDePort[aRecSyntheseDoc.LengthFraisDePort-1].Valeur := 0; // Ajouter 0 aux remises HT : Inc(aRecSyntheseDoc.LengthRemiseHT); Setlength(aRecSyntheseDoc.RemiseHT, aRecSyntheseDoc.LengthRemiseHT); aRecSyntheseDoc.RemiseHT[aRecSyntheseDoc.LengthRemiseHT-1].Valeur := 0; // Ajouter 0 au débit antérieur : Inc(aRecSyntheseDoc.LengthDebitAnterieur); Setlength(aRecSyntheseDoc.DebitAnterieur, aRecSyntheseDoc.LengthDebitAnterieur); aRecSyntheseDoc.DebitAnterieur[aRecSyntheseDoc.LengthDebitAnterieur-1].Valeur := 0; // *** 18/10/2012 - AFI_656053.tif - Impossible de faire le SetLength dans l' Array aRecSyntheseDoc.TotalTVA depuis ici ... // *** Si les taux sont trouvés "manuellement" *** // for t := 0 to aRecSyntheseDoc.LengthTauxTVA-1 do if aRecSyntheseDoc.TauxTVA[t].AssociatedExpressionKeywordIndex = -1 then aRecSyntheseDoc.IndexRsltTauxTVA := t; // *** Cohérences entre les éléments somme et totaux *** // RelancerCoherence: UneCoherenceTrouvee := false; // Chercher une cohérence entre les montants TTC et le Total TTC : if (aRecSyntheseDoc.IndexRsltSomme_MontantsTTC -1) or (aRecSyntheseDoc.IndexRsltTotalTTC -1) then for s := 0 to aRecSyntheseDoc.LengthSomme_MontantsTTC - 1 do if (aRecSyntheseDoc.IndexRsltSomme_MontantsTTC -1) or (aRecSyntheseDoc.IndexRsltSomme_MontantsTTC s) then if aRecSyntheseDoc.Somme_MontantsTTC[s].Valeur <> 0 then for t := 0 to aRecSyntheseDoc.LengthTotalTTC - 1 do if (aRecSyntheseDoc.IndexRsltTotalTTC -1) or (aRecSyntheseDoc.IndexRsltTotalTTC t) then if ValeursEgales(aRecSyntheseDoc.Somme_MontantsTTC[s].Valeur, aRecSyntheseDoc.TotalTTC[t].Valeur) then begin if aRecSyntheseDoc.IndexRsltSomme_MontantsTTC <> s then begin aRecSyntheseDoc.IndexRsltSomme_MontantsTTC := s; UneCoherenceTrouvee := true; end; if aRecSyntheseDoc.IndexRsltTotalTTC <> t then begin aRecSyntheseDoc.IndexRsltTotalTTC := t; UneCoherenceTrouvee := true; end; end; // Chercher une cohérence entre les montants HT et le Total HT : if (aRecSyntheseDoc.IndexRsltSomme_MontantsHT -1) or (aRecSyntheseDoc.IndexRsltTotalHT -1) then for s := 0 to aRecSyntheseDoc.LengthSomme_MontantsHT - 1 do if (aRecSyntheseDoc.IndexRsltSomme_MontantsHT -1) or (aRecSyntheseDoc.IndexRsltSomme_MontantsHT s) then if aRecSyntheseDoc.Somme_MontantsHT[s].Valeur <> 0 then for t := 0 to aRecSyntheseDoc.LengthTotalHT - 1 do if (aRecSyntheseDoc.IndexRsltTotalHT -1) or (aRecSyntheseDoc.IndexRsltTotalHT t) then for f := 0 to aRecSyntheseDoc.LengthFraisDePort - 1 do if (aRecSyntheseDoc.IndexRsltFraisDePort -1) or (aRecSyntheseDoc.IndexRsltFraisDePort f) then if ValeursEgales(aRecSyntheseDoc.Somme_MontantsHT[s].Valeur + aRecSyntheseDoc.FraisDePort[f].Valeur, aRecSyntheseDoc.TotalHT[t].Valeur) then begin if aRecSyntheseDoc.IndexRsltSomme_MontantsHT <> s then begin aRecSyntheseDoc.IndexRsltSomme_MontantsHT := s; UneCoherenceTrouvee := true; end; if aRecSyntheseDoc.IndexRsltTotalHT <> t then begin aRecSyntheseDoc.IndexRsltTotalHT := t; UneCoherenceTrouvee := true; end; if aRecSyntheseDoc.IndexRsltFraisDePort <> f then begin aRecSyntheseDoc.IndexRsltFraisDePort := f; UneCoherenceTrouvee := true; end; end; // Chercher une cohérence entre les montants HT, Montants TVA : if (aRecSyntheseDoc.IndexRsltSomme_MontantsHT -1) or (aRecSyntheseDoc.IndexRsltSomme_MontantsTVA -1) then for s := 0 to aRecSyntheseDoc.LengthSomme_MontantsHT - 1 do if (aRecSyntheseDoc.IndexRsltSomme_MontantsHT -1) or (aRecSyntheseDoc.IndexRsltSomme_MontantsHT s) then if aRecSyntheseDoc.Somme_MontantsHT[s].Valeur <> 0 then for s2 := 0 to aRecSyntheseDoc.LengthSomme_MontantsTVA - 1 do if (aRecSyntheseDoc.IndexRsltSomme_MontantsTVA -1) or (aRecSyntheseDoc.IndexRsltSomme_MontantsTVA s2) then if Valider_TauxTVA(s, s2, aRecSyntheseDoc.IndexRsltTauxTVA) then // Compare pour chaque montant HT et chaque montant TVA si le taux est ok begin aRecSyntheseDoc.IndexRsltSomme_MontantsHT := s; aRecSyntheseDoc.IndexRsltSomme_MontantsTVA := s2; UneCoherenceTrouvee := true; end; // Total TVA = Total TTC - Total HT: if (aRecSyntheseDoc.IndexRsltTotalTVA = -1) and (aRecSyntheseDoc.IndexRsltTotalHT <> -1) and (aRecSyntheseDoc.IndexRsltTotalTTC <> -1) then for t := 0 to aRecSyntheseDoc.LengthTotalTVA - 1 do if ValeursEgales(aRecSyntheseDoc.TotalTTC[aRecSyntheseDoc.IndexRsltTotalTTC].Valeur - aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.IndexRsltTotalHT].Valeur, aRecSyntheseDoc.TotalTVA[t].Valeur) then begin aRecSyntheseDoc.IndexRsltTotalTVA := t; UneCoherenceTrouvee := true; end; // Total HT = Total TTC - Total TVA: if (aRecSyntheseDoc.IndexRsltTotalHT = -1) and (aRecSyntheseDoc.IndexRsltTotalTVA <> -1) and (aRecSyntheseDoc.IndexRsltTotalTTC <> -1) then for t := 0 to aRecSyntheseDoc.LengthTotalHT - 1 do if ValeursEgales(aRecSyntheseDoc.TotalTTC[aRecSyntheseDoc.IndexRsltTotalTTC].Valeur - aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.IndexRsltTotalTVA].Valeur, aRecSyntheseDoc.TotalHT[t].Valeur) then begin aRecSyntheseDoc.IndexRsltTotalHT := t; UneCoherenceTrouvee := true; end; // *** Calcul du Total TTC *** // // Total TTC = Total HT (ou somme montants HT) + Total TVA (ou somme montants TVA) : if aRecSyntheseDoc.IndexRsltTotalTTC = -1 then for t := 0 to aRecSyntheseDoc.LengthTotalTTC - 1 do // for f := 0 to aRecSyntheseDoc.LengthFraisDePort - 1 do if Valider_TotalTTC(aRecSyntheseDoc.TotalTTC[t].Valeur{ - aRecSyntheseDoc.FraisDePort[f].Valeur}) then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltTotalTTC := t; // aRecSyntheseDoc.IndexRsltFraisDePort := f; end; // *** Calcul du Net à payer *** // // Net à payer = Total TTC + Debit anterieur if aRecSyntheseDoc.IndexRsltTotalTTC = -1 then begin // Chercher une cohérence entre les montants TTC et le net à payer : if aRecSyntheseDoc.IndexRsltSomme_MontantsTTC = -1 then for s := 0 to aRecSyntheseDoc.LengthSomme_MontantsTTC - 1 do if aRecSyntheseDoc.Somme_MontantsTTC[s].Valeur <> 0 then for d := 0 to aRecSyntheseDoc.LengthDebitAnterieur - 1 do for n := 0 to aRecSyntheseDoc.LengthNetAPayer - 1 do if ValeursEgales(aRecSyntheseDoc.Somme_MontantsTTC[s].Valeur + aRecSyntheseDoc.DebitAnterieur[d].Valeur, aRecSyntheseDoc.NetAPayer[n].Valeur) then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltSomme_MontantsTTC := s; aRecSyntheseDoc.IndexRsltDebitAnterieur := d; aRecSyntheseDoc.IndexRsltNetAPayer := n; end; // Net à payer = Total HT (ou somme montants HT) + Total TVA (ou somme montants TVA) + Debit anterieur if aRecSyntheseDoc.IndexRsltNetAPayer = -1 then for n := 0 to aRecSyntheseDoc.LengthNetAPayer - 1 do for d := 0 to aRecSyntheseDoc.LengthDebitAnterieur - 1 do // for f := 0 to aRecSyntheseDoc.LengthFraisDePort - 1 do if Valider_TotalTTC(aRecSyntheseDoc.NetAPayer[n].Valeur {- aRecSyntheseDoc.FraisDePort[f].Valeur} + aRecSyntheseDoc.DebitAnterieur[d].Valeur) then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltNetAPayer := n; aRecSyntheseDoc.IndexRsltDebitAnterieur := d; // aRecSyntheseDoc.IndexRsltFraisDePort := f; end; { // On ne peut pas faire de cohérnce entre 2 éléments qui ont presque toujours la même valeur car ça les valide même si les valeurs mal OCRIsées // Si on a ni le Total TTC ni le Net à payer : if aRecSyntheseDoc.IndexRsltNetAPayer = -1 then if aRecSyntheseDoc.LengthNetAPayer <> 0 then begin if aRecSyntheseDoc.LengthTotalTTC <> 0 then begin // Chercher une cohérence entre le total TTC et le net à payer : for t := 0 to aRecSyntheseDoc.LengthTotalTTC - 1 do for n := 0 to aRecSyntheseDoc.LengthNetAPayer - 1 do for d := 0 to aRecSyntheseDoc.LengthDebitAnterieur - 1 do // for f := 0 to aRecSyntheseDoc.LengthFraisDePort - 1 do // if ValeursEgales(aRecSyntheseDoc.NetAPayer[n].Valeur, aRecSyntheseDoc.TotalTTC[t].Valeur + aRecSyntheseDoc.FraisDePort[f].Valeur + aRecSyntheseDoc.DebitAnterieur[d].Valeur) then if ValeursEgales(aRecSyntheseDoc.NetAPayer[n].Valeur, aRecSyntheseDoc.TotalTTC[t].Valeur + aRecSyntheseDoc.DebitAnterieur[d].Valeur) then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltTotalTTC := t; aRecSyntheseDoc.IndexRsltNetAPayer := n; aRecSyntheseDoc.IndexRsltDebitAnterieur := d; // aRecSyntheseDoc.IndexRsltFraisDePort := f; end; end else if aRecSyntheseDoc.LengthNetAPayer <> 0 then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltNetAPayer := aRecSyntheseDoc.LengthNetAPayer - 1; end; end else if aRecSyntheseDoc.LengthTotalTTC <> 0 then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltTotalTTC := aRecSyntheseDoc.LengthTotalTTC - 1; end; } end else begin // On a le total TTC et au moins une autre valeur, chercher une cohérence entre le total TTC et le net à payer : if (aRecSyntheseDoc.IndexRsltNetAPayer = -1) and ((aRecSyntheseDoc.IndexRsltTotalHT <> -1) or (aRecSyntheseDoc.IndexRsltTotalTVA <> -1)) then for n := 0 to aRecSyntheseDoc.LengthNetAPayer - 1 do for d := 0 to aRecSyntheseDoc.LengthDebitAnterieur - 1 do // for f := 0 to aRecSyntheseDoc.LengthFraisDePort - 1 do if ValeursEgales(aRecSyntheseDoc.NetAPayer[n].Valeur, aRecSyntheseDoc.TotalTTC[aRecSyntheseDoc.IndexRsltTotalTTC].Valeur {+ aRecSyntheseDoc.FraisDePort[f].Valeur} + aRecSyntheseDoc.DebitAnterieur[d].Valeur) then begin if (aRecSyntheseDoc.IndexRsltNetAPayer -1) or (aRecSyntheseDoc.IndexRsltDebitAnterieur -1) {or (aRecSyntheseDoc.IndexRsltFraisDePort = -1)} then UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltNetAPayer := n; aRecSyntheseDoc.IndexRsltDebitAnterieur := d; // aRecSyntheseDoc.IndexRsltFraisDePort := f; end; end; // Taux de TVA depuis le total HT et Total Montant TVA : if aRecSyntheseDoc.IndexRsltTauxTVA = -1 then if (aRecSyntheseDoc.IndexRsltSomme_MontantsTTC -1) and (aRecSyntheseDoc.IndexRsltSomme_MontantsTVA -1) then if (aRecSyntheseDoc.IndexRsltTotalHT <> -1) and (aRecSyntheseDoc.IndexRsltTotalTVA <> -1) then begin for t := 0 to aRecSyntheseDoc.LengthTauxTVA-1 do if aRecSyntheseDoc.TauxTVA[t].LengthValeurs = 1 then if ValeursEgales(aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur * aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.IndexRsltTotalHT].Valeur / 100, aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.IndexRsltTotalTVA].Valeur) then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltTauxTVA := t; end; // Calculer le taux : if aRecSyntheseDoc.IndexRsltTauxTVA = -1 then begin if FrmPrin.Pays_TauxTVA1 <> 0 then if ValeursEgales(FrmPrin.Pays_TauxTVA1 * aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.IndexRsltTotalHT].Valeur / 100, aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.IndexRsltTotalTVA].Valeur) then begin UneCoherenceTrouvee := True; t := aRecSyntheseDoc.LengthTauxTVA; Inc(aRecSyntheseDoc.LengthTauxTVA); SetLength(aRecSyntheseDoc.TauxTVA, aRecSyntheseDoc.LengthTauxTVA); aRecSyntheseDoc.TauxTVA[t].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TauxTVA[t].ExpressionIndex := -1; aRecSyntheseDoc.TauxTVA[aRecSyntheseDoc.LengthTauxTVA-1].LengthValeurs := 1; SetLength(aRecSyntheseDoc.TauxTVA[aRecSyntheseDoc.LengthTauxTVA-1].Valeurs, 1); aRecSyntheseDoc.TauxTVA[aRecSyntheseDoc.LengthTauxTVA-1].Valeurs[0].Valeur := FrmPrin.Pays_TauxTVA1; aRecSyntheseDoc.IndexRsltTauxTVA := t; end; if FrmPrin.Pays_TauxTVA2 <> 0 then if ValeursEgales(FrmPrin.Pays_TauxTVA2 * aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.IndexRsltTotalHT].Valeur / 100, aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.IndexRsltTotalTVA].Valeur) then begin UneCoherenceTrouvee := True; t := aRecSyntheseDoc.LengthTauxTVA; Inc(aRecSyntheseDoc.LengthTauxTVA); SetLength(aRecSyntheseDoc.TauxTVA, aRecSyntheseDoc.LengthTauxTVA); aRecSyntheseDoc.TauxTVA[t].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TauxTVA[t].ExpressionIndex := -1; aRecSyntheseDoc.TauxTVA[aRecSyntheseDoc.LengthTauxTVA-1].LengthValeurs := 1; SetLength(aRecSyntheseDoc.TauxTVA[aRecSyntheseDoc.LengthTauxTVA-1].Valeurs, 1); aRecSyntheseDoc.TauxTVA[aRecSyntheseDoc.LengthTauxTVA-1].Valeurs[0].Valeur := FrmPrin.Pays_TauxTVA2; aRecSyntheseDoc.IndexRsltTauxTVA := t; end; if FrmPrin.Pays_TauxTVA3 <> 0 then if ValeursEgales(FrmPrin.Pays_TauxTVA3 * aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.IndexRsltTotalHT].Valeur / 100, aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.IndexRsltTotalTVA].Valeur) then begin UneCoherenceTrouvee := True; t := aRecSyntheseDoc.LengthTauxTVA; Inc(aRecSyntheseDoc.LengthTauxTVA); SetLength(aRecSyntheseDoc.TauxTVA, aRecSyntheseDoc.LengthTauxTVA); aRecSyntheseDoc.TauxTVA[t].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TauxTVA[t].ExpressionIndex := -1; aRecSyntheseDoc.TauxTVA[aRecSyntheseDoc.LengthTauxTVA-1].LengthValeurs := 1; SetLength(aRecSyntheseDoc.TauxTVA[aRecSyntheseDoc.LengthTauxTVA-1].Valeurs, 1); aRecSyntheseDoc.TauxTVA[aRecSyntheseDoc.LengthTauxTVA-1].Valeurs[0].Valeur := FrmPrin.Pays_TauxTVA3; aRecSyntheseDoc.IndexRsltTauxTVA := t; end; end; end; // 26/05/2012 - Chercher une cohérence entre 3 valeurs : Total HT, Total TVA et Total TTC if (aRecSyntheseDoc.IndexRsltTotalTTC -1) or (aRecSyntheseDoc.IndexRsltTotalHT -1) or (aRecSyntheseDoc.IndexRsltTotalTVA = -1) then for t3 := 0 to aRecSyntheseDoc.LengthTotalTTC-1 do if (aRecSyntheseDoc.IndexRsltTotalTTC t3) or (aRecSyntheseDoc.IndexRsltTotalTTC -1) then for t2 := 0 to aRecSyntheseDoc.LengthTotalHT-1 do if (aRecSyntheseDoc.IndexRsltTotalHT t2) or (aRecSyntheseDoc.IndexRsltTotalHT -1) then for t := 0 to aRecSyntheseDoc.LengthTotalTVA-1 do if (aRecSyntheseDoc.IndexRsltTotalTVA t) or (aRecSyntheseDoc.IndexRsltTotalTVA -1) then if ValeursEgales(aRecSyntheseDoc.TotalTTC[t3].Valeur, aRecSyntheseDoc.TotalHT[t2].Valeur + aRecSyntheseDoc.TotalTVA[t].Valeur) then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltTotalTTC := t3; aRecSyntheseDoc.IndexRsltTotalHT := t2; aRecSyntheseDoc.IndexRsltTotalTVA := t; end; // *** Cohérences par déduction et recherche de nouvelles valeurs *** // // 27/05/2012 - Copier le net à payer vers le TotalTTC : if not UneCoherenceTrouvee then if (aRecSyntheseDoc.LengthTotalTTC 0) and (aRecSyntheseDoc.LengthNetAPayer 1) then begin UneCoherenceTrouvee := true; aRecSyntheseDoc.LengthTotalTTC := 1; SetLength(aRecSyntheseDoc.TotalTTC, 1); aRecSyntheseDoc.TotalTTC[0] := aRecSyntheseDoc.NetAPayer[0]; end; // 26/05/2012 - Ajouter total HT grâce au taux (même si tableau non vide, car la valeur a pu être mal OCRisée) et valider avec Total TTC, taux TVA et valeur de la TVA: if not UneCoherenceTrouvee then try if (aRecSyntheseDoc.IndexRsltTotalTTC -1) or (aRecSyntheseDoc.IndexRsltTauxTVA -1) or (aRecSyntheseDoc.IndexRsltTotalTVA = -1) then for t3 := 0 to aRecSyntheseDoc.LengthTotalTTC-1 do if (aRecSyntheseDoc.IndexRsltTotalTTC t3) or (aRecSyntheseDoc.IndexRsltTotalTTC -1) then for t := 0 to aRecSyntheseDoc.LengthTauxTVA-1 do if ((t aRecSyntheseDoc.IndexRsltTauxTVA) or (aRecSyntheseDoc.IndexRsltTauxTVA -1)) and (aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur > 0) and (aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur <> 100) then begin _TotalHT := Arrondir( aRecSyntheseDoc.TotalTTC[t3].Valeur / (1+(aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur/100)), 2 ); // Voir s' il y a une cohérence entre le TotalHT et le total TVA : for t2 := 0 to aRecSyntheseDoc.LengthTotalTVA-1 do if (aRecSyntheseDoc.IndexRsltTotalTVA t2) or (aRecSyntheseDoc.IndexRsltTotalTVA -1) then if ValeursEgales(_TotalHT + aRecSyntheseDoc.TotalTVA[t2].Valeur, aRecSyntheseDoc.TotalTTC[t3].Valeur) then begin UneCoherenceTrouvee := true; aRecSyntheseDoc.IndexRsltTotalTTC := t3; aRecSyntheseDoc.IndexRsltTauxTVA := t; aRecSyntheseDoc.IndexRsltTotalTVA := t2; // Ajouter le total HT : Inc(aRecSyntheseDoc.LengthTotalHT); SetLength(aRecSyntheseDoc.TotalHT, aRecSyntheseDoc.LengthTotalHT); aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.LengthTotalHT-1].Valeur := _TotalHT; aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.LengthTotalHT-1].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.LengthTotalHT-1].ExpressionIndex := UnDocument.FindExpression(_TotalHT, etFloat, 0, UnDocument.ExpressionCount-1); end; end; except end; // 27/05/2012 - Ajouter total TVA grâce au taux (même si tableau non vide, car la valeur a pu être mal OCRisée) et valider avec Total TTC, taux TVA et total HT: if not UneCoherenceTrouvee then try if (aRecSyntheseDoc.IndexRsltTotalTTC -1) or (aRecSyntheseDoc.IndexRsltTauxTVA -1) or (aRecSyntheseDoc.IndexRsltTotalHT = -1) then for t3 := 0 to aRecSyntheseDoc.LengthTotalTTC-1 do if (aRecSyntheseDoc.IndexRsltTotalTTC t3) or (aRecSyntheseDoc.IndexRsltTotalTTC -1) then for t := 0 to aRecSyntheseDoc.LengthTauxTVA-1 do if ((t aRecSyntheseDoc.IndexRsltTauxTVA) or (aRecSyntheseDoc.IndexRsltTauxTVA -1)) and (aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur > 0) and (aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur <> 100) then begin // Voir s' il y a une cohérence entre le TotalHT et le total TVA : for t2 := 0 to aRecSyntheseDoc.LengthTotalHT-1 do if (aRecSyntheseDoc.IndexRsltTotalHT t2) or (aRecSyntheseDoc.IndexRsltTotalHT -1) then begin _TotalTVA := Arrondir( aRecSyntheseDoc.TotalHT[t2].Valeur * aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur / 100, 2 ); if ValeursEgales(_TotalTVA + aRecSyntheseDoc.TotalHT[t2].Valeur, aRecSyntheseDoc.TotalTTC[t3].Valeur) then begin UneCoherenceTrouvee := true; aRecSyntheseDoc.IndexRsltTotalTTC := t3; aRecSyntheseDoc.IndexRsltTauxTVA := t; aRecSyntheseDoc.IndexRsltTotalHT := t2; // Ajouter le total TVA : Inc(aRecSyntheseDoc.LengthTotalTVA); SetLength(aRecSyntheseDoc.TotalTVA, aRecSyntheseDoc.LengthTotalTVA); aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.LengthTotalTVA-1].Valeur := _TotalTVA; aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.LengthTotalTVA-1].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.LengthTotalTVA-1].ExpressionIndex := UnDocument.FindExpression(_TotalTVA, etFloat, 0, UnDocument.ExpressionCount-1); end; end; end; except end; // 27/05/2012 - Ajouter total TTC grâce au taux (même si tableau non vide, car la valeur a pu être mal OCRisée) et valider avec Total TVA, taux TVA et total HT: if not UneCoherenceTrouvee then try if (aRecSyntheseDoc.IndexRsltTotalTVA -1) or (aRecSyntheseDoc.IndexRsltTauxTVA -1) or (aRecSyntheseDoc.IndexRsltTotalHT = -1) then for t3 := 0 to aRecSyntheseDoc.LengthTotalTVA-1 do if (aRecSyntheseDoc.IndexRsltTotalTVA t3) or (aRecSyntheseDoc.IndexRsltTotalTVA -1) then for t := 0 to aRecSyntheseDoc.LengthTauxTVA-1 do if ((t aRecSyntheseDoc.IndexRsltTauxTVA) or (aRecSyntheseDoc.IndexRsltTauxTVA -1)) and (aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur > 0) and (aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur <> 100) then begin // Voir s' il y a une cohérence : for t2 := 0 to aRecSyntheseDoc.LengthTotalHT-1 do if (aRecSyntheseDoc.IndexRsltTotalHT t2) or (aRecSyntheseDoc.IndexRsltTotalHT -1) then begin _TotalTTC := Arrondir( aRecSyntheseDoc.TotalHT[t2].Valeur * (1 + aRecSyntheseDoc.TauxTVA[t].Valeurs[0].Valeur/100), 2 ); if ValeursEgales(aRecSyntheseDoc.TotalTVA[t3].Valeur + aRecSyntheseDoc.TotalHT[t2].Valeur, _TotalTTC) then begin UneCoherenceTrouvee := true; aRecSyntheseDoc.IndexRsltTotalTVA := t3; aRecSyntheseDoc.IndexRsltTauxTVA := t; aRecSyntheseDoc.IndexRsltTotalHT := t2; // Ajouter le total TTC : Inc(aRecSyntheseDoc.LengthTotalTTC); SetLength(aRecSyntheseDoc.TotalTTC, aRecSyntheseDoc.LengthTotalTTC); aRecSyntheseDoc.TotalTTC[aRecSyntheseDoc.LengthTotalTTC-1].Valeur := _TotalTTC; aRecSyntheseDoc.TotalTTC[aRecSyntheseDoc.LengthTotalTTC-1].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TotalTTC[aRecSyntheseDoc.LengthTotalTTC-1].ExpressionIndex := UnDocument.FindExpression(_TotalTTC, etFloat, 0, UnDocument.ExpressionCount-1); end; end; end; except end; // 23/04/2012 - Ajouter un Total TVA par rapport aux montants TVA : if not UneCoherenceTrouvee then if (aRecSyntheseDoc.LengthTotalTVA 0) and (aRecSyntheseDoc.LengthSomme_MontantsTVA 1) then if UnDocument.FindExpression(aRecSyntheseDoc.Somme_MontantsTVA[0].Valeur, etFloat, 0, UnDocument.ExpressionCount-1) <> -1 then begin UneCoherenceTrouvee := true; aRecSyntheseDoc.LengthTotalTVA := 1; SetLength(aRecSyntheseDoc.TotalTVA, 1); aRecSyntheseDoc.TotalTVA[0].Valeur := aRecSyntheseDoc.Somme_MontantsTVA[0].Valeur; aRecSyntheseDoc.TotalTVA[0].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TotalTVA[0].ExpressionIndex := UnDocument.FindExpression(aRecSyntheseDoc.Somme_MontantsTVA[0].Valeur, etFloat, 0, UnDocument.ExpressionCount-1); end; // 23/04/2012 - Ajouter un Total HT par rapport aux montants HT : if not UneCoherenceTrouvee then if (aRecSyntheseDoc.LengthTotalHT 0) and (aRecSyntheseDoc.LengthSomme_MontantsHT 1) then if UnDocument.FindExpression(aRecSyntheseDoc.Somme_MontantsHT[0].Valeur, etFloat, 0, UnDocument.ExpressionCount-1) <> -1 then begin UneCoherenceTrouvee := true; aRecSyntheseDoc.LengthTotalHT := 1; SetLength(aRecSyntheseDoc.TotalHT, 1); aRecSyntheseDoc.TotalHT[0].Valeur := aRecSyntheseDoc.Somme_MontantsHT[0].Valeur; aRecSyntheseDoc.TotalHT[0].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TotalHT[0].ExpressionIndex := UnDocument.FindExpression(aRecSyntheseDoc.Somme_MontantsHT[0].Valeur, etFloat, 0, UnDocument.ExpressionCount-1); end; // 23/04/2012 - Ajouter un Total TTC par rapport aux montants TTC : if not UneCoherenceTrouvee then if (aRecSyntheseDoc.LengthTotalTTC 0) and (aRecSyntheseDoc.LengthSomme_MontantsTTC 1) then if UnDocument.FindExpression(aRecSyntheseDoc.Somme_MontantsTTC[0].Valeur, etFloat, 0, UnDocument.ExpressionCount-1) <> -1 then begin UneCoherenceTrouvee := true; aRecSyntheseDoc.LengthTotalTTC := 1; SetLength(aRecSyntheseDoc.TotalTTC, 1); aRecSyntheseDoc.TotalTTC[0].Valeur := aRecSyntheseDoc.Somme_MontantsTTC[0].Valeur; aRecSyntheseDoc.TotalTTC[0].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TotalTTC[0].ExpressionIndex := UnDocument.FindExpression(aRecSyntheseDoc.Somme_MontantsTTC[0].Valeur, etFloat, 0, UnDocument.ExpressionCount-1); end; // Ajouter le Total TTC qui est un champ obligatoire si on ne l' a pas (quelques fois sur fond gris et donc, illisible) : if not UneCoherenceTrouvee then if (aRecSyntheseDoc.IndexRsltTotalTTC -1) and (aRecSyntheseDoc.IndexRsltNetAPayer -1) then if aRecSyntheseDoc.LengthTotalTTC = 0 then if (aRecSyntheseDoc.IndexRsltTotalTVA <> -1) or (aRecSyntheseDoc.LengthTotalTVA = 1) then if (aRecSyntheseDoc.IndexRsltTotalHT <> -1) or (aRecSyntheseDoc.LengthTotalHT = 1) then begin UneCoherenceTrouvee := true; if aRecSyntheseDoc.IndexRsltTotalHT = -1 then aRecSyntheseDoc.IndexRsltTotalHT := 0; if aRecSyntheseDoc.IndexRsltTotalTVA = -1 then aRecSyntheseDoc.IndexRsltTotalTVA := 0; aRecSyntheseDoc.LengthTotalTTC := 1; SetLength(aRecSyntheseDoc.TotalTTC, 1); aRecSyntheseDoc.TotalTTC[0].Valeur := aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.IndexRsltTotalTVA].Valeur + aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.IndexRsltTotalHT].Valeur; aRecSyntheseDoc.TotalTTC[0].AssociatedExpressionKeywordIndex := -1; aRecSyntheseDoc.TotalTTC[0].ExpressionIndex := UnDocument.FindExpression(aRecSyntheseDoc.TotalTTC[0].Valeur, etFloat, 0, UnDocument.ExpressionCount-1); aRecSyntheseDoc.IndexRsltTotalTTC := 0; end; // *** Cohérences par manipulation des éléments *** // // Quelques fois, il faut regrouper les éléments somme des montants HT en un seul élément : if not UneCoherenceTrouvee then if (aRecSyntheseDoc.IndexRsltTotalHT -1) and (aRecSyntheseDoc.IndexRsltSomme_MontantsHT -1) then if aRecSyntheseDoc.LengthSomme_MontantsHT > 1 then while aRecSyntheseDoc.LengthSomme_MontantsHT > 1 do begin UneCoherenceTrouvee := true; // Va permettre de refaire une recherche while aRecSyntheseDoc.Somme_MontantsHT[1].LengthValeurs <> 0 do begin aRecSyntheseDoc.Somme_MontantsHT[0].LengthValeurs := aRecSyntheseDoc.Somme_MontantsHT[0].LengthValeurs + 1; SetLength(aRecSyntheseDoc.Somme_MontantsHT[0].Valeurs, aRecSyntheseDoc.Somme_MontantsHT[0].LengthValeurs); aRecSyntheseDoc.Somme_MontantsHT[0].Valeurs[aRecSyntheseDoc.Somme_MontantsHT[0].LengthValeurs-1].Valeur := aRecSyntheseDoc.Somme_MontantsHT[1].Valeurs[0].Valeur; aRecSyntheseDoc.Somme_MontantsHT[0].Valeurs[aRecSyntheseDoc.Somme_MontantsHT[0].LengthValeurs-1].ExpressionIndex := aRecSyntheseDoc.Somme_MontantsHT[1].Valeurs[0].ExpressionIndex; aRecSyntheseDoc.Somme_MontantsHT[0].Valeur := aRecSyntheseDoc.Somme_MontantsHT[0].Valeur + aRecSyntheseDoc.Somme_MontantsHT[1].Valeurs[0].Valeur; aRecSyntheseDoc.Somme_MontantsHT[1].LengthValeurs := aRecSyntheseDoc.Somme_MontantsHT[1].LengthValeurs - 1; end; aRecSyntheseDoc.LengthSomme_MontantsHT := aRecSyntheseDoc.LengthSomme_MontantsHT - 1; SetLength(aRecSyntheseDoc.Somme_MontantsHT, aRecSyntheseDoc.LengthSomme_MontantsHT); end; // Le total TVA peut se trouver à la fin des montants TVA (total de la colonne ou seule valeur de la colonne): if not UneCoherenceTrouvee then if aRecSyntheseDoc.LengthTotalTVA = 0 then begin // Copier le montant le plus grand dans Total TVA : aExpressionIndex := -1; TmpExtended := 0; ValeurMax := 1000000; for s := 0 to aRecSyntheseDoc.LengthSomme_MontantsTVA-1 do if aRecSyntheseDoc.Somme_MontantsTVA[s].Valeurs[aRecSyntheseDoc.Somme_MontantsTVA[s].LengthValeurs - 1].Valeur > TmpExtended then if aRecSyntheseDoc.Somme_MontantsTVA[s].Valeurs[aRecSyntheseDoc.Somme_MontantsTVA[s].LengthValeurs - 1].Valeur < ValeurMax then begin aExpressionIndex := aRecSyntheseDoc.Somme_MontantsTVA[s].Valeurs[aRecSyntheseDoc.Somme_MontantsTVA[s].LengthValeurs - 1].ExpressionIndex; aAssociatedExpressionKeywordIndex := aRecSyntheseDoc.Somme_MontantsTVA[s].AssociatedExpressionKeywordIndex; TmpExtended := aRecSyntheseDoc.Somme_MontantsTVA[s].Valeurs[aRecSyntheseDoc.Somme_MontantsTVA[s].LengthValeurs - 1].Valeur; end; if aExpressionIndex <> -1 then begin UneCoherenceTrouvee := true; Inc(aRecSyntheseDoc.LengthTotalTVA); SetLength(aRecSyntheseDoc.TotalTVA, aRecSyntheseDoc.LengthTotalTVA); aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.LengthTotalTVA-1].ExpressionIndex := aExpressionIndex; aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.LengthTotalTVA-1].AssociatedExpressionKeywordIndex := aAssociatedExpressionKeywordIndex; aRecSyntheseDoc.TotalTVA[aRecSyntheseDoc.LengthTotalTVA-1].Valeur := TmpExtended; end; end; // 05/05/2012 // Le total HT peut se trouver à la fin des montants HT (total de la colonne ou seule valeur de la colonne): if not UneCoherenceTrouvee then if aRecSyntheseDoc.LengthTotalHT = 0 then begin // Copier le montant le plus grand dans Total HT : aExpressionIndex := -1; TmpExtended := 0; ValeurMax := 1000000; for s := 0 to aRecSyntheseDoc.LengthSomme_MontantsHT-1 do if aRecSyntheseDoc.Somme_MontantsHT[s].Valeurs[aRecSyntheseDoc.Somme_MontantsHT[s].LengthValeurs - 1].Valeur > TmpExtended then if aRecSyntheseDoc.Somme_MontantsHT[s].Valeurs[aRecSyntheseDoc.Somme_MontantsHT[s].LengthValeurs - 1].Valeur < ValeurMax then begin aExpressionIndex := aRecSyntheseDoc.Somme_MontantsHT[s].Valeurs[aRecSyntheseDoc.Somme_MontantsHT[s].LengthValeurs - 1].ExpressionIndex; aAssociatedExpressionKeywordIndex := aRecSyntheseDoc.Somme_MontantsHT[s].AssociatedExpressionKeywordIndex; TmpExtended := aRecSyntheseDoc.Somme_MontantsHT[s].Valeurs[aRecSyntheseDoc.Somme_MontantsHT[s].LengthValeurs - 1].Valeur; end; if aExpressionIndex <> -1 then begin UneCoherenceTrouvee := true; Inc(aRecSyntheseDoc.LengthTotalHT); SetLength(aRecSyntheseDoc.TotalHT, aRecSyntheseDoc.LengthTotalHT); aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.LengthTotalHT-1].ExpressionIndex := aExpressionIndex; aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.LengthTotalHT-1].AssociatedExpressionKeywordIndex := aAssociatedExpressionKeywordIndex; aRecSyntheseDoc.TotalHT[aRecSyntheseDoc.LengthTotalHT-1].Valeur := TmpExtended; end; end; // 05/05/2012 // Le total TTC peut se trouver à la fin des montants TTC (total de la colonne ou seule valeur de la colonne): if not UneCoherenceTrouvee then if aRecSyntheseDoc.LengthTotalTTC = 0 then begin // Copier le montant le plus grand dans Total TTC : aExpressionIndex := -1; TmpExtended := 0; ValeurMax := 1000000; for s := 0 to aRecSyntheseDoc.LengthSomme_MontantsTTC-1 do if aRecSyntheseDoc.Somme_MontantsTTC[s].Valeurs[aRecSyntheseDoc.Somme_MontantsTTC[s].LengthValeurs - 1].Valeur > TmpExtended then if aRecSyntheseDoc.Somme_MontantsTTC[s].Valeurs[aRecSyntheseDoc.Somme_MontantsTTC[s].LengthValeurs - 1].Valeur < ValeurMax then begin aExpressionIndex := aRecSyntheseDoc.Somme_MontantsTTC[s].Valeurs[aRecSyntheseDoc.Somme_MontantsTTC[s].LengthValeurs - 1].ExpressionIndex; aAssociatedExpressionKeywordIndex := aRecSyntheseDoc.Somme_MontantsTTC[s].AssociatedExpressionKeywordIndex; TmpExtended := aRecSyntheseDoc.Somme_MontantsTTC[s].Valeurs[aRecSyntheseDoc.Somme_MontantsTTC[s].LengthValeurs - 1].Valeur; end; if aExpressionIndex <> -1 then begin UneCoherenceTrouvee := true; Inc(aRecSyntheseDoc.LengthTotalTTC); SetLength(aRecSyntheseDoc.TotalTTC, aRecSyntheseDoc.LengthTotalTTC); aRecSyntheseDoc.TotalTTC[aRecSyntheseDoc.LengthTotalTTC-1].ExpressionIndex := aExpressionIndex; aRecSyntheseDoc.TotalTTC[aRecSyntheseDoc.LengthTotalTTC-1].AssociatedExpressionKeywordIndex := aAssociatedExpressionKeywordIndex; aRecSyntheseDoc.TotalTTC[aRecSyntheseDoc.LengthTotalTTC-1].Valeur := TmpExtended; end; end; // *** Si rien d' autre a fonctionné *** // // Renvoyer au moins le champ obligatoire Total TTC si aucune valeur de la cohérence trouvée : if not UneCoherenceTrouvee then if (aRecSyntheseDoc.IndexRsltTotalTTC -1) and (aRecSyntheseDoc.IndexRsltNetAPayer -1) and (aRecSyntheseDoc.IndexRsltTotalHT -1) and (aRecSyntheseDoc.IndexRsltTotalTVA -1) then if aRecSyntheseDoc.LengthTotalTTC > 0 then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltTotalTTC := 0; end else if aRecSyntheseDoc.LengthNetAPayer > 0 then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltNetAPayer := 0; end; // Récupérer la somme des montants TTC si on a rien trouvé : if not UneCoherenceTrouvee then if (aRecSyntheseDoc.IndexRsltTotalTTC -1) and (aRecSyntheseDoc.IndexRsltNetAPayer -1) and (aRecSyntheseDoc.IndexRsltTotalHT -1) and (aRecSyntheseDoc.IndexRsltTotalTVA -1) and (aRecSyntheseDoc.IndexRsltSomme_MontantsTTC = -1) and (aRecSyntheseDoc.LengthSomme_MontantsTTC > 0) then if aRecSyntheseDoc.Somme_MontantsTTC[0].LengthValeurs = 1 then begin UneCoherenceTrouvee := True; aRecSyntheseDoc.IndexRsltSomme_MontantsTTC := 0; end; // *** Finalisation *** // // Renvoyer les frais de port si montants HT non trouvés : if not UneCoherenceTrouvee then if (aRecSyntheseDoc.IndexRsltSomme_MontantsHT -1) and (aRecSyntheseDoc.IndexRsltFraisDePort -1) and (aRecSyntheseDoc.LengthFraisDePort > 1) then begin UneCoherenceTrouvee := true; aRecSyntheseDoc.IndexRsltFraisDePort := 0; // Celui trouvé par TcyDocER ... end; if (UneCoherenceTrouvee) and (Retours < 20) then begin Inc(Retours); Goto RelancerCoherence; end; end; end.
initialise_SyntheseDoc(MonRecSyntheseDoc);par
DefaultRecSyntheseDoc: RecSyntheseDoc = (NumFacture_ExpressionIndex : -1; DateFacture_ExpressionIndex: -1; TVAIntracom_ExpressionIndex: -1; NumSiret_ExpressionIndex : -1; Telephone_ExpressionIndex : -1; Fax_ExpressionIndex : -1; EMail_ExpressionIndex : -1; Website_ExpressionIndex : -1; NumClient_ExpressionIndex : -1; IndexRsltSomme_MontantsTVA : -1; IndexRsltTauxTVA : -1; IndexRsltTotalTVA : -1; IndexRsltSomme_MontantsHT : -1; IndexRsltTotalHT : -1; IndexRsltRemiseHT : -1; IndexRsltFraisDePort : -1; IndexRsltSomme_MontantsTTC : -1; IndexRsltTotalTTC : -1; IndexRsltDebitAnterieur : -1; IndexRsltNetAPayer : -1 );
procedure CheckRecSyntheseDoc(const aRecSyntheseDoc: RecSyntheseDoc); begin Assert(aRecSyntheseDoc.LengthSomme_MontantsTVA = Length(aRecSyntheseDoc.Somme_MontantsTVA)); Assert(aRecSyntheseDoc.LengthTauxTVA = Length(aRecSyntheseDoc.TauxTVA )); Assert(aRecSyntheseDoc.LengthTotalTVA = Length(aRecSyntheseDoc.TotalTVA )); Assert(aRecSyntheseDoc.LengthSomme_MontantsHT = Length(aRecSyntheseDoc.Somme_MontantsHT )); Assert(aRecSyntheseDoc.LengthTotalHT = Length(aRecSyntheseDoc.TotalHT )); Assert(aRecSyntheseDoc.LengthRemiseHT = Length(aRecSyntheseDoc.RemiseHT )); Assert(aRecSyntheseDoc.LengthFraisDePort = Length(aRecSyntheseDoc.FraisDePort )); Assert(aRecSyntheseDoc.LengthSomme_MontantsTTC = Length(aRecSyntheseDoc.Somme_MontantsTTC)); Assert(aRecSyntheseDoc.LengthTotalTTC = Length(aRecSyntheseDoc.TotalTTC )); Assert(aRecSyntheseDoc.LengthDebitAnterieur = Length(aRecSyntheseDoc.DebitAnterieur )); Assert(aRecSyntheseDoc.LengthNetAPayer = Length(aRecSyntheseDoc.NetAPayer )); end;
unit Unit1; interface uses Windows, SysUtils, Generics.Collections; {/* En mode "Yes we can !" */} type TPointXY = packed record { Toujours en packed } public X, Y : integer; { Une structure simple pour l'exemple ... TPoint } public class function create(aX, aY: integer): TPointXY; static; // p0 := TPointXY.Create(12, 24); { fonction statique qui permet de créer un TPointXY rapidement. Peut être appelée du type ou d'une variable : P0 := TPointXY.Create( Rect.Left, Rect.Top ); ou P1 := P0.Create( Rect.Left-2, Rect.Top-2 ); } procedure assign(aX, aY: integer); // p0.assign(24, 32); { fonction qui permet d'assigner X et Y en une seule ligne P1.Assign( Rect.Right, Rect.Bottom ); } procedure reset; // X=0 Y=0 { fonction qui remet à zéro X et Y P1.Reset; } { Surcharge des opérateurs pour TPointXY } class operator explicit(A: Windows.TPoint): TPointXY; // interroperability with Windows.TPoint { Assignation à un TPointXY à partir d'un TPoint P1 := Form1.ClientRect.TopLeft; } class operator explicit(A: TPointXY): Windows.TPoint; // '' { Assignation à un TPoint à partir d'un TPointXY Form1.ClientRect.RightBottom := P1; } class operator explicit(A: TPointXY): string; // str :p0; -> str "X, Y" class operator implicit(A: TPointXY): string; // string(p0); -> ("X, Y") { Assignation explicite et implicite d'un TPointXY sur une chaine. LabelPoint.Caption := P0; // Explicit call Str := string(P0); // Implicit call } class operator equal(A,B: TPointXY): boolean; // p0 p1 -> bool exp (A.X B.X) AND (A.Y = B.Y) class operator notEqual(A,B: TPointXY): boolean; // p0 <> p1 -> bool exp (A.X <> B.X) OR (A.Y <> B.Y) class operator logicalOr(A: TPointXY; B: integer): boolean; // p0 OR 12 -> bool exp (X 12) OR (Y 12) class operator logicalAnd(A: TPointXY; B: integer): boolean; // p0 AND 12 -> bool exp (X 12) AND (Y 12) class operator logicalXor(A: TPointXY; B: integer): boolean; // p0 XOR 12 -> bool exp (X 12) XOR (Y 12) class operator add(A, B: TPointXY): TPointXY; // p2 :p0 + p1 -> p2.[X|Y] p0.[X|Y] + p1.[X|Y] class operator subtract(A, B: TPointXY): TPointXY; // p2 :p0 - p1 -> p2.[X|Y] p0.[X|Y] - p1.[X|Y] //class operator greaterThan(A,B: TPointXY): boolean; // p0 > p1 -> bool exp (A.X > B.X) OR (A.Y > B.Y) //class operator greaterThanOrEqual(A,B: TPointXY): boolean; // p0 >= p1 -> bool exp (A.X >= B.X) OR (A.Y >= B.Y) //class operator lessThan(A,B: TPointXY): boolean; // p0 < p1 -> bool exp (A.X < B.X) OR (A.Y < B.Y) //class operator lessThanOrEqual(A,B: TPointXY): boolean; // p0 <= p1 -> bool exp (A.X <= B.X) OR (A.Y <= B.Y) //class operator multiply(A, B: TPointXY): TPointXY; // p2 :p0 * p1 -> p2.[X|Y] p0.[X|Y] * p1.[X|Y] //class operator divide(A, B: TPointXY): TPointXY; // p2 :p0 / p1 -> p2.[X|Y] round(p0.[X|Y] / p1.[X|Y]) //class operator intDivide(A, B: TPointXY): TPointXY; // p2 :p0 div p1 -> p2.[X|Y] p0.[X|Y] DIV p1.[X|Y] //class operator add(A: TPointXY; B: integer): TPointXY; // p1 := p0 + 8 //class operator substract(A: TPointXY; B: integer): TPointXY; // p1 := p0 - 8 //class operator multiply(A: TPointXY; B: integer): TPointXY; // p1 := p0 * 2 //class operator multiply(A: TPointXY; B: extended): TPointXY; // p1 := p0 * sin(Pi*2) //class operator divide(A: TPointXY; B: integer): TPointXY; // p1 := p0 / 2 //class operator divide(A: TPointXY; B: extended): TPointXY; // p1 := p0 / cos(Pi*2) end; { TPoints on utilise le type TList générique (pas le classes.TList ! nuance) } TPoints = TList<TPointXY>; // <- to easy, hop on a un Liste de TPointXY pas besoin de surcharger un classes.TList ... { Type de liste de Points } TCalcPointIndexs = ( rpiA, rpiB, rpiSum, rpiDiff ); { TCalc Permet de stocker 4 liste distinctes de Points : A et B, provenant de calculs ou d'une image etc. Sum somme de A et B Diff différence entre A et B La tache est simplifiée par l'utilisation du TList<> et de la surcharge des opérateurs sur TPointXY } TCalc = packed record private fInitialized: boolean; // controle d'initialisation True si Initialize à été appelée, sinon false function getMaxCountAB: integer; // renvois le Count de la plus petite des listes entre A et B public Points : array[TCalcPointIndexs] of TPoints; // 4 listes A, B, Sum et Diff public procedure MakeSum; // Construit la liste de sommes A+B procedure MakeDiff;// Construit la liste de différence A-B procedure Initialize;// à appeler pour initialiser les listes TPoints, Bloc Try / Finally requit ! procedure Finalize; // à appeler pour finaliser le TCalc (detruit les listes TPoints) end; implementation { Ici, une implémentation fortement réduite grace au type TList<> générique et les surcharge d'opérateurs. } { TCalc } procedure TCalc.Finalize; var i : TCalcPointIndexs; begin assert(fInitialized, 'Calc not initialized.'); for i := low(TCalcPointIndexs) to high(TCalcPointIndexs) do Points[i].Free; end; function TCalc.getMaxCountAB: integer; begin assert(fInitialized, 'Calc not initialized.'); if Points[rpiA].Count > Points[rpiB].Count then result := Points[rpiB].Count else result := Points[rpiA].Count; end; procedure TCalc.Initialize; var i : TCalcPointIndexs; begin if not fInitialized then begin fInitialized := true; for i := low(TCalcPointIndexs) to high(TCalcPointIndexs) do begin Points[i] := TPoints.Create; fInitialized := fInitialized and assigned(Points[i]); end; end; end; procedure TCalc.MakeDiff; var I,C: integer; begin assert(fInitialized, 'Calc not initialized.'); Points[rpiDiff].Clear; C := getMaxCountAB; for I := 0 to C - 1 do Points[rpiDiff].Add( Points[rpiA].Items[I] - Points[rpiB].Items[I] ); end; procedure TCalc.MakeSum; var I,C: integer; begin assert(fInitialized, 'Calc not initialized.'); Points[rpiSum].Clear; C := getMaxCountAB; for I := 0 to C - 1 do Points[rpiSum].Add( Points[rpiA].Items[I] + Points[rpiB].Items[I] ); end; { TPointXY } class operator TPointXY.add(A, B: TPointXY): TPointXY; begin result.X := A.X + B.X; result.Y := A.Y + B.Y; end; procedure TPointXY.assign(aX, aY: integer); begin X := aX; Y := aY; end; class function TPointXY.create(aX, aY: integer): TPointXY; begin result.X := aX; result.Y := aY; end; class operator TPointXY.equal(A, B: TPointXY): boolean; begin result :(A.X B.X) and (A.Y = B.Y); end; class operator TPointXY.explicit(A: TPointXY): string; begin result := format('%d x %d',[A.X, A.Y]); end; class operator TPointXY.explicit(A: Windows.TPoint): TPointXY; begin result.X := A.X; result.Y := A.Y; end; class operator TPointXY.explicit(A: TPointXY): Windows.TPoint; begin result.X := A.X; result.Y := A.Y; end; class operator TPointXY.implicit(A: TPointXY): string; begin result := A; // call Explicit(TPointX): string end; class operator TPointXY.logicalAnd(A: TPointXY; B: integer): boolean; begin result :(A.X B) and (A.Y = B); end; class operator TPointXY.logicalOr(A: TPointXY; B: integer): boolean; begin result :(A.X B) or (A.Y = B); end; class operator TPointXY.logicalXor(A: TPointXY; B: integer): boolean; begin result :(A.X B) xor (A.Y = B); end; class operator TPointXY.notEqual(A, B: TPointXY): boolean; begin result := (A.X <> B.X) or (A.Y <> B.Y); end; procedure TPointXY.reset; begin X := 0; Y := 0; end; class operator TPointXY.subtract(A, B: TPointXY): TPointXY; begin result.X := A.X - B.X; result.Y := A.Y - B.Y; end; end.