📄 qimport2ascii.pas
字号:
unit QImport2ASCII;
{$I VerCtrl.inc}
interface
uses Classes, QImport2, SysUtils, IniFiles;
type
TQImport2ASCII = class(TQImport2)
private
FComma: char;
FQuote: char;
//---
FFile: TextFile;
FColumns: TStrings;
FCounter: integer;
FBuffStr: string;
//---
function HasComma: boolean;
procedure ReadColumns(const Str: string; AStrings: TStrings);
protected
function CheckProperties: boolean; override;
procedure StartImport; override;
function CheckCondition: boolean; override;
function Skip: boolean; override;
procedure FillImportRow; override;
function ImportData: TQImportResult; override;
procedure ChangeCondition; override;
procedure FinishImport; override;
procedure DoLoadConfiguration(IniFile: TIniFile); override;
procedure DoSaveConfiguration(IniFile: TIniFile); override;
public
constructor Create(AOwner: TComponent); override;
published
property FileName;
property SkipFirstRows default 0;
property Comma: char read FComma write FComma;
property Quote: char read FQuote write FQuote;
end;
implementation
uses {$IFDEF WIN32}QImport2StrIDs{$ENDIF}
{$IFDEF LINUX}QImport2Consts{$ENDIF}, DB, QImport2Common;
{ TQImport2ASCII }
constructor TQImport2ASCII.Create(AOwner: TComponent);
begin
inherited;
SkipFirstRows := 0;
FComma := GetListSeparator;
FQuote := '"';
end;
function TQImport2ASCII.CheckProperties: boolean;
var
i, j: integer;
begin
Result := inherited CheckProperties;
if HasComma then begin // example field=2
for i := 0 to Map.Count - 1 do
try
StrToInt(Map.Values[Map.Names[i]]);
except
on E:EConvertError do raise EQImportError.Create({$IFDEF WIN32}QImportLoadStr(QIE_MapMissing){$ENDIF}
{$IFDEF LINUX}QIE_MapMissing{$ENDIF});
end;
end
else begin // example: field=3;5
for i := 0 to Map.Count - 1 do begin
j := Pos(';', Map.Values[Map.Names[i]]);
if j = 0 then raise EQImportError.Create({$IFDEF WIN32}QImportLoadStr(QIE_MapMissing){$ENDIF}
{$IFDEF LINUX}QIE_MapMissing{$ENDIF})
else begin
try
StrToInt(Copy(Map.Values[Map.Names[i]], 1, j - 1));
except
on E:EConvertError do raise EQImportError.Create({$IFDEF WIN32}QImportLoadStr(QIE_MapMissing){$ENDIF}
{$IFDEF LINUX}QIE_MapMissing{$ENDIF});
end;
try
StrToInt(Copy(Map.Values[Map.Names[i]], j + 1, Length(Map.Values[Map.Names[i]]) - j));
except
on E:EConvertError do raise EQImportError.Create({$IFDEF WIN32}QImportLoadStr(QIE_MapMissing){$ENDIF}
{$IFDEF LINUX}QIE_MapMissing{$ENDIF});
end;
end;
end;
end
end;
procedure TQImport2ASCII.StartImport;
begin
AssignFile(FFile, FileName);
Reset(FFile);
FColumns := TStringList.Create;
FCounter := 0;
end;
function TQImport2ASCII.CheckCondition: boolean;
begin
Result := not Eof(FFile);
end;
function TQImport2ASCII.Skip: boolean;
begin
Readln(FFile, FBuffStr);
Result := (SkipFirstRows > 0) and (FCounter < SkipFirstRows);
if Result then Inc(FCounter);
Result := Result or (Trim(FBuffStr) = EmptyStr);
end;
procedure TQImport2ASCII.FillImportRow;
var
j, k: integer;
begin
FImportRow.ClearValues;
ReadColumns(FBuffStr, FColumns);
for j := 0 to FImportRow.Count - 1 do begin
k := Map.IndexOfName(FImportRow[j].Name);
if (k > -1) and
(IsCSV or (QImportDestinationFindColumn(IsCSV, ImportDestination, DataSet,
{$IFNDEF NOGUI}DBGrid, ListView, StringGrid, GridCaptionRow,{$ENDIF}
FImportRow[j].Name) > -1) or
(ImportDestination = qidUserDefined)) then
begin
try
if HasComma
then FBuffStr := FColumns[StrToInt(Map.Values[Map.Names[k]]) - 1]
else FBuffStr := FColumns.Values[Map.Names[k]];
except
FBuffStr := EmptyStr;
end;
FImportRow.SetValue(Map.Names[k], FBuffStr, false);
end;
DoUserDataFormat(FImportRow[j]);
end;
end;
function TQImport2ASCII.ImportData: TQImportResult;
begin
Result := qirOk;
try
try
if Canceled and not CanContinue then
begin
Result := qirBreak;
Exit;
end;
DataManipulation;
except
on E:Exception do begin
try
DestinationCancel;
except
end;
DoImportError(E);
Result := qirContinue;
Exit;
end;
end;
finally
if (not IsCSV) and (CommitRecCount > 0) and not CommitAfterDone and
((ImportedRecs + ErrorRecs) mod CommitRecCount = 0) then
DoNeedCommit;
if (ImportRecCount > 0) and
((ImportedRecs + ErrorRecs) mod ImportRecCount = 0) then
Result := qirBreak;
end;
end;
procedure TQImport2ASCII.ChangeCondition;
begin
//
end;
procedure TQImport2ASCII.FinishImport;
begin
try
if not Canceled and not IsCSV then
begin
if CommitAfterDone then
DoNeedCommit
else if (CommitRecCount > 0) and ((ImportedRecs + ErrorRecs) mod CommitRecCount > 0) then
DoNeedCommit;
end;
finally
if Assigned(FColumns) then FColumns.Free;
CloseFile(FFile);
end;
end;
procedure TQImport2ASCII.DoLoadConfiguration(IniFile: TIniFile);
begin
inherited;
with IniFile do begin
SkipFirstRows := ReadInteger(ASCII_OPTIONS, ASCII_SKIP_LINES, SkipFirstRows);
Comma := Str2Char(ReadString(ASCII_OPTIONS, ASCII_COMMA,
Char2Str(Comma)), Comma);
Quote := Str2Char(ReadString(ASCII_OPTIONS, ASCII_QUOTE,
Char2Str(Quote)), Quote);
end;
end;
procedure TQImport2ASCII.DoSaveConfiguration(IniFile: TIniFile);
begin
inherited;
with IniFile do begin
WriteInteger(ASCII_OPTIONS, ASCII_SKIP_LINES, SkipFirstRows);
WriteString(ASCII_OPTIONS, ASCII_COMMA, Comma);
WriteString(ASCII_OPTIONS, ASCII_QUOTE, Quote);
end;
end;
function TQImport2ASCII.HasComma: boolean;
begin
Result := FComma <> #0;
end;
procedure TQImport2ASCII.ReadColumns(const Str: string; AStrings: TStrings);
var
SS: string;
P, L, i: integer;
begin
if HasComma then begin
CSVStringToStrings(Str, Quote, Comma, AStrings);
end
else begin // fixed width
AStrings.Clear;
for i := 0 to Map.Count - 1 do begin
SS := Map.Values[Map.Names[i]];
P := StrToIntDef(Copy(SS, 1, Pos(';', SS) - 1), 0);
L := StrToIntDef(Copy(SS, Pos(';', SS) + 1, Length(SS)), 0);
AStrings.Values[Map.Names[i]] := Copy(Str, P + 1, L);
end;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -