#include #include #include #include #include #include #include #include #include #include "at3.h" // nomi campi maschera #include "at3900a.h" // nomi dei campi #include "soggetti.h" #include "atstats.h" #include "sezioni.h" #include "comuni.h" // classe per la definizione di una riga di statistica class TRigaSxCom : public TObject { TString16 _com; TArray _valori; protected: const TRigaSxCom& copy(const TRigaSxCom& riga); public: const TString16 com() const { return _com; } TObject* dup() const { return new TRigaSxCom(*this); } const TRigaSxCom& operator = (const TRigaSxCom& riga); const real& operator [] (int colonna) const; void aggiorna_valore(int colonna, const real& numero) ; void azzera_valori(); // costruttore TRigaSxCom(TString16 com) {_com = com;} // costruttore di copia TRigaSxCom(const TRigaSxCom& riga) { copy(riga); } virtual ~TRigaSxCom() {}; }; const TRigaSxCom& TRigaSxCom::copy(const TRigaSxCom& riga) { _com = riga._com; _valori = riga._valori; return (*this); } const TRigaSxCom& TRigaSxCom::operator = (const TRigaSxCom& riga) { copy(riga); return (*this); } const real& TRigaSxCom::operator [] (int colonna) const { real* valore = (real*)_valori.objptr(colonna); if (valore == NULL) return ZERO; else return *valore; } void TRigaSxCom::aggiorna_valore(int colonna, const real& numero) { real* valore = (real*)_valori.objptr(colonna); if (valore == NULL) _valori.add(new real(numero), colonna); else *valore += numero; } void TRigaSxCom::azzera_valori() { _valori.destroy(); } class TStatSogxCom : public TApplication { TMask* _msk; TRelation* _rel; TCursor* _cur; TLocalisamfile* _sezioni; TLocalisamfile* _comuni; TLocalisamfile* _soggetti; TLocalisamfile* _atstats; TAssoc_array* _colonne; TAssoc_array* _comprovincia; TAssoc_array _categorie; TArray _righe, _righetotali; TString16 _sezini, _sotini, _sezfin, _sotfin, _provincia; TDate _dataini, _datafin; static bool filter_func_statxcom(const TRelation* rel); protected: virtual bool create(); virtual bool destroy(); virtual bool menu(MENU_TAG m); virtual TMask& get_mask() { return *_msk; } virtual TRelation* get_relation() const { return _rel; } int data2row(const TString16 com); bool riepilogo(); bool stampa(); bool crea_colonne(); bool crea_righe(); void azzera_righe(); void stampa_sezione(TString16 codsez, TString16 codsot); void stampa_totali(); void crea_intestazione(); public: TStatSogxCom() {} }; HIDDEN inline TStatSogxCom& app() { return (TStatSogxCom&) main_app(); } int TStatSogxCom::data2row(const TString16 com) { real& indicer = (real&)_comprovincia->find((const char*) com); return ((int) indicer.integer()); } bool TStatSogxCom::crea_colonne() { _colonne->destroy(); real contatore(ZERO); real* oggetto = new real(contatore); const char* indice = "T"; // tutti i donatori _colonne->add(indice,(TObject*)oggetto); return TRUE; } bool TStatSogxCom::filter_func_statxcom(const TRelation* rel) { bool filtrato = TRUE; TLocalisamfile& sog = rel->lfile(LF_SOGGETTI); // filtro per categorie TAssoc_array& categorie = app()._categorie; if (categorie.items() != 0) { const TString16 cat = sog.get(SOG_CATDON); filtrato = categorie.is_key((const char*) cat); } return filtrato; } bool TStatSogxCom::crea_righe() { TLocalisamfile comuni(LF_COMUNI); comuni.setkey(2); TString16 com = "****"; int indice = 0; _comprovincia->destroy(); real* oggetto1 = new real(indice); _comprovincia->add((const char*) com, (TObject*) oggetto1); _righe.add(new TRigaSxCom(com), indice); _righetotali.add(new TRigaSxCom(com), indice); comuni.zero(); for (comuni.first(); !comuni.eof(); comuni.next()) { TString provincia = comuni.get(COM_PROVCOM); if (provincia == _provincia) { indice++; com = comuni.get(COM_COM); _righe.add(new TRigaSxCom(com), indice); _righetotali.add(new TRigaSxCom(com), indice); real* oggetto = new real(indice); _comprovincia->add((const char*) com,(TObject*) oggetto); } } return _righe.items()>0; } bool TStatSogxCom::create() { TApplication::create(); _msk = new TMask("at3900a"); _rel = new TRelation(LF_SOGGETTI); _rel->add(LF_COMUNI, "COM==DOM_CODCOM"); _soggetti = new TLocalisamfile(LF_SOGGETTI); _atstats = new TLocalisamfile(LF_ATSTATS); _sezioni = new TLocalisamfile(LF_SEZIONI); _comuni = new TLocalisamfile(LF_COMUNI); _colonne = new TAssoc_array(); _comprovincia = new TAssoc_array(); dispatch_e_menu(BAR_ITEM(1)); return TRUE; } bool TStatSogxCom::destroy() { delete _comprovincia; delete _colonne; delete _comuni; delete _sezioni; delete _atstats; delete _soggetti; delete _rel; delete _msk; return TApplication::destroy(); } bool TStatSogxCom::menu(MENU_TAG m) { TMask& msk = get_mask(); KEY tasto; tasto = msk.run(); if (tasto == K_ENTER) { _sezini = _msk->get(F_SEZINI); _sotini = _msk->get(F_SOTINI); _sezfin = _msk->get(F_SEZFIN); _sotfin = _msk->get(F_SOTFIN); _provincia = _msk->get(F_PROVINCIA); if (riepilogo()) stampa(); } return FALSE; } void TStatSogxCom::crea_intestazione() { TPrintrow row; TString256 sep; sep = "STATISTICA SOGGETTI PER COMUNE DI DOMICILIO"; sep.center_just(80); row.put(sep); row.put("@>", 1); row.put("Pag. @#", 70); printer().setheaderline(2, row); sep = "Categorie "; sep << _msk->get(F_CAT1) << " "; sep << _msk->get(F_CAT2) << " "; sep << _msk->get(F_CAT3) << " "; sep << _msk->get(F_CAT4) << " "; sep << _msk->get(F_CAT5) << " "; sep << _msk->get(F_CAT6) << " "; sep.center_just(80); row.reset(); row.put(sep); printer().setheaderline(3, row); sep = ""; sep << "Comune Numero"; row.reset(); row.put(sep); printer().setheaderline(5, row); sep = ""; sep.fill('-',80); row.reset(); row.put(sep); printer().setheaderline(6, row); } bool TStatSogxCom::stampa() { if (printer().open()) { crea_intestazione(); TRelation* relstat = new TRelation(LF_ATSTATS); TCursor* curstat = new TCursor(relstat, "", 1); TString16 oldsez = "**"; TString16 oldsot = "**"; double numero; TString16 actsez, actsot; TString16 com; long last = curstat->items(); for ( *curstat=0; curstat->pos() < last; ++(*curstat) ) { actsez = curstat->curr().get(ATSS_CODSEZ); actsot = curstat->curr().get(ATSS_CODSOT); com = curstat->curr().get(ATSS_COM); numero = (double)curstat->curr().get_int(ATSS_NUMERO); if (actsez != oldsez || actsot != oldsot) { if (oldsez != "**" && oldsot != "**") { stampa_sezione(oldsez,oldsot); azzera_righe(); } oldsez = actsez; oldsot = actsot; } if (com.empty()) com = "****"; TRigaSxCom& riga = (TRigaSxCom&)_righe[data2row(com)]; TRigaSxCom& rigatotale = (TRigaSxCom&)_righetotali[data2row(com)]; const char* indicen = "T"; real& colonnan = (real&)_colonne->find(indicen); real n = numero; riga.aggiorna_valore((int) colonnan.integer(),n); rigatotale.aggiorna_valore((int) colonnan.integer(),n); } if (oldsez != "**" && oldsot != "**") { stampa_sezione(oldsez,oldsot); if ((_sezini != _sezfin) || (_sotini != _sotfin)) stampa_totali(); } delete curstat; delete relstat; printer().close(); return TRUE; } else return FALSE; } void TStatSogxCom::azzera_righe() { for (int i=0; i<_righe.items(); i++) { TRigaSxCom& riga = (TRigaSxCom&)_righe[i]; riga.azzera_valori(); } } void TStatSogxCom::stampa_sezione(TString16 codsez, TString16 codsot) { TPrintrow row; TString256 rigastampa; rigastampa = "Sezione: "; rigastampa << codsez; if (codsot.not_empty()) { rigastampa << "/"; rigastampa << codsot; } rigastampa << " "; TLocalisamfile sezioni(LF_SEZIONI); sezioni.setkey(1); sezioni.zero(); sezioni.put(SEZ_CODSEZ,codsez); sezioni.put(SEZ_CODSOT,codsot); if (sezioni.read() == NOERR) { TString80 den = sezioni.get(SEZ_DENSEZ); rigastampa << den; den = sezioni.get(SEZ_DENSOT); if (den.not_empty()) { rigastampa << "/"; rigastampa << den; } } rigastampa.center_just(80); row.put(rigastampa); printer().setheaderline(1, row); TLocalisamfile comuni(LF_COMUNI); comuni.setkey(1); TRigaSxCom rigatotali(" "); TString16 valore; TString16 com; for (int i=0; i<_righe.items(); i++) { TRigaSxCom& riga = (TRigaSxCom&)_righe[i]; const char* indicet = "T"; real& colonnat = (real&)_colonne->find(indicet); if (riga[(int) colonnat.integer()] != 0) { rigatotali.aggiorna_valore((int) colonnat.integer(),riga[(int) colonnat.integer()]); row.reset(); rigastampa = ""; rigastampa << riga.com(); rigastampa << " "; comuni.zero(); comuni.put(COM_COM,riga.com()); if (comuni.read() == NOERR) rigastampa << comuni.get(COM_DENCOM); int pos = 41; valore = ""; valore.format("%8s",riga[(int) colonnat.integer()].string(8,0)); rigastampa.overwrite((const char*)valore, pos); pos = pos+8; row.put((const char*) rigastampa); printer().print(row); } } // stampa totali per sezione rigastampa = ""; rigastampa.fill('-',80); row.reset(); row.put(rigastampa); printer().print(row); row.reset(); rigastampa = ""; rigastampa = "Totale"; int pos = 41; const char* indicet = "T"; real& colonnat = (real&)_colonne->find(indicet); valore = ""; valore.format("%8s",rigatotali[(int) colonnat.integer()].string(8,0)); rigastampa.overwrite((const char*)valore, pos); pos = pos+8; row.put((const char*) rigastampa); printer().print(row); printer().formfeed(); } void TStatSogxCom::stampa_totali() { TPrintrow row; TString256 rigastampa; rigastampa = "Riepilogo sezioni stampate"; rigastampa.center_just(80); row.put(rigastampa); printer().setheaderline(1, row); TLocalisamfile comuni(LF_COMUNI); comuni.setkey(1); TRigaSxCom rigatotali(" "); TString16 valore; TString16 com; for (int i=0; i<_righe.items(); i++) { TRigaSxCom& riga = (TRigaSxCom&)_righetotali[i]; const char* indicet = "T"; real& colonnat = (real&)_colonne->find(indicet); if (riga[(int) colonnat.integer()] != 0) { rigatotali.aggiorna_valore((int) colonnat.integer(),riga[(int) colonnat.integer()]); row.reset(); rigastampa = ""; rigastampa << riga.com(); rigastampa << " "; comuni.zero(); comuni.put(COM_COM,riga.com()); if (comuni.read() == NOERR) rigastampa << comuni.get(COM_DENCOM); int pos = 41; valore = ""; valore.format("%8s",riga[(int) colonnat.integer()].string(8,0)); rigastampa.overwrite((const char*)valore, pos); pos = pos+8; row.put((const char*) rigastampa); printer().print(row); } } // stampa totali per sezione rigastampa = ""; rigastampa.fill('-',80); row.reset(); row.put(rigastampa); printer().print(row); row.reset(); rigastampa = ""; rigastampa = "Totale"; int pos = 41; const char* indicet = "T"; real& colonnat = (real&)_colonne->find(indicet); valore = ""; valore.format("%8s",rigatotali[(int) colonnat.integer()].string(8,0)); rigastampa.overwrite((const char*)valore, pos); pos = pos+8; row.put((const char*) rigastampa); printer().print(row); printer().formfeed(); } bool TStatSogxCom::riepilogo() { if (crea_colonne() && crea_righe()) { // cancello i risultati della elaborazione precedente TLocalisamfile stat(LF_ATSTATS); for (stat.first(); !stat.eof(); stat.next()) stat.remove(); stat.setkey(1); _cur = new TCursor(_rel, "", 1); TString256 filtro = ""; // filtro per sezione/sottogruppo if (_sezini.not_empty()) { if (_sotini.not_empty()) { filtro << "("; filtro << format("(90->CODSEZ > \"%s\")",(const char*)_sezini); filtro << " || "; filtro << "(" << format("(90->CODSEZ == \"%s\")",(const char*)_sezini); filtro << " && "; filtro << format("(90->CODSOT >= \"%s\")",(const char*)_sotini); filtro << ")"; filtro << ")"; } else filtro << format("(90->CODSEZ >= \"%s\")",(const char*)_sezini); } if (_sezfin.not_empty()) { if (filtro.not_empty()) filtro << " && "; if (_sotfin.not_empty()) { filtro << "("; filtro << format("(90->CODSEZ < \"%s\")",(const char*)_sezfin); filtro << " || "; filtro << "(" << format("(90->CODSEZ == \"%s\")",(const char*)_sezfin); filtro << " && "; filtro << format("(90->CODSOT <= \"%s\")",(const char*)_sotfin); filtro << ")"; filtro << ")"; } else filtro << format("(90->CODSEZ <= \"%s\")",(const char*)_sezfin); } if (filtro.not_empty()) filtro << " && "; filtro << format("(13->PROVCOM == \"%s\")",(const char*)_provincia); _cur->setfilter((const char*) filtro, TRUE); _categorie.destroy(); const TString16 catpri = _msk->get(F_CAT1); const TString16 catsec = _msk->get(F_CAT2); const TString16 catter = _msk->get(F_CAT3); const TString16 catqua = _msk->get(F_CAT4); const TString16 catqui = _msk->get(F_CAT5); const TString16 catses = _msk->get(F_CAT6); if (catpri.not_empty()) _categorie.add((const char*) catpri); if (catsec.not_empty()) _categorie.add((const char*) catsec); if (catter.not_empty()) _categorie.add((const char*) catter); if (catqua.not_empty()) _categorie.add((const char*) catqua); if (catqui.not_empty()) _categorie.add((const char*) catqui); if (catses.not_empty()) _categorie.add((const char*) catses); _cur->set_filterfunction(filter_func_statxcom); TString16 codsez, codsot; long numero; TString16 com; TRectype& recsog = _cur->curr(); long last = _cur->items(); TProgind prg (last, "Elaborazione in corso... Prego attendere", FALSE, TRUE, 30); for ( *_cur=0; _cur->pos() < last; ++(*_cur) ) { prg.addstatus(1); codsez = recsog.get(SOG_CODSEZ); codsot = recsog.get(SOG_CODSOT); com = recsog.get(SOG_DOM_CODCOM); if (com.empty()) com = "****"; stat.zero(); stat.put(ATSS_CODSEZ, codsez); stat.put(ATSS_CODSOT, codsot); stat.put(ATSS_COM, com); if (stat.read() == NOERR) { numero = stat.get_long(ATSS_NUMERO); numero++; stat.put(ATSS_NUMERO, numero); stat.rewrite(); } else { stat.put(ATSS_CODSEZ, codsez); stat.put(ATSS_CODSOT, codsot); stat.put(ATSS_COM, com); numero = 1; stat.put(ATSS_NUMERO, numero); stat.write(); } } return (stat.eod() > 0); } else return FALSE; } int at3900(int argc, char* argv[]) { TStatSogxCom a; a.run(argc, argv, "Statistica soggetti per comune di domicilio"); return 0; }