Fórum Conciliação bancária #465955
06/01/2014
0
Estou desenvolvendo a opção de conciliação bancária de um sistema, procurei na internet sobre isso e código em Delphi, e encontrei o código abaixo (código que fiz algumas poucas alterações), mas se por exemplo eu leio um OFX do Itaú ele funciona, já para o Banco do Brasil não, pois existe uma diferença de tags, e se eu adapto para o BB aí não funciona para o Itaú. O problema é que isto pode ocorrer com outros bancos, gostaria de algo genérico. Acredito que isto deveria ser um padrão.
Alguém tem alguma ideia, dica, código de como eu poderia proceder?
Segue o código:
unit YMOFXReader_2;
interface
uses classes, SysUtils, Controls;
type
TOFXItem = class
MovType : string;
MovDate : TDate;
Value : double;
ID : string;
Document : string;
Desc : string;
CheckNum:string;
end;
TYMOFXReader = class(TComponent)
public
BankID : integer;
AccountID : string;
AccountType : string;
InitialBalance : double;
FinalBalance : double;
DtStart,DtEnd:TDate;
Ag,CC:string;
Org:string;
constructor Create( AOwner: TComponent ); override;
destructor Destroy; override;
function Process: boolean;
function Get(iIndex: integer): TOFXItem;
function Count: integer;
private
FOFXFile : string;
FListItems : TList;
procedure Clear;
procedure Delete( iIndex: integer );
function Add: TOFXItem;
function PrepareFloat( sString : string ) : string;
function InfLine ( sLine : string ): string;
function FindString ( sSubString, sString : string ): boolean;
function ReplaceString(sString: string; sOld: string; sNew: string; bInsensitive : boolean = true): string;
protected
published
property OFXFile: string read FOFXFile write FOFXFile;
end;
procedure Register;
implementation
constructor TYMOFXReader.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FListItems := TList.Create;
end;
destructor TYMOFXReader.Destroy;
begin
FListItems.Free;
inherited Destroy;
end;
procedure TYMOFXReader.Delete( iIndex: integer );
begin
TOFXItem(FListItems.Items[iIndex]).Free;
FListItems.Delete( iIndex );
end;
procedure TYMOFXReader.Clear;
//var
// i: integer;
// oPointer : Pointer;
begin
while FListItems.Count > 0 do
Delete(0);
FListItems.Clear;
end;
function TYMOFXReader.Count: integer;
begin
Result := FListItems.Count;
end;
function TYMOFXReader.Get(iIndex: integer): TOFXItem;
begin
Result := TOFXItem(FListItems.Items[iIndex]);
end;
function TYMOFXReader.Process: boolean;
var
oFile : TStringList;
i : integer;
bOFX : boolean;
oItem : TOFXItem;
sLine : string;
dBalance : double;
begin
Result := false;
Clear;
bOFX := false;
if not FileExists(FOFXFile) then
exit;
oFile := TStringList.Create;
oFile.LoadFromFile(FOFXFile);
dBalance := 0;
i := 0;
while i < oFile.Count do
begin
sLine := oFile.Strings[i];
if FindString('<OFX>', sLine) then
bOFX := true;
if bOFX then
begin
// -----------------------------------------------------------------------
// BankID
if FindString('<BANKID>', sLine) then BankID := StrToIntDef(InfLine(sLine), 0);
// -----------------------------------------------------------------------
// AccountID
if FindString('<ACCTID>', sLine) then AccountID := InfLine(sLine);
// -----------------------------------------------------------------------
// AccountType
if FindString('<ACCTTYPE>', sLine) then AccountType := InfLine(sLine);
// -----------------------------------------------------------------------
// FinalBalance
if FindString('<LEDGER>', sLine) then FinalBalance := StrToFloat(PrepareFloat(InfLine(sLine)));
// -----------------------------------------------------------------------
//DtStart
if FindString('<DTSTART>', sLine) then DtStart := EncodeDate(StrToIntDef(copy(InfLine(sLine),1,4), 0),
StrToIntDef(copy(InfLine(sLine),5,2), 0),
StrToIntDef(copy(InfLine(sLine),7,2), 0));
// -----------------------------------------------------------------------
//DtEnd
if FindString('<DTEND>', sLine) then DtEnd := EncodeDate(StrToIntDef(copy(InfLine(sLine),1,4), 0),
StrToIntDef(copy(InfLine(sLine),5,2), 0),
StrToIntDef(copy(InfLine(sLine),7,2), 0));
// -----------------------------------------------------------------------
//Agência
if FindString('<BRANCHID>', sLine) then Ag := InfLine(sLine);
// -----------------------------------------------------------------------
//Conta corrente
if FindString('<ACCTID>', sLine) then CC := InfLine(sLine);
// -----------------------------------------------------------------------
//Organização
if FindString('<ORG>', sLine) then Org := InfLine(sLine);
// -----------------------------------------------------------------------
// Moviment
if FindString('<STMTTRN>', sLine) then
begin
oItem := Add;
Inc(i);
sLine := oFile.Strings[i];
if FindString('<TRNTYPE>', sLine) then oItem.MovType := InfLine(sLine);
Inc(i);
sLine := oFile.Strings[i];
if FindString('<DTPOSTED>', sLine) then oItem.MovDate := EncodeDate(StrToIntDef(copy(InfLine(sLine),1,4), 0),
StrToIntDef(copy(InfLine(sLine),5,2), 0),
StrToIntDef(copy(InfLine(sLine),7,2), 0));
Inc(i);
sLine := oFile.Strings[i];
if FindString('<TRNAMT>', sLine) then
begin
oItem.Value := StrToFloat(PrepareFloat(InfLine(sLine)));
dBalance := dBalance - oItem.Value;
end;
Inc(i);
sLine := oFile.Strings[i];
if FindString('<FITID>', sLine) then oItem.ID := InfLine(sLine);
Inc(i);
sLine := oFile.Strings[i];
//if FindString('<CHKNUM>', sLine) then oItem.Document := InfLine(sLine);
if FindString('<CHECKNUM>', sLine) then oItem.CheckNum := InfLine(sLine);
Inc(i);
sLine := oFile.Strings[i];
if FindString('<REFNUM>', sLine) then oItem.Document := InfLine(sLine);
Inc(i);
sLine := oFile.Strings[i];
if FindString('<MEMO>', sLine) then oItem.Desc := InfLine(sLine);
// end;
end;
// -----------------------------------------------------------------------
end;
Inc(i);
end;
InitialBalance := FinalBalance + dBalance;
Result := bOFX;
end;
function TYMOFXReader.PrepareFloat( sString : string ) : string;
begin
Result := sString;
Result := ReplaceString(Result, '.', FormatSettings.DecimalSeparator);
Result := ReplaceString(Result, ',', FormatSettings.DecimalSeparator);
end;
function TYMOFXReader.ReplaceString(sString: string; sOld: string; sNew: string; bInsensitive : boolean = true): string;
var
iPosition: integer ;
sTempNew: string ;
begin
iPosition := 1;
sTempNew := '';
while (iPosition > 0) do
begin
if bInsensitive then
iPosition := AnsiPos(UpperCase(sOld),UpperCase(sString))
else
iPosition := AnsiPos(sOld,sString);
if (iPosition > 0) then
begin
sTempNew := sTempNew + copy(sString, 1, iPosition - 1) + sNew;
sString := copy(sString, iPosition + Length(sOld), Length(sString) );
end;
end;
sTempNew := sTempNew + sString;
Result := (sTempNew);
end;
function TYMOFXReader.InfLine ( sLine : string ): string;
var
iTemp : integer;
begin
Result := '';
sLine := Trim(sLine);
if FindString('>', sLine) then
begin
sLine := Trim(sLine);
iTemp := Pos('>', sLine);
Result := copy(sLine, iTemp+1, Length(sLine)-iTemp+1);
end;
//26/12/2013
if FindString('<', result) then
begin
sLine := Trim(result);
iTemp := Pos('<', result);
Result := copy(result, 1, iTemp-1);
end;
end;
function TYMOFXReader.Add: TOFXItem;
var
oItem : TOFXItem;
begin
oItem := TOFXItem.Create;
FListItems.Add(oItem);
Result := oItem;
end;
function TYMOFXReader.FindString ( sSubString, sString : string ): boolean;
begin
Result := Pos(UpperCase(sSubString), UpperCase(sString)) > 0;
end;
procedure Register;
begin
RegisterComponents('YoungArts', [TYMOFXReader]);
end;
end.
Obrigado desde já!
Rubens Filho
Curtir tópico
+ 0Post mais votado
08/01/2014
Acredito que deste modo posso resolver qualquer tipo de layout que apareça. O que eu fiz foi que a cada linha que passe do arquivo OFX é procurado qual tag da linha correspondente se encaixa em um conjunto de tags, assim, bastando incluir neste conjunto de tags a nova tag que não possui, assim:
procedure TYMOFXReader.ProcuraTag(vTag: string;var oItem : TOFXItem);
begin
if FindString('<TRNTYPE>', vTag) then oItem.MovType := InfLine(vTag);
if FindString('<DTPOSTED>', vTag) then oItem.MovDate := EncodeDate(StrToIntDef(copy(InfLine(vTag),1,4), 0),
StrToIntDef(copy(InfLine(vTag),5,2), 0),
StrToIntDef(copy(InfLine(vTag),7,2), 0));
if FindString('<TRNAMT>', vTag) then
begin
oItem.Value := StrToFloat(PrepareFloat(InfLine(vTag)));
//dBalance := dBalance - oItem.Value;
end;
if FindString('<FITID>', vTag) then oItem.ID := InfLine(vTag);
//if FindString('<CHKNUM>', vTag) then oItem.Document := InfLine(vTag);
if FindString('<CHECKNUM>', vTag) then oItem.CheckNum := InfLine(vTag);
if FindString('<REFNUM>', vTag) then oItem.Document := InfLine(vTag);
if FindString('<MEMO>', vTag) then oItem.Desc := InfLine(vTag);
end;
Agora o código todo fica assim:
[code]
unit YMOFXReader_2;
interface
uses classes, SysUtils, Controls;
type
TOFXItem = class
MovType : string;
MovDate : TDate;
Value : double;
ID : string;
Document : string;
Desc : string;
CheckNum:string;
end;
TYMOFXReader = class(TComponent)
public
BankID : integer;
AccountID : string;
AccountType : string;
InitialBalance : double;
FinalBalance : double;
DtStart,DtEnd:TDate;
Ag,CC:string;
Org:string;
constructor Create( AOwner: TComponent ); override;
destructor Destroy; override;
function Process: boolean;
function Get(iIndex: integer): TOFXItem;
function Count: integer;
private
FOFXFile : string;
FListItems : TList;
procedure Clear;
procedure Delete( iIndex: integer );
function Add: TOFXItem;
function PrepareFloat( sString : string ) : string;
function InfLine ( sLine : string ): string;
function FindString ( sSubString, sString : string ): boolean;
function ReplaceString(sString: string; sOld: string; sNew: string; bInsensitive : boolean = true): string;
procedure ProcuraTag(vTag:string;var oItem : TOFXItem);
protected
published
property OFXFile: string read FOFXFile write FOFXFile;
end;
procedure Register;
implementation
constructor TYMOFXReader.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FListItems := TList.Create;
end;
destructor TYMOFXReader.Destroy;
begin
FListItems.Free;
inherited Destroy;
end;
procedure TYMOFXReader.Delete( iIndex: integer );
begin
TOFXItem(FListItems.Items[iIndex]).Free;
FListItems.Delete( iIndex );
end;
procedure TYMOFXReader.Clear;
//var
// i: integer;
// oPointer : Pointer;
begin
while FListItems.Count > 0 do
Delete(0);
FListItems.Clear;
end;
function TYMOFXReader.Count: integer;
begin
Result := FListItems.Count;
end;
function TYMOFXReader.Get(iIndex: integer): TOFXItem;
begin
Result := TOFXItem(FListItems.Items[iIndex]);
end;
function TYMOFXReader.Process: boolean;
var
oFile : TStringList;
i : integer;
bOFX : boolean;
oItem : TOFXItem;
sLine : string;
dBalance : double;
begin
Result := false;
Clear;
bOFX := false;
if not FileExists(FOFXFile) then
exit;
oFile := TStringList.Create;
oFile.LoadFromFile(FOFXFile);
dBalance := 0;
i := 0;
while i < oFile.Count do
begin
sLine := oFile.Strings[i];
if FindString('<OFX>', sLine) then
bOFX := true;
if bOFX then
begin
// -----------------------------------------------------------------------
// BankID
if FindString('<BANKID>', sLine) then BankID := StrToIntDef(InfLine(sLine), 0);
// -----------------------------------------------------------------------
// AccountID
if FindString('<ACCTID>', sLine) then AccountID := InfLine(sLine);
// -----------------------------------------------------------------------
// AccountType
if FindString('<ACCTTYPE>', sLine) then AccountType := InfLine(sLine);
// -----------------------------------------------------------------------
// FinalBalance
if FindString('<LEDGER>', sLine) then FinalBalance := StrToFloat(PrepareFloat(InfLine(sLine)));
// -----------------------------------------------------------------------
//DtStart
if FindString('<DTSTART>', sLine) then DtStart := EncodeDate(StrToIntDef(copy(InfLine(sLine),1,4), 0),
StrToIntDef(copy(InfLine(sLine),5,2), 0),
StrToIntDef(copy(InfLine(sLine),7,2), 0));
// -----------------------------------------------------------------------
//DtEnd
if FindString('<DTEND>', sLine) then DtEnd := EncodeDate(StrToIntDef(copy(InfLine(sLine),1,4), 0),
StrToIntDef(copy(InfLine(sLine),5,2), 0),
StrToIntDef(copy(InfLine(sLine),7,2), 0));
// -----------------------------------------------------------------------
//Agência
if FindString('<BRANCHID>', sLine) then Ag := InfLine(sLine);
// -----------------------------------------------------------------------
//Conta corrente
if FindString('<ACCTID>', sLine) then CC := InfLine(sLine);
// -----------------------------------------------------------------------
//Organização
if FindString('<ORG>', sLine) then Org := InfLine(sLine);
// -----------------------------------------------------------------------
// Moviment
if FindString('<STMTTRN>', sLine) then
begin
oItem := Add;
Inc(i);
sLine := oFile.Strings[i];
ProcuraTag(sLine,oItem);
//if FindString('<TRNTYPE>', sLine) then oItem.MovType := InfLine(sLine);
Inc(i);
sLine := oFile.Strings[i];
ProcuraTag(sLine,oItem);
//if FindString('<DTPOSTED>', sLine) then oItem.MovDate := EncodeDate(StrToIntDef(copy(InfLine(sLine),1,4), 0),
// StrToIntDef(copy(InfLine(sLine),5,2), 0),
//
Rubens Filho
Gostei + 1
Mais Posts
06/01/2014
Douglas
infelizmente terá que realizar verificações código.
Gostei + 0
06/01/2014
Leandro Chiodini
Boa tarde Amigo,
Posso te falar, pois programo muito esse tipo de rotina,
Infelizmente cada banco tem o seu layout,
hoje nao existe um layout unificado para todos os bancos
em materia de conciliação,
entao infelizmente você tera que desenvolver, uma rotina para o BB
e outra para outro banco.
A dica que eu te dou, antes de desenvolver um novo, da uma olhada nos que voce ja tem,
pois alguns bancos utilizam layouts iguais, porem pode acontecer o que você esta vendo agora.
dois diferentes,
dai neste caso, voce precisa fazer o tratamento , diferente por bancos.
espero ter ajudado.
att
Chiodini
Gostei + 0
06/01/2014
Alan Souza
Gostei + 0
07/01/2014
Rubens Filho
Farei algo genérico mesmo e irei especializando.
Abraços.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)