// oggetto TCausale_magazzino // oggetto TMov_Mag , multirecord del movimento di magazzino // funzione di ricostruzione saldi #include #include #include "mglib.h" #include "movmag.h" #include "rmovmag.h" #include #ifndef __CGLIB01_H #include "../cg/cglib01.h" #endif #ifndef __DBLIB_H #include "../db/dblib.h" #endif // ********************* // movimenti di magazzino // movimenti // dati della linea di movimento di magazzino class TLine_movmag : public TObject { TString8 _codcaus; TString4 _um; real _quant, _prezzo; public: const TString& codcaus() const { return _codcaus; } const TString& um() const { return _um; } const real& quant() const { return _quant; } const real& prezzo() const { return _prezzo; } void set(const TString& cau, const TString& um, const real& q, const real& p); int operator==(const TLine_movmag&) const; virtual TObject* dup() const { return new TLine_movmag(*this); } TLine_movmag() {}; TLine_movmag(const TLine_movmag &); virtual ~TLine_movmag() {}; }; void TLine_movmag ::set(const TString& cau,const TString& um,const real& q, const real& p) { _codcaus=cau; _um=um; _quant=q; _prezzo=p; } TLine_movmag ::TLine_movmag(const TLine_movmag &l) { set(l._codcaus, l._um, l._quant, l._prezzo); } int TLine_movmag::operator==(const TLine_movmag &l) const { return (_codcaus==l._codcaus)&&(_um==l._um)&&(_quant==l._quant)&&(_prezzo==l._prezzo); } // ******************************** // TMov_mag TCausale_magazzino *TMov_mag::_causmag = NULL; TMov_mag::TMov_mag() : TMultiple_rectype(LF_MOVMAG), lines_to_add(), lines_to_subtract() { add_file(LF_RMOVMAG,"NRIG"); } TMov_mag::~TMov_mag() { } const TCausale_magazzino& TMov_mag::causale(const char* cod) const { if (cod == NULL || *cod == '\0') cod = get(MOVMAG_CODCAUS); if (!_causmag) _causmag = new TCausale_magazzino(cod); else *_causmag = cache().get("%CAU",cod); return *_causmag; } void TMov_mag::zero(char c) { TMultiple_rectype::zero(c); lines_to_add.destroy(); lines_to_subtract.destroy(); } // valuta il valore della chiave per un nuovo record bool TMov_mag::renum() { put(MOVMAG_NUMREG,get_next_key()); return TRUE; } // copia la chiave dal file principale a quello delle righe void TMov_mag::set_body_key(TRectype & rowrec) { rowrec.put(RMOVMAG_NUMREG,get(MOVMAG_NUMREG)); } void TMov_mag::load_rows_file(int logicnum) { CHECK(logicnum==LF_RMOVMAG,"L'unico file collegabile ai movimenti sono le righe"); TMultiple_rectype::load_rows_file(logicnum); mark_current_lines(); } int TMov_mag::remove(TBaseisamfile& f) const { const int res = TMultiple_rectype::remove(f); if (res == NOERR) { // effettua la variazione dei saldi ((TMov_mag *)this)->update_balances(); } return res; } void TMov_mag::add_extrarows() const { add_autorows(); add_explrows(); // if (add_explrows()) // add_autorows(); } bool TMov_mag::add_autorows() const { bool added=FALSE; TString8 codmag; // aggiunge le righe automatiche for (int r = rows(); r > 0; r--) { TRecord_array & b = body(); TRectype & row = b[r]; TString8 codcaus(row.get(RMOVMAG_CODCAUS)); if (codcaus.empty()) codcaus=get(MOVMAG_CODCAUS); const TCausale_magazzino& cau = causale(codcaus); codcaus=cau.caus_collegata(); if (codcaus.not_empty()) { const TCausale_magazzino& cau_coll = causale(codcaus); if (!row.get_bool(RMOVMAG_ESPLOSA)) { // deve esserci una riga collegata if (!b.exist(r + 1) || b[r + 1].get_char(RMOVMAG_TIPORIGA) != riga_automatica) { // manca, la inserisco TRectype * linea_auto = new TRectype(row); codmag = codmag_rauto(r); if (codmag.empty()) codmag = cau_coll.default_magdep(); if (codmag.not_empty()) linea_auto->put(RMOVMAG_CODMAG, codmag); const char * prezzo = prezzo_rauto(r); if (prezzo != NULL) linea_auto->put(RMOVMAG_PREZZO, prezzo); linea_auto->put(RMOVMAG_NRIG, r+1); linea_auto->put(RMOVMAG_TIPORIGA, (char) riga_automatica); linea_auto->put(RMOVMAG_CODCAUS, codcaus); b.insert_row(linea_auto); added=TRUE; } } } } // ciclo righe return added; } bool TMov_mag::add_explrows() const { TDistinta_tree distinta; TArticolo articolo; TArray boom; bool added=FALSE; TRecord_array& b = body(); // aggiunge le righe da explosione distinta for (int r = rows(); r > 0; r--) { const TRectype& row = b[r]; TString8 codcaus(row.get(RMOVMAG_CODCAUS)); if (codcaus.empty()) codcaus=get(MOVMAG_CODCAUS); const TCausale_magazzino& cau = causale(codcaus); if (cau.esplodente() && !row.get_bool(RMOVMAG_ESPLOSA)) { const TCodice_articolo codart = row.get(RMOVMAG_CODART); const char tipo_costo = cau.get("S11")[0]; const int livello = cau.get_int("I0"); const TString4 umroot(row.get(RMOVMAG_UM)); const int rigaprec = r - 1; const bool is_coll = r > 0 && b[r].get_char(RMOVMAG_TIPORIGA) == riga_automatica; // mancano le righe, le inserisco boom.destroy(); bool ok=distinta.set_root(row); if (ok) { bool stop_prod = cau.get_bool("B4"); distinta.explode(boom, TRUE, RAGGR_EXP_NONE, livello, "A", 0, stop_prod); //TString codmag(codmag_rauto(r)); real prezzo(prezzo_rauto(r)); TRectype * linea_auto; for (int newrow=0; newrow < boom.items() ; newrow++) { TRiga_esplosione & riga_esp=(TRiga_esplosione & )(boom[newrow]); linea_auto = new TRectype(row); linea_auto->put(RMOVMAG_CODART, riga_esp.articolo()); linea_auto->put(RMOVMAG_LIVGIAC, riga_esp.giacenza()); linea_auto->put(RMOVMAG_UM, riga_esp.um()); linea_auto->put(RMOVMAG_QUANT, riga_esp.val()); //if (codmag.not_empty()) // linea_auto->put(RMOVMAG_CODMAG, codmag); //if (!prezzo.is_zero()) articolo.read(riga_esp.articolo()); if (tipo_costo == 'U') prezzo = articolo.get_real(ANAMAG_ULTCOS1); else if (tipo_costo == 'S') prezzo = articolo.get_real(ANAMAG_COSTSTD); linea_auto->put(RMOVMAG_PREZZO, prezzo); linea_auto->put(RMOVMAG_NRIG, r+1+newrow); linea_auto->put(RMOVMAG_ESPLOSA, TRUE); char coll_type = articolo.get_char(ANAMAG_COLLTYPE); TString8 codmag; if (coll_type == 'M') { if (is_coll) codmag = b[rigaprec].get(RMOVMAG_CODMAG); } else if (coll_type == 'F') { TString16 key("F|"); key << articolo.get(ANAMAG_CODFORN); codmag = cache().get(LF_CFVEN, key, CFV_CODMAG); } else if (coll_type == 'A') codmag = articolo.get(ANAMAG_CODMAG); if (codmag.not_empty()) linea_auto->put(RMOVMAG_CODMAG, codmag); b.insert_row(linea_auto); added=TRUE; } // ora ci sono, mi basta eliminare la riga "padre" if (boom.items() > 0 ) { if (boom.items() == 1 && codart == ((TRiga_esplosione &)boom[0]).articolo()) error_box(FR("Movimento di magazzino %ld:\ndistinta %s ciclica"), get_long(MOVMAG_NUMREG),(const char *)codart); b.destroy_row(r,TRUE); } else message_box(FR("Movimento di magazzino %ld:\nimpossibile esplodere l'articolo %s"), get_long(MOVMAG_NUMREG),(const char *)codart); } else if (b[r].get_char(RMOVMAG_TIPORIGA) == riga_automatica) b.destroy_row(r,TRUE); } } // ciclo righe return added; } int TMov_mag::write(TBaseisamfile& f) const { int res; add_extrarows(); if ((res=TMultiple_rectype::write(f))==NOERR ) { TMov_mag &myself=((TMov_mag &)*this); const int nrows = rows(); for (int i = 1; i <= nrows; i++) myself.line_inserted(line2key(i), line2data(i)); // effettua la variazione dei saldi myself.update_balances(); } return res; } int TMov_mag::rewrite(TBaseisamfile& f) const { int res; add_extrarows(); if ((res=TMultiple_rectype::rewrite(f))==NOERR ) { TMov_mag &myself=((TMov_mag &)*this); const int nrows = rows(); for (int i = 1; i <= nrows; i++) myself.line_inserted(line2key(i), line2data(i)); // effettua la variazione dei saldi myself.update_balances(); } return res; } const char* TMov_mag::get_next_key() { TLocalisamfile f(LF_MOVMAG); f.last(); long a = f.get_long(MOVMAG_NUMREG)+1; TString& nextcod = get_tmp_string(); nextcod.format("%ld", a); return nextcod; } bool TMov_mag::key_complete() { const bool ok = head().get_long(MOVMAG_NUMREG) > 0L; return ok; } //******* // gestione delle variazione dei saldi // // int TMov_mag::force_update_bal() { // reset delle strutture per il controlli delle variazioni dei saldi mark_current_lines(FALSE); return update_balances(); } // restituisce il valore dei dati TLine_movmag& TMov_mag::line2data(int nrig) const { static TLine_movmag line; const TRectype& r = body().row(nrig); const TString& c = r.get(RMOVMAG_CODCAUS).blank() ? get(MOVMAG_CODCAUS) : r.get(RMOVMAG_CODCAUS); const TString& u = r.get(RMOVMAG_UM); const real q = r.get_real(RMOVMAG_QUANT); const real p = r.get_real(RMOVMAG_PREZZO); line.set(c, u, q, p); return line; } TToken_string & TMov_mag::line2key(int numriga) const { const TRectype& r = body().row(numriga); TToken_string& key = get_tmp_string(); key = r.get(RMOVMAG_CODART); key.add(r.get(RMOVMAG_CODMAG)); key.add(r.get(RMOVMAG_LIVGIAC)); key.add(numriga); return key; } TString TMov_mag::key2field(TToken_string &key,const char *fieldname) { if (strcmp(fieldname,RMOVMAG_CODART)==0) return key.get(0); if (strcmp(fieldname,RMOVMAG_CODMAG)==0) return key.get(1); if (strcmp(fieldname,RMOVMAG_LIVGIAC)==0) return key.get(2); CHECKS(FALSE, "Nome di campo non appartenente al file righe mov ", fieldname); return EMPTY_STRING; } int TMov_mag::line_inserted(TToken_string &k, TLine_movmag &r) { if (_annoes != get(MOVMAG_ANNOES) || _datacomp != get_date(MOVMAG_DATACOMP)) lines_to_add.add(k,r); else { if (lines_to_subtract.is_key(k)&& (TLine_movmag &)lines_to_subtract[k]==r) // modifica annullata lines_to_subtract.remove(k); else // linea modificata lines_to_add.add(k,r); } return 0; } int TMov_mag::line_deleted(TToken_string &k, TLine_movmag &r) { if (_annoes != get(MOVMAG_ANNOES) || _datacomp != get_date(MOVMAG_DATACOMP)) lines_to_subtract.add(k,r); else { if (lines_to_add.is_key(k)&& r==(TLine_movmag &)lines_to_add[k] ) // modifica annullata lines_to_add.remove(k); else // linea modificata lines_to_subtract.add(k,r); } return 0; } void TMov_mag::mark_current_lines(const bool as_deleted) { _annoes = get(MOVMAG_ANNOES); _datacomp = get_date(MOVMAG_DATACOMP); const TRecord_array& b = body(); lines_to_add.destroy(); lines_to_subtract.destroy(); for (int i = b.last_row(); i > 0; i = b.pred_row(i)) { TLine_movmag& data = line2data(i); TToken_string& key = line2key(i); if (as_deleted) line_deleted(key, data); else line_inserted(key, data); } } bool TMov_mag::unlock_anamag(const char *codart) { TLocalisamfile anamag(LF_ANAMAG); anamag.put(ANAMAG_CODART,codart); return (anamag.read(_isequal,_unlock)==NOERR); } bool TMov_mag::lock_anamag(const char *codart) { TLocalisamfile anamag(LF_ANAMAG); anamag.put(ANAMAG_CODART,codart); KEY key = K_ENTER; while (key != K_ESC) { if (anamag.read(_isequal,_testandlock)==NOERR) return TRUE; TString mess; mess << TR("Il record di anagrafica dell'articolo '")<< codart << TR("' risulta essere già in uso."); TTimed_breakbox bbox(mess,10); key = bbox.run(); } return FALSE; } void TMov_mag::giac_putkey(TLocalisamfile & mag,const TString& annoes,TToken_string curr_key) { mag.zero(' '); mag.put(MAG_ANNOES,annoes); mag.put(MAG_CODMAG,key2field(curr_key,RMOVMAG_CODMAG)); mag.put(MAG_CODART,key2field(curr_key,RMOVMAG_CODART)); mag.put(MAG_LIVELLO,key2field(curr_key,RMOVMAG_LIVGIAC)); } // aggiorna tutti i saldi in base alle modifiche fatte. // il lock su anagrafica dovrebbe garantire il lock su tutte le // giacenze dell'articolo int TMov_mag::update_balances() { bool updated_bal=TRUE; TLocalisamfile mag(LF_MAG); mag.setkey(2); TString_array keys_to_add,keys_to_remove; lines_to_add.get_keys(keys_to_add); lines_to_subtract.get_keys(keys_to_remove); // aggiunge i saldi nuovi keys_to_add.sort(); TToken_string* curr_key = (TToken_string*)keys_to_add.first_item(); int nriga=1; while (curr_key) { const TCodice_articolo cod = key2field(*curr_key, RMOVMAG_CODART); if (curr_art.lock_and_prompt(cod)) { // lock gained TLine_movmag & line_mov=(TLine_movmag &)lines_to_add[*curr_key]; const TCausale_magazzino& causmag = causale(line_mov.codcaus()); if (causmag.update_ultcos()) { const real prezzo = curr_art.convert_to_um(line_mov.prezzo(), line_mov.um(), NULL, false); curr_art.update_ultcosti(prezzo,get_date("DATACOMP"), get_long("NUMREG"),nriga++); curr_art.rewrite(); } giac_putkey(mag, get(MOVMAG_ANNOES), *curr_key); if (mag.read()!=NOERR) { // non trovato: aggiungo giac_putkey(mag, get(MOVMAG_ANNOES), *curr_key); mag.put(MAG_NRIGA,1+curr_art.mag(get(MOVMAG_ANNOES)).rows()); mag.write(); } // modifica questo record (e lo sblocca) update_balances(mag.curr(), line_mov, +1); /*// ottimizzazione :(cerca di sfruttare la lettura fatta per un eventuale saldo vecchio) // ciò causa la modifica dell'oggetto TMov_mag (il metodo non è più const) if (_annoes == get("ANNOES") && lines_to_subtract.is_key(*curr_key)) { update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*curr_key],-1); ((TMov_mag *)this)->lines_to_add.remove(*curr_key); ((TMov_mag *)this)->lines_to_subtract.remove(*curr_key); }*/ mag.rewrite(); // conclude la TRANSAZIONE prima di sbloccare il record dell'articolo TToken_string *rem_key=(TToken_string *)keys_to_remove.first_item(); while ( rem_key) { if (key2field(*rem_key,RMOVMAG_CODART)==key2field(*curr_key,RMOVMAG_CODART)) { giac_putkey(mag,_annoes,*rem_key); if (mag.read()==NOERR) { update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*rem_key],-1); mag.rewrite(); } keys_to_remove.remove_item(); } rem_key=(TToken_string *)keys_to_remove.succ_item(); } curr_art.unlock(); } curr_key=(TToken_string *)keys_to_add.succ_item(); } // togli i saldi vecchi curr_key=(TToken_string *)keys_to_remove.first_item(); while (curr_key) { if (curr_art.lock_and_prompt((const char *)key2field(*curr_key,RMOVMAG_CODART))) { giac_putkey(mag,_annoes,*curr_key); // modifica questo record (e lo sblocca) if (mag.read()==NOERR) { update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*curr_key],-1); mag.rewrite(); } curr_art.unlock(); } curr_key=(TToken_string *)keys_to_remove.succ_item(); } mark_current_lines(); return updated_bal; } // aggiorna i saldi del record corrente // in base alla causale e alla modifica fatta (con segno + o -) int TMov_mag::update_balances(TRectype & magrec, const TLine_movmag &l,int rett_sign) { TLocalisamfile umart(LF_UMART); umart.setkey(2); umart.put(UMART_CODART,magrec.get(MAG_CODART)); umart.put(UMART_UM , l.um()); const int err = umart.read(); const real fc = (err == NOERR && umart.get_int(UMART_NRIGA) > 1) ? umart.get_real(UMART_FC) : UNO; const real qt = l.quant(); real diff = real(rett_sign) * qt * fc; if (err == NOERR && fc != UNO) { umart.setkey(1); umart.put(UMART_CODART,magrec.get(MAG_CODART)); umart.put(UMART_NRIGA, 1); if (umart.read() == NOERR) TArticolo::round_um(diff, umart.get(UMART_UM)); } real diff_val = real(rett_sign) * qt * l.prezzo(); // Se è una causale che movimenta il valore ma la qta è 0 // anche diff_val avrà lo stesso valore, impostando 0 di conseguenza // anche nei campi relativi a VALACQ, VALRIM etc etc. // Quindi al limite come controllo finale su movimenti che movimentano la qta // nel caso il calcolo dia proprio ZERO, impostiamo diff_val all'importo del valore stesso const TCausale_magazzino& caus = causale(l.codcaus()); if (qt.is_zero() && caus.update_val()) diff_val = real(rett_sign) * l.prezzo(); if (caus.update_qta()) { update_balance(magrec,"GIAC",diff* (real)caus.sgn(s_giac)); // update .. update_balance(magrec,"ACQ",diff* (real)caus.sgn(s_acq)); // update .. update_balance(magrec,"ENT",diff* (real)caus.sgn(s_ent)); update_balance(magrec,"VEN",diff* (real)caus.sgn(s_ven)); update_balance(magrec,"USC",diff* (real)caus.sgn(s_usc)); update_balance(magrec,"ORDC",diff* (real)caus.sgn(s_ordc)); update_balance(magrec,"ORDF",diff* (real)caus.sgn(s_ordf)); update_balance(magrec,"RIM",diff* (real)caus.sgn(s_rim)); update_balance(magrec,"SCARTI",diff* (real)caus.sgn(s_scart)); update_balance(magrec,"INCL",diff* (real)caus.sgn(s_incl)); update_balance(magrec,"ACL",diff* (real)caus.sgn(s_acl)); update_balance(magrec,"PRODCOMP",diff* (real)caus.sgn(s_prodc)); update_balance(magrec,"PRODFIN",diff* (real)caus.sgn(s_prodf)); update_balance(magrec,"NLABEL",diff* (real)caus.sgn(s_label)); update_balance(magrec,"USER1",diff* (real)caus.sgn(s_user1)); update_balance(magrec,"USER2",diff* (real)caus.sgn(s_user2)); update_balance(magrec,"USER3",diff* (real)caus.sgn(s_user3)); update_balance(magrec,"USER4",diff* (real)caus.sgn(s_user4)); update_balance(magrec,"USER5",diff* (real)caus.sgn(s_user5)); update_balance(magrec,"USER6",diff* (real)caus.sgn(s_user6)); } if (caus.update_val()) { update_balance(magrec,"VALACQ",diff_val* (real)caus.sgn(s_acq)); // update .. update_balance(magrec,"VALENT",diff_val* (real)caus.sgn(s_ent)); update_balance(magrec,"VALVEN",diff_val* (real)caus.sgn(s_ven)); update_balance(magrec,"VALUSC",diff_val* (real)caus.sgn(s_usc)); update_balance(magrec,"VALORDC",diff_val* (real)caus.sgn(s_ordc)); update_balance(magrec,"VALORDF",diff_val* (real)caus.sgn(s_ordf)); update_balance(magrec,"VALRIM",diff_val* (real)caus.sgn(s_rim)); update_balance(magrec,"VALSCARTI",diff_val* (real)caus.sgn(s_scart)); update_balance(magrec,"USERVAL1",diff* (real)caus.sgn(s_user1)); update_balance(magrec,"USERVAL2",diff* (real)caus.sgn(s_user2)); update_balance(magrec,"USERVAL3",diff* (real)caus.sgn(s_user3)); update_balance(magrec,"USERVAL4",diff* (real)caus.sgn(s_user4)); update_balance(magrec,"USERVAL5",diff* (real)caus.sgn(s_user5)); update_balance(magrec,"USERVAL6",diff* (real)caus.sgn(s_user6)); } return 0; } int TMov_mag::update_balances(TRectype& magrec, int numrig, int rett_sign) { const TLine_movmag& lmm = line2data(numrig); return update_balances(magrec, lmm, rett_sign); } HIDDEN TEsercizi_contabili _esercizi; int TMov_mag::codice_esercizio(const TDate &d) { return _esercizi.date2esc(d); } void TMov_mag::update_balance(TRectype & magrec, const char * fieldname, real diff) const { magrec.put(fieldname,magrec.get_real(fieldname)+diff); } void zero_balances(TRectype & mag) { mag.put(MAG_GIAC,0); mag.put(MAG_RIM,0);mag.put(MAG_VALRIM,0); mag.put(MAG_ACQ,0);mag.put(MAG_VALACQ,0); mag.put(MAG_ENT,0);mag.put(MAG_VALENT,0); mag.put(MAG_VEN,0);mag.put(MAG_VALVEN,0); mag.put(MAG_USC,0);mag.put(MAG_VALUSC,0); mag.put(MAG_ORDF,0);mag.put(MAG_VALORDF,0); mag.put(MAG_ORDC,0);mag.put(MAG_VALORDC,0); mag.put(MAG_SCARTI,0);mag.put(MAG_VALSCARTI,0); mag.put(MAG_PRODCOMP,0); mag.put(MAG_PRODFIN,0); mag.put(MAG_INCL,0); mag.put(MAG_ACL,0); mag.put(MAG_NLABEL,0); } void copy_oldbalances(const TRectype& oldmag,TRectype & mag) { mag.put(MAG_GIAC,oldmag.get(MAG_GIAC)); mag.put(MAG_RIM,oldmag.get(MAG_RIM)); mag.put(MAG_VALRIM,oldmag.get(MAG_VALRIM)); mag.put(MAG_ACQ,0); mag.put(MAG_VALACQ,0); mag.put(MAG_ENT,0); mag.put(MAG_VALENT,0); mag.put(MAG_VEN,0); mag.put(MAG_VALVEN,0); mag.put(MAG_USC,0); mag.put(MAG_VALUSC,0); mag.put(MAG_ORDF,oldmag.get(MAG_ORDF)); mag.put(MAG_VALORDF,oldmag.get(MAG_VALORDF)); mag.put(MAG_ORDC,oldmag.get(MAG_ORDC)); mag.put(MAG_VALORDC,oldmag.get(MAG_VALORDC)); mag.put(MAG_SCARTI,0); mag.put(MAG_VALSCARTI,0); mag.put(MAG_PRODCOMP,oldmag.get(MAG_PRODCOMP)); mag.put(MAG_PRODFIN,oldmag.get(MAG_PRODFIN)); mag.put(MAG_INCL,oldmag.get(MAG_INCL)); mag.put(MAG_ACL,oldmag.get(MAG_ACL)); mag.put(MAG_NLABEL,0); } //********************** bool rebuild_balances(const TString& annoes, const TTipo_valorizz tipo_valorizz, const char* catven, const char* codlis) { bool ok=TRUE; // Aggiorna il cazzillo per caricare eventuali date di chiusura e altre amenita' simili TEsercizi_contabili esercizi; esercizi.update(); // Non fidiamoci troppo const int cod_pred_es = esercizi.pred(atoi(annoes)); TString4 pred_es; pred_es.format("%d",cod_pred_es); const bool reset_giac = cod_pred_es != 0 ? esercizi.esercizio(cod_pred_es).chiusura_mag().ok() : TRUE; TString information; // azzera tutte giacenze (ciclo sulle giacenze) TRelation rel2(LF_ANAMAG); // relazione con un solo file (LF_ANAMAG) ma col record Head_Body TCursor cur2(&rel2); const long maxart=cur2.objects(); if (maxart > 0) { TArticolo_giacenza * a_g= new TArticolo_giacenza; // record dell'articolo di magazzino rel2.lfile().set_curr(a_g); TArticolo_giacenza& articolo=*a_g; information.format(FR("Ricostruzione saldi esercizio %s: azzeramento..."),(const char *)annoes); TProgind barra_art(maxart,information, false, true); cur2.freeze(); for (long a=0; aANNOES==" << annoes; TCursor cur(&rel,filterexpr); // cursore filtrato const long maxmov=cur.objects(); if (maxmov > 0) { TMov_mag * m_m= new TMov_mag; // record del movimento di magazzino rel.lfile().set_curr(m_m); TMov_mag & mov_rec=*m_m; information.format(FR("Ricostruzione saldi esercizio %s: ricalcolo ..."),(const char *)annoes); TProgind barra_mov(maxmov,information, false, true); cur.freeze(); for (long m=0; m