Beispiel - AUTOMATION (CSV Importer)

Erläuterung

In diesem Beispiel wird ein einfacher und effizienter Importer für CSV Dateien implementiert.

Über Ressourcen können folgende Elemente konfiguriert werden:

  • ExportScheme (Für die weitere Verarbeitung)

  • PreScriptScheme (Für die weitere Verarbeitung)

  • SourcePath (Quellpfad mit Platzhaltern)

  • ErrorPath (Fehlerverzeichnis für fehlerhafte Zeilen in der CSV)

  • WriteMetaLog (Boolean)

  • Delimiter (Zeichen für Spaltentrenner - Standard ist $09)

  • DeleteSource (Boolean)

  • FileNameColumn (Name der Spalte die das Blob beinhaltet)

Skript

// ==================================================================================
// Info.............: CSV Import
// ----------------------------------------------------------------------------------
// Company..........: CTO Balzuweit GmbH
// ----------------------------------------------------------------------------------
// Creation.........: 29.09.2019
// Changed..........: 29.09.2019
// ==================================================================================

var
  Row              : Integer;
  eineCSV          : TStringList;
  eineCSVRow       : TStringList;
  einCSVHeader     : TStringList;
  iCSVDateipfade   : Integer;
  IndexFilenameCol : Integer;
  Document         : TccDocument;
  ExportScheme     : String;
  PreScriptScheme  : String;
  SourcPath        : String;
  BlobSourcePath   : String;
  WriteMetaLog     : Boolean;
  Delimiter        : String;
  DeleteSource     : Boolean;
  FileNameColumn   : String;

// ----------------------------------------------------------------------------------
// Datensatz in die Queue schreiben
// ----------------------------------------------------------------------------------
procedure CreateFileFromRow(SourcePath,ErrorPath,CSVFileName,ExportScheme,PreScriptScheme,Destination : String; var eineCSVHeaderRow : TStringList; var eineCSVRow : TStringList);
var
  Col : Integer;
begin
  Document.Clear;
  Document.Task            := ccQT_Export;
  Document.State           := ccQS_Idle;
  Document.ExportScheme    := ExportScheme;
  Document.PreScriptScheme := PreScriptScheme;
  Document.Destination     := Destination;
  Document.Id              := CreateId;

  ErrorText := '';

  if Pos('\',eineCSVRow[IndexFilenameCol]) > 0
    then Filename := eineCSVRow[IndexFilenameCol]
    else Filename := SourcePath + eineCSVRow[IndexFilenameCol];

  if FileExists(FileName) = true
    then Document.AddBlob(FileName)
    else ErrorText := 'blob file ' + FileName + ' not found!';

  for Col:=0 to eineCSVRow.Count-1 do
  begin
    if Col = IndexFilenameCol then continue;

    if WriteMetaLog = true
      then ccScriptEngine.Log(ccLog_Meta,eineCSVHeaderRow[Col] + ':' +  eineCSVRow[Col]);

    Document.SetFieldValue(eineCSVHeaderRow[Col],eineCSVHeaderRow[Col],eineCSVRow[Col]);
  end;

  if DeleteSource = true
    then CopyOrMove := ccTM_Move
    else CopyOrMove := ccTM_Copy;

  if (Document.SaveToQueue(true,CopyOrMove,'CSV_Importer') = false) or (Length(ErrorText) > 0) then
  begin
    ccScriptEngine.Log(ccLog_Debug, ErrorPath + CSVFileName + '_error');
    ccScriptEngine.Log(ccLog_Debug, eineCSVHeaderRow.DelimitedText);

    ErrorFileName := ErrorPath + CSVFileName + '_error';
    CreatePath(ErrorPath);

    if FileExists(ErrorFileName) = false
      then SaveStringToFile2(ErrorFileName, eineCSVHeaderRow.DelimitedText + CRLF, true);
    SaveStringToFile2(ErrorFileName, eineCSVRow.DelimitedText + CRLF, true);

    ccScriptEngine.Log(ccLog_Error, 'processing exception - ' + ErrorText + ' [' + eineCSVRow[0] + ']');
  end else ccScriptEngine.Log(ccLog_Success,'document with id ' + Document.Id + ' successfully imported');
end;

// ----------------------------------------------------------------------------------
// Hauptverarbeitung
// ----------------------------------------------------------------------------------
begin
  // --------------------------------------
  // Initialisierung
  // --------------------------------------
  Document           := TccDocument.Create;
  eineCSV            := TStringList.Create;
  eineCSVRow         := TStringList.Create;
  einCSVHeader       := TStringList.Create;
  vieleCSVDateipfade := UnAssigned;

  ExportScheme       := ccScriptEngine.GetResource('ExportScheme','');
  PreScriptScheme    := ccScriptEngine.GetResource('PreScriptScheme','');
  SourcePath         := ccScriptEngine.GetResource('SourcePath','');
  ErrorPath          := ccScriptEngine.GetResource('ErrorPath',ExtractFilePath(SourcePath) + 'error\');
  WriteMetaLog       := ccScriptEngine.GetResource('WriteMetaLog',false);
  Delimiter          := ccScriptEngine.GetResource('Delimiter',#09);
  DeleteSource       := ccScriptEngine.GetResource('DeleteSource',false);
  FileNameColumn     := ccScriptEngine.GetResource('FileNameColumn','FILENAME');

  eineCSVRow.Delimiter         := Delimiter;
  eineCSVRow.StrictDelimiter   := True;
  einCSVHeader.Delimiter       := Delimiter;
  einCSVHeader.StrictDelimiter := True;

  try
    // --------------------------------------
    // Durchsuche den SourcePath nach CSV Dateien
    // --------------------------------------
    GetFileList(SourcePath, 0, faOlder, vieleCSVDateipfade);

    if VarIsArray(vieleCSVDateipfade) then
    begin
      // --------------------------------------
      // Starte die Verarbeitung
      // --------------------------------------
      for iCSVDateipfade:=0 to VarArrayHighBound(vieleCSVDateipfade, 1) do
      begin
        ccScriptEngine.Log(ccLog_Info,'processing file ' + vieleCSVDateipfade[iCSVDateipfade]);

        eineCSV.LoadFromFile(vieleCSVDateipfade[iCSVDateipfade]);

        ccScriptEngine.Log(ccLog_Info,'rowcount is ' + IntToStr(eineCSV.Count));

        einCSVHeader.DelimitedText := eineCSV[0];
        IndexFilenameCol           := einCSVHeader.IndexOf(FileNameColumn);

        for Row:=1 to eineCSV.Count-1 do
        begin
          eineCSVRow.DelimitedText := eineCSV[Row];
          CreateFileFromRow(ExtractFilePath(SourcePath), ErrorPath, ExtractFileName(vieleCSVDateipfade[iCSVDateipfade]), ExportScheme, PreScriptScheme, 'document', einCSVHeader, eineCSVRow);
        end;

        // --------------------------------------
        // Nach Erfolgreicher Erstellung der Dokumente CSV Datei löschen
        // --------------------------------------
        if DeleteSource = true then
        begin
          ccScriptEngine.Log(ccLog_Info,'deleting source file ' + vieleCSVDateipfade[iCSVDateipfade]);
          DeleteFile(vieleCSVDateipfade[iCSVDateipfade],0,false);
        end;
      end;
    end;
  finally
    einCSVHeader.Free;
    eineCSVRow.Free;
    eineCSV.Free;
    Document.Free;
  end;
end;