campo-sirio/ab/ab0400.cpp
alex eb2b326a11 Patch level : 2.2 23
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :

Riportate le modifiche dalla versione 2.1 222

Si puo cominciare a fare il primo CD


git-svn-id: svn://10.65.10.50/trunk@12708 c028cbd2-c16b-5b4b-a496-9718f37d4682
2005-02-17 18:13:12 +00:00

855 lines
23 KiB
C++
Executable File

#include "abpcon.h"
#include <automask.h>
#include <applicat.h>
#include <config.h>
#include <clifo.h>
#include <mask.h>
#include <pconti.h>
#include <progind.h>
#include <relation.h>
#include <rmov.h>
#include "saldi.h"
#include <utility.h>
#include "../cg/cglib01.h"
#include "../cg/cglib02.h"
#include "ab0.h"
#include "ab0400.h"
///////////////////////////////////////////////////////////
// TRicl_mask
///////////////////////////////////////////////////////////
class TRicl_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TRicl_mask() : TAutomask("ab0400a") { }
virtual ~TRicl_mask() { }
};
bool TRicl_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
const short id = o.dlg();
switch (id)
{
case F_ESER:
case F_PDB:
if (e == fe_modify)
{
TMask & m = o.mask();
const TString16 codpdb = m.get(F_PDB);
const int eser = m.get_int(F_ESER);
if (eser == 0 || codpdb.empty())
{
m.set(F_DAL, "");
m.set(F_AL, "");
}
else
{
TEsercizi_contabili es;
es.update();
const int anno = es.esercizio(eser).inizio().year();
const TRectype & pdb = cache().get("%PDB", codpdb);
TDate dal(pdb.get_int("I0"), pdb.get_int("I1"), anno);
TDate al(pdb.get_int("I2"), pdb.get_int("I3"), anno);
if (al < dal)
al.addyear(1);
m.set(F_DAL, dal);
m.set(F_AL, al);
}
}
break;
case F_DAL:
if (e == fe_close)
{
TMask & m = o.mask();
if (m.get(F_ESER).empty() && (m.get(F_DAL).empty() || m.get(F_AL).empty()))
return o.error_box(TR("E' necessario specificare o il codice esercizio oppure\nle date limite"));
}
break;
case F_OUTPUT:
if (e == fe_close)
{
if (o.get().empty())
return o.error_box(TR("E' necessario specificare il file di output"));
}
break;
default:
break;
}
return TRUE;
}
enum TCalc_type {_saldi = 0, _ivdircee, _analisi } ;
class TRiga_calcolo : public TObject
{
int _gruppo;
int _conto;
long _sottoconto;
int _indbil;
real _saldo_iniziale;
real _prog_dare;
real _prog_avere;
virtual TObject* dup() const { return new TRiga_calcolo(*this);}
public:
void set_conto(int g, int c, long s, int i) { _gruppo = g; _conto = c; _sottoconto = s; _indbil = i;}
void set_saldi(const real & si, const real & pd, const real & pa) { _saldo_iniziale = si;
_prog_dare = pd;
_prog_avere = pa;}
const int gruppo() const { return _gruppo;}
const int conto() const { return _conto;}
const long sottoconto() const { return _sottoconto;}
const int indicatore_bilancio() const { return _indbil;}
real saldo_iniziale() const { return _saldo_iniziale;}
real prog_dare() const { return _prog_dare;}
real prog_avere() const { return _prog_avere;}
real saldo() const { return _saldo_iniziale + _prog_dare - _prog_avere;}
bool sezione_opposta() const;
const bool is_zero() const { return _saldo_iniziale == ZERO && _prog_dare == ZERO && _prog_avere == ZERO;}
TRiga_calcolo& copy(const TRiga_calcolo& c);
TRiga_calcolo(const TRiga_calcolo& c);
TRiga_calcolo() {}
virtual ~TRiga_calcolo() {}
};
bool TRiga_calcolo::sezione_opposta() const
{
bool reverse = FALSE;
const real s = saldo();
if (s != ZERO)
{
char sezione = s > ZERO ? 'D' : 'A';
if (_indbil == 1 || _indbil == 3)
reverse = sezione == 'A';
else
if (_indbil == 2 || _indbil == 4)
reverse = sezione == 'D';
}
return reverse;
}
TRiga_calcolo & TRiga_calcolo::copy(const TRiga_calcolo & c)
{
_gruppo = c._gruppo;
_conto = c._conto;
_sottoconto = c._sottoconto;
_indbil = c._indbil;
_saldo_iniziale = c._saldo_iniziale;
_prog_dare = c._prog_dare;
_prog_avere = c._prog_avere;
return *this;
}
TRiga_calcolo::TRiga_calcolo(const TRiga_calcolo & c)
{
copy(c);
}
class TRiga_output : public TObject
{
TString _code;
real _saldo_iniziale;
real _prog_dare;
real _prog_avere;
virtual TObject* dup() const { return new TRiga_output(*this);}
public:
TRiga_output & operator +=(const TRiga_calcolo & c);
const TString & code() const { return _code;}
real saldo_iniziale() const { return _saldo_iniziale;}
real prog_dare() const { return _prog_dare;}
real prog_avere() const { return _prog_avere;}
real saldo() const { return _saldo_iniziale + _prog_dare - _prog_avere;}
char sezione_saldo() const { return saldo() > 0 ? 'D' : 'A';}
TRiga_output& copy(const TRiga_output& o);
TRiga_output(const TRiga_output& o);
TRiga_output(const char * code) : _code(code) {}
virtual ~TRiga_output() {}
};
TRiga_output & TRiga_output::operator += (const TRiga_calcolo & c)
{
_saldo_iniziale += c.saldo_iniziale();
_prog_dare += c.prog_dare();
_prog_avere += c.prog_avere();
return *this;
}
TRiga_output & TRiga_output::copy(const TRiga_output & o)
{
_code = o._code;
_saldo_iniziale = o._saldo_iniziale;
_prog_dare = o._prog_dare;
_prog_avere = o._prog_avere;
return *this;
}
TRiga_output::TRiga_output(const TRiga_output& o)
{
copy(o);
}
enum TFile_type { _textfile, _csvfile, _dbffile } ;
class TRicl_saldi : public TSkeleton_application
{
TRicl_mask *_mask;
TFilename _output_file;
TCalc_type _calc_type;
int _codes;
TDate _dal;
TDate _al;
bool _all_recs;
bool _provv;
TString _codpdb;
TString _codcms;
TArray _risultati;
TAssoc_array _output;
TString_array _output_keys;
ofstream * _file;
TExternisamfile * _dbf;
#ifdef DBG
protected:
FILE * _log;
void open_log();
void write_log(const char * line);
void close_log();
#endif
public:
virtual bool create();
virtual bool destroy();
void mask2parms(const TMask & m);
void ini2parms(const char * filename);
void calculate_clifo(const char tipo, const int gruppo, const int conto, const int indbil, const bool saldi_attuali, const TString & codcom);
void calculate();
void transform();
void get_code(const TRectype & rec, bool cee, bool reverse, TString & code);
void map(int gruppo, int conto, long sottoconto, bool reverse, TString & code);
void output();
virtual void main_loop();
TFile_type open_output();
void output_line(TFile_type t, const char * key, TRiga_output & r, const bool is_commessa, TString & codcms);
void close_output(TFile_type t);
TRicl_saldi() {}
virtual ~TRicl_saldi() {}
};
#ifdef DBG
void TRicl_saldi::open_log()
{
TFilename log("ab0400.log");
_log = fopen(log,"a");
if (_log == NULL)
fatal_box(FR("Non posso aprire il file di log della conversione(%s)"), (const char *) log);
}
void TRicl_saldi::write_log(const char * line)
{
fprintf(_log,"%s\n", line);
}
void TRicl_saldi::close_log()
{
fclose(_log);
}
#endif
bool TRicl_saldi::create()
{
open_files(LF_TAB, LF_TABCOM, LF_ABPCON, LF_ABSALDI, LF_SALDI, LF_RMOV, LF_MOV,
LF_PCON, 0);
_mask = new TRicl_mask();
return TSkeleton_application::create();
}
bool TRicl_saldi::destroy()
{
delete _mask;
return TSkeleton_application::destroy();
}
void TRicl_saldi::mask2parms(const TMask & m)
{
TEsercizi_contabili es;
_calc_type = (TCalc_type) m.get_int(F_TIPO);
_codes = m.get_int(F_ESER);
_dal = m.get(F_DAL);
_al = m.get(F_AL);
if (_codes != 0 && !_dal.ok())
_dal = es.esercizio(_codes).inizio();
if (_codes != 0 && !_al.ok())
_al = es.esercizio(_codes).fine();
if (_codes == 0)
{
_codes = es.date2esc(_dal);
if (_codes == 0)
_codes = es.date2esc(_al);
}
_all_recs = m.get_bool(F_STRUCT);
_provv = m.get_bool(F_PROVV);
_codcms = m.get(F_COMM);
_output_file = m.get(F_OUTPUT);
_codpdb = m.get(F_PDB);
#ifdef DBG
TString line ;
write_log("---------------------------------------------------");
line = TR("Tipo di calcolo : ");
switch (_calc_type)
{
case _saldi :
line << TR("Saldi Contabili");
break;
case _ivdircee :
line << TR("IV Direttiva CEE");
break;
case _analisi :
line << TR("Analisi");
break;
default :
break;
}
write_log(line);
line = TR("Esercizio : "); line << _codes;
write_log(line);
line = TR("Codice periodo : "); line << _codpdb;
write_log(line);
line = TR("Dal : "); line << _dal.string();
write_log(line);
line = TR("Al : "); line << _al.string();
write_log(line);
line = TR("Movimenti provv.: "); line << (_provv ? "Si" : "No");
write_log(line);
line = TR("Intera struttura: "); line << (_all_recs ? "Si" : "No");
write_log(line);
line = TR("Commessa : "); line << _codcms;
write_log(line);
line = TR("Output : "); line << ((const char *) _output_file);
write_log(line);
write_log("");
#endif
}
void TRicl_saldi::ini2parms(const char * filename)
{
TConfig c(filename, "Main");
TEsercizi_contabili es;
_calc_type = (TCalc_type) c.get_int("Tipo");
_codes = c.get_int("Esercizio");
_dal = c.get("Dal");
_al = c.get("Al");
if (_codes != 0 && !_dal.ok())
_dal = es.esercizio(_codes).inizio();
if (_codes != 0 && !_al.ok())
_al = es.esercizio(_codes).fine();
if (_codes == 0)
{
_codes = es.date2esc(_dal);
if (_codes == 0)
_codes = es.date2esc(_al);
}
_all_recs = c.get_bool("Struttura");
_provv = c.get_bool("Provvisori");
_codcms = c.get("Commessa");
_output_file = c.get("Output");
_codpdb = c.get("Periodo");
#ifdef DBG
TString line ;
write_log("---------------------------------------------------");
line = TR("Tipo di calcolo : ");
switch (_calc_type)
{
case _saldi :
line << TR("Saldi Contabili");
break;
case _ivdircee :
line << TR("IV Direttiva CEE");
break;
case _analisi :
line << TR("Analisi");
break;
default :
break;
}
write_log(line);
line = TR("Esercizio : "); line << _codes;
write_log(line);
line = TR("Codice periodo : "); line << _codpdb;
write_log(line);
line = TR("Dal : "); line << _dal.string();
write_log(line);
line = TR("Al : "); line << _al.string();
write_log(line);
line = TR("Movimenti provv.: "); line << (_provv ? "Si" : "No");
write_log(line);
line = TR("Intera struttura: "); line << (_all_recs ? "Si" : "No");
write_log(line);
line = TR("Commessa : "); line << _codcms;
write_log(line);
line = TR("Output : "); line << ((const char *) _output_file);
write_log(line);
write_log("");
#endif
}
void TRicl_saldi::calculate_clifo(const char tipo, const int gruppo, const int conto, const int indbil, const bool saldi_attuali, const TString & codcom)
{
TRelation relcf(LF_CLIFO);
TRectype & clifo = relcf.curr();
clifo.put(CLI_TIPOCF, tipo);
TCursor cur(&relcf, "", 1, &clifo, &clifo);
long sottoconto;
TSaldo sal;
TRiga_calcolo r;
const TRecnotype items = cur.items();
cur.freeze();
TString prompt = tipo == 'C' ? TR("Ricalcolo saldi Clienti") : TR("Ricalcolo saldi Fornitori");
prompt << ' ' << gruppo << ' ' << conto;
TProgind p(items, prompt, FALSE);
for (cur = 0L; !p.iscancelled() && cur.pos() < items; ++cur)
{
sottoconto = clifo.get_long(CLI_CODCF);
if (saldi_attuali)
sal.ultima_immissione_bilancio(_codes, gruppo, conto, sottoconto, indbil, _provv ? 2 :1, FALSE);
else
sal.saldo_periodo(gruppo, conto, sottoconto, _dal, _al, indbil, _provv, codcom);
r.set_conto(gruppo, conto, sottoconto, indbil);
r.set_saldi(sal.saldoini(), sal.prgdare(), sal.prgavere());
#ifdef DBG
TString line ;
line.format(FR("Conto %03d.%03d.%06ld - "), gruppo, conto, sottoconto);
line << TR("Saldo iniziale ") << sal.saldoini().stringa(18, 3);
line << TR(" Prog.Dare ") << sal.prgdare().stringa(18, 3);
line << TR(" Prog.Avere ") << sal.prgavere().stringa(18, 3);
line << TR(" Saldo ") << sal.saldo().stringa(18, 3);
write_log(line);
#endif
if (_all_recs || !r.is_zero())
_risultati.add(r);
p.addstatus(1L);
}
}
void TRicl_saldi::calculate()
{
TRelation relpcon(LF_PCON);
const TRectype & pcon = relpcon.curr();
TCursor cur(&relpcon, "CONTO!=0"); // Escludi i gruppi
int indbil = 0;
TSaldo sal;
TRiga_calcolo r;
TEsercizi_contabili es;
const TEsercizio & e = es.esercizio(_codes);
const bool is_commessa = _codcms.not_empty();
const bool saldi_attuali = (!is_commessa) && ((!_dal.ok() && !_al.ok()) || (_dal == e.inizio() && _al == e.fine()));
const TRecnotype items = cur.items();
cur.freeze();
_risultati.destroy();
TProgind p(items, TR("Ricalcolo saldi"), FALSE);
for (cur = 0L; !p.iscancelled() && cur.pos() < items; ++cur)
{
const int gruppo = pcon.get_int(PCN_GRUPPO);
const int conto = pcon.get_int(PCN_CONTO);
const long sottoconto = pcon.get_long(PCN_SOTTOCONTO);
if (sottoconto == 0L) // E' un conto
{
indbil = pcon.get_int(PCN_INDBIL);
const char tmcf = pcon.get_char(PCN_TMCF);
if (tmcf > ' ')
calculate_clifo(tmcf, gruppo, conto, indbil, saldi_attuali, _codcms);
}
else
{
if (saldi_attuali)
sal.ultima_immissione_bilancio(_codes, gruppo, conto, sottoconto, indbil, _provv ? 2 :1, FALSE);
else
sal.saldo_periodo(gruppo, conto, sottoconto, _dal, _al, indbil, _provv, _codcms);
r.set_conto(gruppo, conto, sottoconto, indbil);
r.set_saldi(sal.saldoini(), sal.prgdare(), sal.prgavere());
#ifdef DBG
TString line ;
line.format(FR("Conto %03d.%03d.%06ld - "), gruppo, conto, sottoconto);
line << TR("Saldo iniziale ") << sal.saldoini().stringa(18, 3);
line << TR(" Prog.Dare ") << sal.prgdare().stringa(18, 3);
line << TR(" Prog.Avere ") << sal.prgavere().stringa(18, 3);
line << TR(" Saldo ") << sal.saldo().stringa(18, 3);
write_log(line);
#endif
if (_all_recs || !r.is_zero())
_risultati.add(r);
p.addstatus(1L);
}
}
}
void TRicl_saldi::get_code(const TRectype &rec, bool cee, bool reverse, TString & code)
{
if (cee)
{
bool opp = reverse && rec.get_int(PCN_SEZIVDOPP) != 0;
code = rec.get(opp ? PCN_SEZIVDOPP : PCN_SEZIVD);
if (code == "0")
code.cut(0);
else
{
code << rec.get(opp ? PCN_LETTIVDOPP : PCN_LETTIVD);
code << format("%4s", (const char *) rec.get(opp ? PCN_NUMRIVDOPP : PCN_NUMRIVD));
const int numrivd = rec.get_int(opp ? PCN_NUMIVDOPP : PCN_NUMIVD);
if (numrivd != 0)
code << format("%02d", numrivd);
code.trim();
}
}
else
{
code = rec.get(PCN_CODCBL);
if (code.empty())
{
TToken_string key(rec.get(PCN_GRUPPO));
key.add(rec.get(PCN_CONTO));
key.add("");
const TRectype & conto = cache().get(LF_PCON, key);
code = conto.get(PCN_CODCBL);
}
}
}
void TRicl_saldi::map(int gruppo, int conto, long sottoconto, bool reverse, TString & code)
{
const bool no_map =_calc_type == _saldi;
if(no_map)
code.format("%03d|%03d|%06ld", gruppo, conto, sottoconto);
else
{
const bool cee =_calc_type == _ivdircee;
code.format("%d|%d|%ld", gruppo, conto, sottoconto);
const TRectype & recs = cache().get(LF_PCON, code);
get_code(recs, cee, reverse, code);
if (code.empty())
{
code.format("%d|%d", gruppo, conto);
const TRectype & recc = cache().get(LF_PCON, code);
get_code(recc, cee, reverse, code);
if (code.empty())
{
code.format("%d", gruppo);
const TRectype & recg = cache().get(LF_PCON, code);
get_code(recg, cee, reverse, code);
}
}
}
}
void TRicl_saldi::transform()
{
const int items = _risultati.items();
TString80 key;
_output.destroy();
for (int i = 0; i < items; i++)
{
const TRiga_calcolo & c = (const TRiga_calcolo &) _risultati[i];
const int gruppo = c.gruppo();
const int conto = c.conto();
const long sottoconto = c.sottoconto();
const bool reverse = c.sezione_opposta();
map(gruppo, conto, sottoconto, reverse, key);
if (key.not_empty())
{
TRiga_output * r = (TRiga_output *)_output.objptr(key);
if (r == NULL)
{
r = new TRiga_output(key);
_output.add(key, r);
}
*r += c;
}
}
}
TFile_type TRicl_saldi::open_output()
{
TString16 ext = _output_file.ext();
TFile_type t;
if (ext == "dbf")
t = _dbffile;
else
if (ext == "csv")
t = _csvfile;
else
t = _textfile;
if (t == _dbffile)
_dbf = new TExternisamfile(_output_file, "ab0400.trr");
else
{
if (_output_file.exist())
remove(_output_file);
_file = new ofstream(_output_file);
}
return t;
}
void TRicl_saldi::output_line(TFile_type t, const char * key, TRiga_output & r, const bool is_commessa, TString & codcms)
{
TString descr;
const bool analisi = _calc_type == _analisi;
const bool saldi = _calc_type == _saldi;
if (analisi)
descr = cache().get(LF_ABPCON, key, ABPC_DESCRIZ);
else
if (saldi)
descr = cache().get(LF_PCON, key, PCN_DESCR);
else
descr = cache().get("%IVD", key, "S0");
real si = r.saldo_iniziale();
char fsi = si >= ZERO ? 'D' : 'A';
real s = r.saldo();
char fs = s >= ZERO ? 'D' : 'A';
real pd = r.prog_dare();
real pa = r.prog_avere();
#ifdef DBG
TString line ;
line.format(FR("Chiave %s"), key);
line << TR("Saldo iniziale ") << si.stringa(18, 3) << " " << fsi;
line << TR(" Prog.Dare ") << pd.stringa(18, 3);
line << TR(" Prog.Avere ") << pa.stringa(18, 3);
line << TR(" Saldo ") << s.stringa(18, 3) << " " << fs;
write_log(line);
#endif
TFixed_string k(key, 40);
if (t == _dbffile)
{
TRectype & rec = _dbf->curr();
rec.put("ANNOES", _codes);
k.strip("|");
rec.put("KEY", k);
rec.put("DESCR", descr);
if (is_commessa)
rec.put("CODCMS", codcms);
rec.put("SALDOI", abs(si));
rec.put("FLAGSI", fsi);
rec.put("PDARE", pd);
rec.put("PAVERE", pa);
rec.put("SALDO", abs(s));
rec.put("FLAGS", fs);
rec.put("DATAI", _dal);
rec.put("DATAF", _al);
rec.put("CODPDB", _codpdb);
if (_dbf->write(rec) != NOERR)
_dbf->rewrite(rec);
}
else
{
real tmp;
if (t == _csvfile)
{
*_file << _codes << ";";
k.replace('|', ';');
*_file << k << ";";
if (is_commessa)
*_file << codcms << ";";
*_file << "\"" << descr << "\";";
tmp = abs(si);
*_file << tmp.stringa() << ";";
*_file << fsi << ";";
*_file << pd.stringa() << ";";
*_file << pa.stringa() << ";";
tmp = abs(s);
*_file << tmp.stringa() << ";";
*_file << fs << ";";
*_file << _dal << ";";
*_file << _al << ";";
*_file << _codpdb << "\n";
}
else
{
*_file << _codes << "\t";
k.replace('|', '\t');
*_file << k << "\t";
if (is_commessa)
*_file << codcms << "\t";
*_file << descr << "\t";
tmp = abs(si);
*_file << tmp.stringa() << "\t";
*_file << fsi << "\t";
*_file << pd.stringa() << "\t";
*_file << pa.stringa() << "\t";
tmp = abs(s);
*_file << tmp.stringa() << "\t";
*_file << fs << "\t";
*_file << _dal << "\t";
*_file << _al << "\t";
*_file << _codpdb << "\n";
}
}
}
void TRicl_saldi::close_output(TFile_type t)
{
if (t == _dbffile)
{
delete _dbf;
_dbf = NULL;
}
else
{
delete _file;
_file = NULL;
}
}
void TRicl_saldi::output()
{
_output_keys.destroy();
_output.get_keys(_output_keys);
_output_keys.sort();
const int items = _output_keys.items();
TFile_type t = open_output();
const bool analisi = _calc_type == _analisi;
const bool is_commessa = _codcms.not_empty();
if (analisi && !is_commessa)
{
TRelation relana(LF_ABSALDI);
TRectype & saldo = relana.curr();
saldo.put(ABS_CODDITTA, get_firm());
saldo.put(ABS_ANNO, _codes);
saldo.put(ABS_CODPDB, _codpdb);
TCursor cur(&relana, "", 1, &saldo, &saldo);
const TRecnotype curs_items = cur.items();
cur.freeze();
for (cur = 0L; cur.pos() < curs_items; ++cur)
relana.remove();
TProgind p(items, "Aggiornamenti Saldi analisi", FALSE);
int err = NOERR;
for (int i = 0; err == NOERR && i < items && !p.iscancelled(); i++)
{
TString & key = _output_keys.row(i);
TRiga_output & r = (TRiga_output &) _output[key];
saldo.zero();
saldo.put(ABS_CODDITTA, get_firm());
saldo.put(ABS_ANNO, _codes);
saldo.put(ABS_CODPDB, _codpdb);
saldo.put(ABS_CODCBL, key);
const real si = r.saldo_iniziale();
const char fsi = si >= ZERO ? 'D' : 'A';
saldo.put(ABS_FLDA, fsi);
saldo.put(ABS_SALDO, abs(si));
saldo.put(ABS_PDARE, r.prog_dare());
saldo.put(ABS_PAVERE, r.prog_avere());
err = relana.write();
if (err == _isreinsert)
err = relana.write();
p.addstatus(1L);
}
if (err != NOERR)
error_box("Impossibile aggiornare l'archivio saldi analisi errore n. %d", err);
}
TProgind p1(items, "Generazione output", FALSE);
for (int i = 0; i < items && !p1.iscancelled() ; i++)
{
TString & key = _output_keys.row(i);
TRiga_output & r = (TRiga_output &) _output[key];
output_line(t, key, r, is_commessa, _codcms);
p1.addstatus(1L);
}
close_output(t);
}
void TRicl_saldi::main_loop()
{
if (argc() == 2)
{
while (_mask->run() != K_QUIT)
{
#ifdef DBG
open_log();
#endif
mask2parms(*_mask);
calculate();
transform();
output();
#ifdef DBG
close_log();
#endif
}
}
else
{
#ifdef DBG
open_log();
#endif
ini2parms(argv(2));
calculate();
transform();
output();
#ifdef DBG
close_log();
#endif
}
}
int ab0400 (int argc, char* argv[])
{
TRicl_saldi main_app;
main_app.run(argc, argv, TR("Riclassificazione saldi"));
return TRUE;
}