XTRACT Scripting Beispiele

Einfache Formularidentifizierung

Das Beispiel zeigt eine einfache Formularidentifizierung wie sie auch ohne Scripting mittels zweier Identifier Felder (Relevance je 50) realisiert werden kann.   

function ccXtractResultHandler : Variant;
begin
  Result   := 0;
  PageText := ccXtractDocument.GetPageText(0);

  if (pos('R E C H N U N G',PageText) > 0) and
     (pos('RechnungsNr',PageText) > 0) then
  begin
    Result := 100;
  end;  
end;

Dynamische Bereichsauswertung 

Das Beispiel ermittelt jeweils den Text des oberen Drittels jeder Seite und sucht dort nach einem Datum im DE Format.

function ccXtractResultHandler : Variant;
begin
  Result   := '';

  for i:=0 to PageCount-1 do
  begin
    Text := ccXtractDocument.GetTextArea(
              i,ccXZT_Object,ccXZA_Loose,ccXCM_Dynamic,0,0,100,30);

    Date := GetFromRegularExpression(' \d{1,2}\.\d{1,2}\.\d{2,4}',Text,',');

    if length(Date) > 0 then
    begin
      Result := Date;
      break;
    end;
  end;
end;

Keyword Search 

Das Script sucht nach Vorkommen der Schlüsselwörter „Rechnung“ und „RECHNUNG“ und gibt die Ergebnisse im Logging aus. 

Function ccXtractResultHandler : Variant;
var
  KW       : Variant;
  KWX      : Variant;
  Hits     : Variant;
begin
  KW  := VarArrayCreate([0,1],varVariant);
  KWX := VarArrayCreate([0,1],varVariant);

  Hits := ccXtractDocument.Search(
            0,['Rechnung','RECHNUNG'],KWX,ccXSA_clarcPatternMatching,60);

  // Alternativer Aufruf
  // KW[0] := 'Rechnung';
  // KW[1] := 'RECHNUNG';
  // Hits := ccXtractDocument.Search(
  //           0,KW,KWX,ccXSA_clarcPatternMatching,60);

  for i:=VarArrayLowBound(Hits,1) to VarArrayHighBound(Hits,1) do
  begin
    Text        := Hits[i,0];
    Accuracy    := Hits[i,1];
    StartObject := Hits[i,2];
    EndObject   := Hits[i,3];

    ccXtractProject.log(
      'search hit'+inttostr(i)+': '+Text+' '+RealToStr(Accuracy,2)+
      '% ['+inttostr(StartObject)+'-'+inttostr(EndObject)+']');
  end;
end;

Feldbezogene Datumsprüfung

Mit diesen Scripten auf Feldebene können deutsche und amerikanische Datumswerte (+ ISO) geprüft werden. Die Erkennung erfolgt unabhängig von der OS oder Gui Sprache.

Im zweiten Script werden auch Strings mit mehreren Datumswerten untereinander (Trenner ist 0Ah) unterstützt. 

// ==================================================================================
// Date verification 1
// ==================================================================================

function CheckDate(DateStr) : Variant;
begin
  Result := 0;

  // ISO Date
  try
    Result := StrToDateExt(DateStr,'yyyy-mm-dd');
    exit;
  except
  end;

  // German date
  try
    Result := StrToDateExt(DateStr,'dd.mm.yyyy');
    exit;
  except
  end;

  // US date
  try
    Result := StrToDateExt(DateStr,'mm/dd/yyyy');
    exit;
  except
  end;
end;


function ccXtractResultHandler : Variant;
begin
  Result := '';
  DateStr := ccXtractProject.GetFieldValueByName( 
  ccXtractProject.InProcessFieldName );
  MyDate := CheckDate(DateStr);

  if MyDate = 0
    then Result := ''
    else Result := FormatDateTime('yyyy-mm-dd',MyDate);
end;

// ==================================================================================
// eof
 // ==================================================================================
 // Date verification 2
 // ==================================================================================
 
 function ccXtractResultHandler : Variant;
 begin
   Result := '';
   DateStr := ccXtractProject.GetFieldValueByName( 
   ccXtractProject.InProcessFieldName ) + chr($0A);
 
   while pos(chr($0A),DateStr) > 0 do
   begin
     CDate := trim(copy(DateStr,1,pos(chr($0A),DateStr)));
     ODate := CDate;
     dd    := '';
     mm    := '';
     yy    := '';
 
     // German date
     if pos('.',CDate) > 0 then
     begin
       CDate := CDate + '.';
       dd := copy(CDate,1,pos('.',CDate)-1); delete(CDate,1,pos('.',CDate));
       mm := copy(CDate,1,pos('.',CDate)-1); delete(CDate,1,pos('.',CDate));
       yy := copy(CDate,1,pos('.',CDate)-1); delete(CDate,1,pos('.',CDate));
     end;
 
     // US date
     if pos('/',CDate) > 0 then
     begin
       CDate := CDate + '/'; 
       mm := copy(CDate,1,pos('.',CDate)-1); delete(CDate,1,pos('.',CDate));
       dd := copy(CDate,1,pos('.',CDate)-1); delete(CDate,1,pos('.',CDate));
       yy := copy(CDate,1,pos('.',CDate)-1); delete(CDate,1,pos('.',CDate));
     end;
 
     if length(yy) = 2 then yy := copy(formatdatetime('yyyy',Now),1,2) + yy;
 
     try
       myDate := EncodeDate(strtoint(yy),strtoint(mm),strtoint(dd));
       Result := Result + FormatDateTime('dd.mm.yyyy',myDate) + lfcr;
     except
     end;
 
     delete(DateStr,1,pos(chr($0A),DateStr));
   end;
 
   Result := trim(Result);
 end;
 
 // ==================================================================================
 // eof

Validation Beispiel

Das hier aufgeführte Beispiel stammt aus dem XCONTROL Validation Modul.

// ==================================================================================
// DetermineValidationStack 
// ==================================================================================

Function ccXtractValidationProcessor : Variant;
Begin                                                                           
  Result := True;                          
                                                 
  // ------------------------------------------------------------
  // Ressourcen laden
  // ------------------------------------------------------------
  ValidationStacks             := ccScriptEngine.GetResource('ValidationStacks','');
  ValidationStackAutoSelection := ccScriptEngine.GetResource('ValidationStackAutoSelection',false);
  ValidationRules              := ccScriptEngine.GetResource('ValidationRules','');
  ValidationStackRotationId    := ccScriptEngine.GetResource('ValidationStackRotationId',-1);

  if length(ValidationStacks) > 0 then ValidationStacks := ValidationStacks + lfcr;
  if length(ValidationRules)  > 0 then ValidationRules  := ValidationRules  + lfcr;

  // ------------------------------------------------------------
  // Zuordnung                                      
  // ------------------------------------------------------------
  Stacks := TStringList.Create;
  try                           
    // ------------------------------------------------------------  
    // Verfügbare Stackliste erstellen
    // ------------------------------------------------------------  
    while pos(lfcr,ValidationStacks) > 0 do
    begin
      Stack := copy(ValidationStacks,1,pos(lfcr,ValidationStacks)-1);
      delete(ValidationStacks,1,pos(lfcr,ValidationStacks)+1);
      if length(Stack) > 0 then Stacks.Add(Stack);
    end;

    ccXtractProject.Log('found '+inttostr(Stacks.Count)+' validation stack(s)');

    // ------------------------------------------------------------
    if Stacks.Count > 0 then
    begin                                                      
      if ValidationStackAutoSelection = false then
      begin
        // ------------------------------------------------------------
        // Direkte Zuordnung
        // ------------------------------------------------------------
        ccXtractProject.Log('direct association to validation stack '+Stacks.Strings[0]);

        ccXtractProject.ValidationQueue := Stacks.Strings[0];
      end else
      begin
        if length(ValidationRules) > 0 then
        begin
          ccXtractProject.Log('checking validation rules');

          // ------------------------------------------------------------
          // Zuordnung nach Feldinhalt
          // ------------------------------------------------------------
          while pos(lfcr,ValidationRules) > 0 do
          begin
            hstr  := copy(ValidationRules,1,pos(lfcr,ValidationRules)-1);
            delete(ValidationRules,1,pos(lfcr,ValidationRules)+1);

            Field := copy(hstr,1,pos('=',hstr)-1); delete(hstr,1,pos('=',hstr));
            Value := copy(hstr,1,pos('=',hstr)-1); delete(hstr,1,pos('=',hstr));
            Stack := copy(hstr,1,length(hstr));

            ccXtractProject.Log('checking validation rule '+vartowidestr(ccXtractProject.GetFieldValue(Field))+' = '+Value);

            if vartowidestr(ccXtractProject.GetFieldValue(Field)) = Value then
            begin
              ccXtractProject.Log('using validation stack '+Stack);
              ccXtractProject.ValidationQueue := Stack;
              break;
            end;
          end;
        end else
        begin
          ccXtractProject.Log('checking stack rotation - current pos is '+inttostr(ValidationStackRotationId));

          // ------------------------------------------------------------
          // Rotierende Stapel
          // ------------------------------------------------------------
          inc(ValidationStackRotationId);
          if (ValidationStackRotationId > (Stacks.Count-1)) or
             (ValidationStackRotationId < 0) then ValidationStackRotationId := 0;

          ccXtractProject.Log('using validation stack '+Stacks.Strings[ValidationStackRotationId]);

          ccXtractProject.ValidationQueue := Stacks.Strings[ValidationStackRotationId];
          ccScriptEngine.SetResource('ValidationStackRotationId',ValidationStackRotationId);
        end;
      end;
    end;  
  finally
    Stacks.Free; 
  end;
End; 

// ==================================================================================
// eof

Headerauswertung mit clarc Xtract Schriftart

Dieses Beispiel entspricht der Umsetzung aus printCapture 2.x auf clarc Xtract bzw. printCapture 3.0. 

Auswertung eines in der Schriftart „clarc Xtract“ angedruckten Headers.

Der Headertext wird auch Blindtext oder Weißzeile genannt.

// ==================================================================================
// Xtract header processing
// ==================================================================================

// ----------------------------------------------------------------------------------
// Ermittelt den kompletten Header aus dem Dokument
// Header-Schriftart: "clarc Xtract"
// ----------------------------------------------------------------------------------

function GetHeaderText(Page,Blanks) : String;
begin
 Result := '';
 ZoneCount := ccXtractDocument.GetZoneCount(0);

 for i:=0 to ZoneCount-1 do
 begin
 if Uppercase(
 Replace(ccXtractDocument.GetZoneFont(0,i),' ','')) = 'CLARCXTRACT' then
 begin
 Result := Result + ccXtractDocument.GetZoneValue(0,i);
 if Blanks = true then Result := Result + ' ';
 end;
 end;

 Result := trim(Result);
end;

// ----------------------------------------------------------------------------------
// Gibt den Inhalt des angegeben Parameters aus dem Header zurück
// ----------------------------------------------------------------------------------
function GetHeaderValueByName(Header,Param) : String;
begin
 Result := '';
 Param := uppercase(Param);
 TmpHeader := Header;
 ParamPos := pos('@@'+Param,uppercase(TmpHeader));

 if ParamPos > 0 then
 begin
 delete(TmpHeader,1,ParamPos+1);
 delete(TmpHeader,1,pos('=',TmpHeader));
 Result := trim(copy(TmpHeader,1,pos('@@',TmpHeader)-1));
 end;
end;

// ----------------------------------------------------------------------------------
// Xtract document processor
// ----------------------------------------------------------------------------------
function ccXtractDocumentProcessor : Variant;
begin
 Result := true;

 Header := GetHeaderText(1,true);
 KundenNummer := GetHeaderValueByname(Header,'KDNR');
 KundenName := GetHeaderValueByname(Header,'KDNAM');

 ccXtractProject.Log('KundenNummer:' + KundenNummer);
 ccXtractProject.Log('KundenName:' + KundenName);

 ccXtractProject.SetFieldValueByName('KDNr',KundenNummer);
 ccXtractProject.SetFieldValueByName('Lieferant',KundenName);
end;

// ==================================================================================
// eof