Mega Code Archive

 
Categories / Delphi / Files
 

Generic File Importer Base Class

Title: Generic File Importer Base Class Question: Here is a useful base class to create derived classes to import data from any flat file format you can think of... ENJOY Answer: {----------------------------------------------------------------------------- Unit Name: classParentDataManipulator Author: StewartM (Stewart Moss) Documentation Date: 23, 08, 2002 (14:39,) Version 1.0 ----------------------------------------------------------------------------- Compiler Directives: Purpose: Dependancies: Description: Parent Class for data manipulation Creates the basic skelton for adding data manipulation sub-classes Each of the inherited classes must override the ProcessData method and provide their own properties specific to the class (ie Invoice Number etc...) Very useful class. inheritance Diagram + -- TParentDataProcessor // base class + | + --- TDerivedImporter // sub class Notes: History: Copyright 2002 by Stewart Moss. All rights reserved. -----------------------------------------------------------------------------} unit classParentDataManipulator; interface uses Sysutils, Classes; type TParentDataProcessor = class(TObject) private StringIn: string; LineCounter: Integer; public FieldNames, FieldValues, MultiFieldNames, MultiFieldValues: TStringList; FormName, FileName: string; Delimiters: string; // A list of delimiters (ie ',/[];:') used in inherited ProcessData() constructor create; destructor Destroy; Override; procedure ProcessFile; function DataAtPos(S: string; StartP, EndP: Integer): string; // Returns the data from "StartP" to "EndP" in String "S" function ExpandTabs(s: string): string; // ExpandTabs to 8 Spaces procedure ProcessData(StrIn: string; LineNumber: Integer); virtual; // Virtual method for override in sub-classes procedure FieldAdd(FieldName, Data: string; GenException: Boolean); // Adds FieldName and FieldValue to Strings and can generate exception if // string is empty when required procedure MultiFieldAdd(FieldName, Data: string; GenException: Boolean); // Adds FieldName and FieldValue to Multi Field Strings and can generate exception if // string is empty when required end; TProcessException = Exception; implementation var F: text; // Exception: TProcessException; { TDataProcessor } constructor TParentDataProcessor.create; begin inherited create; FieldNames := TStringList.Create; FieldValues := TStringList.Create; MultiFieldNames := TStringList.Create; MultiFieldValues := TStringList.Create; FieldNames.Clear; FieldValues.Clear; MultiFieldNames.Clear; MultiFieldValues.Clear; end; procedure TParentDataProcessor.ProcessFile; begin if Filename = '' then raise Exception.Create('No Filename specified'); try AssignFile(F, Filename); Reset(f); except try CloseFile(F); except end; raise Exception.Create('Could not open file ' + FileName); end; LineCounter := 0; while not eof(f) do begin Inc(LineCounter); try Readln(f, StringIn); except try CloseFile(f); except // swallow CloseFile errors end; raise Exception.Create('Could not read from file. Line number ' + IntToStr(LineCounter)); end; StringIn := ExpandTabs(StringIn); // Exapnd Tabs to 8 Spaces ProcessData(StringIn, LineCounter); // Execute virutal method in sub-classes passing current line and LineNumber end; try closefile(f); except raise Exception.Create('Could not close file ' + FileName); end; end; procedure TParentDataProcessor.ProcessData(StrIn: string; LineNumber: Integer); // Virtual method for override in sub-classes begin // end; destructor TParentDataProcessor.Destroy; begin FieldNames.Free; FieldValues.Free; MultiFieldNames.Free; MultiFieldValues.Free; end; function TParentDataProcessor.DataAtPos(S: string; StartP, EndP: Integer): string; begin // Returns the data from "StartP" to "EndP" in String "S" Result := trim(Copy(S, StartP, EndP - StartP)); end; function TParentDataProcessor.ExpandTabs(s: string): string; begin // ExpandTabs to 8 Spaces Result := StringReplace(S, #09, ' ', [rfReplaceAll]); end; procedure TParentDataProcessor.FieldAdd(FieldName, Data: string; GenException: Boolean); begin // Adds FieldName and FieldValue to Strings and can generate exception if // string is empty if (GenException) and (Data = '') then raise Exception.create('-- No ' + FieldName + ' Specified --'); Fieldnames.add(FieldName); FieldValues.add(Data); end; procedure TParentDataProcessor.MultiFieldAdd(FieldName, Data: string; GenException: Boolean); var loop: integer; flag: Boolean; begin // Adds FieldName and FieldValue to Multi Field Strings and can generate exception if // string is empty if (GenException) and (Data = '') then raise Exception.create('-- No Multiple Field - ' + FieldName + ' Specified --'); flag := false; loop:=0; while (loop MultiFieldNames.count ) and not flag do begin if MultiFieldNames.Strings[loop] = FieldName then flag := true; inc(Loop); end; dec(loop); if Flag then MultiFieldValues.Strings[loop] := MultiFieldValues.Strings[loop] + ';' + Data else begin MultiFieldNames.add(FieldName); MultiFieldValues.add(Data); end; end; end.