Il parametro  assume il valore TRUE se si tratta di un
+//        nuovo oggetto.
+THash_key* TIndexed_array::_lookup(
+  const char* k,  // @parm Chiave da cercare
+  bool& isnew,    // @parm Viene assegnato TRUE se si tratta di una nuova chiave
+  bool insert)    // @parm Permette di inserire la chiave
+
+  // @comm Ricerca all'interno della tabella hash l'oggetto con la chiave 
,
+  //       nel caso non venga trovato 
 ritorna TRUE (si tratta di un
+  //       oggetto nuovo) e viene inserito nella tabella se il parametro 
+  //       e' settato a TRUE.
+{
+  const TFixed_string key(k);
+  const word hv = key.hash() % HASH_SIZE;
+  TArray& arr = bucket(hv);
+  THash_key* o = nullptr;
+  isnew = false;
+  int i;
+
+  for (i = 0; i < arr.items(); i++)
+  {
+    THash_key* ob = (THash_key*)arr.objptr(i);
+    if (ob->_key == key)
+    {
+      o = ob; break;
+    }
+    if (ob->_key > key)
+      break;
+  }
+
+  if (o == nullptr)
+  {
+    if (insert)
+    {
+      o = new THash_key(key);
+      arr.insert(o, i);
+    }
+    isnew = true;
+  }
+
+  return o;
+}
+
+bool TIndexed_array::add2index(const char* key, int index, bool force)
+{
+  bool isnew = false;
+  THash_key * key_object = _lookup(key, isnew, true);
+
+  isnew &= key_object != nullptr;
+  if (isnew)
+    key_object->_index = index;
+  return key != nullptr && isnew;
+}
+
+// @mfunc Copia tutto l'array e ne duplica gli elementi
+//
+TIndexed_array & TIndexed_array::copy(const TIndexed_array & a) // @parm Array associativo sorgente
+{
+  TIndexed_array& from = (TIndexed_array&)a;
+
+  TArray::destroy();
+  TArray::copy(from);
+  FOR_EACH_ARRAY_ITEM(from, r, o)
+  {
+    THash_object & obj = *((THash_object *)o);
+
+    add2index(obj.key(), r, true);
+  }
+  restart();
+  return *this;
+}
+
+const char* TIndexed_array::class_name() const
+{
+  return "Indexed array";
+}
+
+
+word TIndexed_array::class_id() const
+{
+  return CLASS_INDEXED_ARRAY;
+}
+
+bool TIndexed_array::is_kind_of(word id) const
+{
+  return class_id() == CLASS_INDEXED_ARRAY || TArray::is_kind_of(id);
+}
+
+#ifdef DBG
+TObject& TIndexed_array::operator[] (int index) const
+{
+  THash_object * o = (THash_object *)TArray::objptr(index);
+
+  if (o == nullptr)
+    fatal_box("Can't access NULL array item %d of %d", index, size());
+  return o->obj();
+}
+#endif
+
+void TIndexed_array::destroy()
+{
+  TArray::destroy();
+  _bucket.destroy();
+  _row = _col = 0;
+  _rowitem = _colitem = 0;
+}
+
+// @doc EXTERNAL
+
+// @mfunc Aggiunge un oggetto all'array.
+// @rdesc Ritorna TRUE se esisteva gia' un elemento con la stessa chiave
+bool TIndexed_array::add(
+  const char* key,  // @parm Chiave d'ordinamento
+  TObject* obj,     // @parm Oggetto da inserire (default=nullptr)
+  bool force)       // @parm Permette di forzare l'inserimento se esiste gia'
+  //       un oggetto con la stessa chiave
+
+  // @parm const TObject | &obj | Indirizzo dell'oggetto da aggiungere
+  //
+  // @syntax add(const char* key, TObject* obj, bool force)
+  // @syntax add(const char* key, const TObject& obj, bool force)
+  //
+  // @comm Se l'oggetto da aggiungere esite gia' la chiave guarda il parametro 
:
+  //       se  = TRUE  lo sostituisce e ritorna TRUE,
+  //       se  = FALSE non sostituisce e ritorna TRUE,
+  //       altrimenti ritorna FALSE.
+  //       Nel caso l'oggetto da aggiungere venga passato per indirizzo
+  //       la funzione aggiunge una copia dell'oggetto e quindi deve essere
+  //       definita 
+{
+  bool isnew = false;
+  THash_key* o = _lookup(key, isnew, true);
+
+  isnew |= force;
+  if (isnew)
+  {
+    const int index = TArray::add(o); // ??
+
+    o->_index = index;
+  }
+  return isnew;
+}
+
+bool TIndexed_array::add(const char* key, const TObject& obj, bool force)
+{
+  bool isnew = false;
+  THash_key * o = _lookup(key, isnew, true);
+
+  isnew |= force;
+  if (isnew)
+  {
+    const int index = TArray::add(obj.dup());
+
+    o->_index = index;
+  }
+  return isnew;
+}
+
+// @doc EXTERNAL
+
+// @mfunc Elimina un oggetto.
+// @rdesc Ritorna il risultato dell'operazione
+//
+// @flag TRUE | Eliminazione avvenuta
+// @flag FALSE | L'oggetto non e' stato trovato
+bool TIndexed_array::remove(
+  const char* k) // @parm Chiave dell'oggetto da eliminare
+
+// @comm Cerca nella tabella hash l'oggetto con chiave  e lo elimina.
+
+{
+  const TFixed_string key(k);
+  const word hv = key.hash() % HASH_SIZE;
+  TArray& arr = bucket(hv);
+  THash_object* o = nullptr;
+  int i;
+
+  for (i = 0; i < arr.items(); i++)
+  {
+    THash_object* ob = (THash_object*)&arr[i];
+    if (ob->key() == key)
+    {
+      o = ob; break;
+    }
+    if (ob->key() > key)
+      break;
+  }
+  if (o != nullptr)
+  {
+    arr.destroy(i, true);
+    return true;
+  }
+  return true;
+}
+
+// @doc EXTERNAL
+
+// @mfunc Trova l'oggetto indicizzato
+//
+// @rdesc Ritorna l'oggetto cercato. Se l'oggetto non viene trovato 
+//        ritorna un errore
+TObject& TIndexed_array::find(
+  const char* key) const // @parm Chiave dell'oggetto da trovare
+
+
+  // @comm Cerca l'oggetto indicizzato con chiave 
. Viene controllato se
+  //       non c'e' (normalmente si usa operator[key])
+{
+  TObject* o = objptr(key);
+
+  CHECKS(o, "Can't find hash object with key ", key);
+  return *o;
+}
+
+// @doc EXTERNAL
+
+// @mfunc Ritorna l'oggetto con chiave 
+// @rdesc Se l'oggetto esiste ne ritorna il puntatore, altrimenti ritorna nullptr
+TObject* TIndexed_array::objptr(
+  const char* key) const // @parm Chiave dell'oggetto da ritornare
+{
+  bool isnew = false;
+  THash_key * k = ((TIndexed_array*)this)->_lookup(key, isnew);
+
+  if (k != nullptr)
+  {
+    THash_object * o = (THash_object *)TArray::objptr(k->index());
+
+    return o ? o->_obj : nullptr;
+  }
+
+  return nullptr;
+}
+
+// @doc EXTERNAL
+
+// @mfunc Controlla l'esistenza di una chiave
+//
+// @rdesc Ritorna il risultato della ricerca
+//
+// @flag TRUE | Se la chiave esiste
+// @flag FALSE | Se la chiave non esiste
+bool TIndexed_array::is_key(
+  const char* key) const // @parm Chiave di cui cercare l'esistenza
+{
+  bool isnew = false;
+  THash_key* o = ((TIndexed_array *)this)->_lookup(key, isnew);
+
+  return o != nullptr;
+}
+
+// @doc EXTERNAL
+
+// @mfunc Ritorna solo l'oggetto
+//
+// @rdesc Ritorna il puntatore all'oggetto (se diverso da nullptr), altrimenti
+//        ritorna error object
+TObject* TIndexed_array::get()
+// @xref 
+{
+  const TArray* arr = (const TArray*)_bucket.objptr(_row);
+  while (_row < HASH_SIZE)
+  {
+    if (arr && (int)_col < arr->items())
+      break;
+    _row = _bucket.succ(_row);
+    arr = (const TArray*)_bucket.objptr(_row);
+    _col = 0;
+  }
+  if (_row >= HASH_SIZE)
+  {
+    _row = 0;
+    return nullptr;
+  }
+  THash_object* o = (THash_object*)arr->objptr(_col++);
+  return (o == nullptr || o->_obj == nullptr) ? &error_object : o->_obj;
+}
+
+// @doc EXTERNAL
+
+// @mfunc Ritorna l'oggetto e la relativa chiave
+//
+// @rdesc Se l'oggetto esiste ne ritorna il puntatore, altrimenti ritorna nullptr
+THash_key* TIndexed_array::get_hashkey()
+
+// @comm Se l'oggetto viene trovato viene richiamata la funzione
+//       
+//
+// @xref 
+{
+  const TArray* arr = (const TArray*)_bucket.objptr(_row);
+
+  while (_row < HASH_SIZE)
+  {
+    if (arr && (int)_col < arr->items())
+      break;
+    _row = _bucket.succ(_row);
+    arr = (const TArray*)_bucket.objptr(_row);
+    _col = 0;
+  }
+  if (_row >= HASH_SIZE)
+  {
+    _row = 0;
+    return nullptr;
+  }
+  return (THash_key*)arr->objptr(_col++);
+}
+
+const TString& TIndexed_array::get_str(const char* key) const
+{
+  bool isnew = false;
+  THash_key* k = ((TIndexed_array *)this)->_lookup(key, isnew);
+
+  if (k != nullptr)
+  {
+    THash_object * o = (THash_object *) TArray::objptr(k->index());
+
+    if (o != nullptr && o->obj().is_kind_of(CLASS_STRING))
+      return (const TString&)o->obj();
+  }
+  return EMPTY_STRING;
+}
+
+bool TIndexed_array::get_bool(const char* key) const
+{
+  const TString& str = get_str(key);
+  return str.full() && strchr("1XY", str[0]) != nullptr;
+}
+
+int TIndexed_array::get_int(const char* key) const
+{
+  const TString& str = get_str(key);
+  return str.full() ? atoi(str) : 0;
+}
+
+// @doc INTERNAL
 
 ///////////////////////////////////////////////////////////
 // TCache
diff --git a/src/include/assoc.h b/src/include/assoc.h
index 052bbdbb9..a67c2efd5 100755
--- a/src/include/assoc.h
+++ b/src/include/assoc.h
@@ -20,7 +20,9 @@ class THash_object : public TObject
 {
   // @cfriend TAssoc_array
   friend class TAssoc_array;  
-  
+  // @cfriend TIndexed_array
+  friend class TIndexed_array;
+
   // @access:(INTERNAL) Private Member
 
   // @cmember:(INTERNAL) Chiave d'ordinamento
@@ -165,6 +167,162 @@ public:
   { destroy(); }  
 };
 
+class THash_key : public TObject
+  // @author:(INTERNAL) Villa
+{
+  // @cfriend TAssoc_array
+  friend class TIndexed_array;
+
+  // @access:(INTERNAL) Private Member
+
+  // @cmember:(INTERNAL) Chiave d'ordinamento
+  TString  _key;
+  // @cmember:(INTERNAL) indice 
+  int      _index;
+
+  // @access Public Member
+public:
+  // @cmember Ritorna la chiave di ordinamento
+  const TString& key() const { return _key; }
+  // @cmember Ritorna l'oggetto
+  int index() const { return _index; }
+
+  // @cmember Costruttore (inizializza la chiave ed opzionalmente l'oggetto)
+  THash_key(const char* k, int index = -1) : _key(k), _index(index) {}
+  // @cmember Distruttore
+  virtual ~THash_key() {}
+};
+
+// @doc EXTERNAL
+
+// @class TIndexed_array | Array con indice hash
+//
+// @base public |TObject
+
+class TIndexed_array : public TArray
+
+  // @author:(INTERNAL) Villa
+
+  //@access:(INTERNAL) Private Member
+{
+  // @cmember:(INTERNAL) Numero di righe della tabella hash
+  word _row;
+  // @cmember:(INTERNAL) Numero di colonne della tabella hash
+  word _col;
+  // @cmember:(INTERNAL) Numero di righe della tabella hash per i metodi _item
+  int _rowitem;
+  // @cmember:(INTERNAL) Numero di colonne della tabella hash per i metodi _item
+  int _colitem;
+  // @cmember:(INTERNAL) Array contenente i dati veri e propri
+  TArray _bucket;
+
+  // @access Protected member
+protected:
+  TArray& bucket(int index);  // ok
+    // @cmember Azzera il numero di riga e colonna corrente della tabella hash
+  void restart() { _row = 0; _col = 0; } //ok
+
+  // @cmember Cerca l'oggetto con chiave k
+  THash_key * _lookup(const char* k, bool& isnew, bool insert = false); //ok
+  // @cmember aggiunge la chiave all'indice
+  bool add2index(const char* key, int index = -1, bool force = false); //ok
+  // @cmember Copia tutto l'array associativo e ne duplica gli elementi
+  TIndexed_array & copy(const TIndexed_array & a); //ok
+
+
+
+  // @access Public Member
+public:
+  // @cmember Duplica l'array associativo copiandone gli elementi.
+  virtual TObject* dup() const { return new TIndexed_array(*this); } // ok
+
+  // @cmember Ritorna il nome della classe
+  virtual const char* class_name() const;  // ok
+  // @cmember Ritorna l'id  della class
+  virtual word class_id() const;  // ok
+  // @cmember Controlla se si tratta di un oggetto derivato da TArray
+  virtual bool is_kind_of(word cid) const; //ok
+ 
+  // @cmember Ritorna l'oggetto nella posizione index
+  TObject& operator[] (int index) const; // ok
+  // @cmember Ritorna l'oggetto nella posizione index
+  virtual TObject* objptr(int index) const; // ok
+
+  //qui
+  // @cmember Rimuove uno o tutti (default) gli elementi
+  virtual bool destroy(int index = -1, bool pack = false);
+  // @cmember Aggiunge un oggetto ad un array.
+  virtual int add(TObject* obj, int index = -1) { CHECK(false, "Must specifiy a key"); }
+  // @cmember Inserisce un elemento dell'array nella posizione index
+  virtual int insert(TObject* obj, int index = 0, bool force = false) { CHECK(false, "Must specifiy a key"); }
+
+  // @cmember Aggiunge un oggetto all'array. L'oggetto viene duplicato
+  virtual int add(const TObject& object, int index = -1) { CHECK(false, "Must specifiy a key"); }
+  // @cmember Inserisce un oggetto alla posizione index
+  virtual int insert(const TObject& object, int index = 0, bool force = false) { CHECK(false, "Must specifiy a key"); }
+  // @cmember Elimina l'elemento nella posizione index dell'array
+  TObject* remove(int index, bool pack = false);
+  // @cmember Elimina l'elemento nella posizione index dell'array
+  TObject* remove_item(bool pack = false);
+  // @cmember Scambia di posto due elementi dell'array
+  void swap(int i1, int i2);
+  // @cmember Rende contigui tutti gli elementi non nulli
+  virtual void pack();
+  // @cmember Cancella tutti gli elementi
+  virtual void destroy();
+
+  // @cmember Aggiunge un oggetto. Se era gia' presente guarda il parametro force
+  bool add(const char* key, TObject* obj = nullptr, bool force = false); //ok
+
+  // @cmember Aggiunge una copia dell'oggetto
+  bool add(const char* key, const TObject& obj, bool force = false); //ok
+
+  // @cmember Elimina un oggetto
+  bool remove(const char* key);
+
+  // @cmember Controlla l'esistenza di una chiave
+  bool is_key(const char* key) const;
+
+  // @cmember Ritorna l'oggetto con chiave key
+  TObject* objptr(const char* key) const;
+
+  // @cmember Trova l'oggetto indicizzato
+  TObject& find(const char* key) const;
+
+  // @cmember Ritorna l'indice del oggetto con chiave key (piu' intuitivo di )
+  TObject& operator[] (const char* key) const { return find(key); }
+
+  // @cmember Ritorna solo l'oggetto
+  TObject* get();
+  // @cmember Ritorna l'oggetto e la relativa chiave
+  THash_key* get_hashkey(); // ok
+
+  bool get_bool(const char* key) const;
+  int get_int(const char* key) const;
+  const TString& get_str(const char* key) const;
+
+  // @cmember Operatore di assegnamento tra array indicizzati
+  TIndexed_array& operator= (const TIndexed_array & a) { return copy(a); }
+
+  // @cmember Costruttori
+  TIndexed_array(int arraysize) : TArray(arraysize), _row(0), _col(0) {}
+  TIndexed_array() : _row(0), _col(0) {}
+  // @cmember Costruttore. Copia tutto l'array indicizzato e ne duplica gli elementi
+  TIndexed_array(const TIndexed_array& a) :  _row(0), _col(0) { copy(a);}
+  // @cmember Distruttore
+  virtual ~TIndexed_array() {}
+};
+
+inline TObject* TIndexed_array::objptr(int index) const
+{
+  THash_object * o = (THash_object *) TArray::objptr(index);
+
+  return (o) ? &(o->obj()) : nullptr;
+}
+
+#ifndef DBG
+inline TObject& TArray::operator[] (int index) const { return ((THash_obj*)objptr(index))->obj();}
+#endif
 class TCache : public TObject
 {
 	TArray _data;
diff --git a/src/include/filebar.h b/src/include/filebar.h
index 4a118bceb..bac366070 100755
--- a/src/include/filebar.h
+++ b/src/include/filebar.h
@@ -19,10 +19,18 @@ BEGIN
   PICTURE TOOL_DELREC
 END
 
+
 BUTTON DLG_NULL 2 2
 BEGIN
   PROMPT -1 1 ""
   PICTURE 0
 END
 
-#include 
\ No newline at end of file
+#include 
+
+BUTTON DLG_LOG 2 2
+BEGIN
+PROMPT 3 1 "~Log"
+
+PICTURE TOOL_PREVIEW
+END
\ No newline at end of file
diff --git a/src/include/isam.cpp b/src/include/isam.cpp
index 8af59c191..c9ebbc8f7 100755
--- a/src/include/isam.cpp
+++ b/src/include/isam.cpp
@@ -1,6 +1,7 @@
 #define __ISAM_CPP
 #define _CRT_SECURE_NO_WARNINGS 1
 
+#include 
 #include 
 #include 
 #include 
@@ -18,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef WIN32
 #include 
@@ -442,7 +444,7 @@ HIDDEN void browse_null(char *start, int nc)
  
 // Traduce l'espressione chiave di CodeBase
 
-HIDDEN  int __build_key(const RecDes& recd, int numkey, const RecType recin, char *key, bool build_x_cb)
+HIDDEN  int __build_key(const RecDes& recd, int numkey, const RecType recin, char *key, bool build_x_cb, bool token = false)
   /* *recd;       descrittore record               */
   /* numkey;      numero chiave                    */
   /* recin;       buffer contenente il record      */
@@ -509,6 +511,8 @@ HIDDEN  int __build_key(const RecDes& recd, int numkey, const RecType recin, cha
           key[i] = toupper(key[i]);
 
       l += len;
+      if (!build_x_cb  && token &&  i < recd.Ky[numkey].NkFields - 1)
+        key[l++] = '|';
     }
     
     // rtrim            
@@ -883,6 +887,7 @@ int TBaseisamfile::_read(TRectype& rec, word op, word lockop)
       prefix().lock_record(_isam_handle, _recno); else
     if (lockop == _unlock)
       prefix().unlock_record(_isam_handle, _recno);
+		_current->clear_modified_fields();
 	}
 
   return _lasterr;
@@ -917,19 +922,221 @@ int TBaseisamfile::_readat(TRectype& rec, TRecnotype nrec, word lockop)
   if (_lasterr != NOERR) 
     _lasterr = get_error(_lasterr);
   else
+  {
     rec = (const char*)DB_getrecord(fhnd);
+		_current->clear_modified_fields();
+	}
   _recno = DB_recno(fhnd);
   if (rec.has_memo())
     rec.init_memo(_recno, _isam_handle);
   return _lasterr;
 }
 
+bool __db_log = false;
+
+void db_log(const bool on)
+{
+	__db_log = on;
+}
+
+bool db_log() { return is_debug_station() && __db_log; }
+bool to_db_log(int logic) { return db_log() && logic != LF_DBLOG && logic != LF_USER; }
+void db_log_on() { db_log(true); }
+void db_log_off() { db_log(false); }
+
+TLocalisamfile * __dblog = NULL;
+TXmlItem * __root = NULL;
+
+bool TBaseisamfile::writelog(const db_op op, TRectype & rec, TRectype * act_rec, int fhnd)
+{
+  bool changed = false;
+  const struct tm * timeloc = xvt_time_now();
+  time_t timestamp = time(NULL);
+  TString trans("DBtrans");
+  TString80 user = ::user();
+  int year;
+  int release;
+  int tag;
+  int patch;
+  TDate date(timeloc->tm_mday, timeloc->tm_mon + 1, timeloc->tm_year + 1900);
+  TString time;
+  TFilename cmdline(main_app().argv(0));
+	TString80 s;
+
+  if (__dblog == NULL)
+    __dblog = new TLocalisamfile(LF_DBLOG);
+
+  const int len = __dblog->curr().length(DBL_USER);
+	
+	xvt_sys_get_user_name(s.get_buffer(), s.size());
+
+	const int at = s.find('@');
+
+  if (at > 0) 
+		s.cut(at); // Windows 8.1 / 10.0 user profile
+	if (user.len() + s.len() + 1 <= len)
+		user << ':' << s;
+	xvt_sys_get_host_name(s.get_buffer(), s.size());
+	if (user.len() + s.len() + 1 <= len)
+		user << '@' << s;
+	
+	TApplication::get_version_info(year, release, tag, patch);
+
+	__dblog->zero();
+	if (__root == NULL)
+		__root = new TXmlItem;
+	__root->Destroy();
+
+	cmdline = cmdline.name_only();
+	for (int i = 1; i < main_app().argc(); i++)
+		cmdline << ' ' << main_app().argv(i);
+	time.format("%02d:%02d:%02d", timeloc->tm_hour, timeloc->tm_min, timeloc->tm_sec);
+
+	__root->SetTag(trans);
+
+	__dblog->put(DBL_CMDLINE, cmdline);
+	__dblog->put(DBL_ANNO, year);
+	__dblog->put(DBL_RELEASE, release);
+	__dblog->put(DBL_TAG, tag);
+	__dblog->put(DBL_PATCH, patch);
+	__root->SetAttr("cmdline", cmdline);
+	__root->SetAttr("year", year);
+	__root->SetAttr("release", release);
+	__root->SetAttr("tag", tag);
+	__root->SetAttr("patch", patch);
+  
+  TXmlItem & head = __root->AddChild("Head");
+  
+	__dblog->put(DBL_CMD, op);
+	__dblog->put(DBL_FILE, _logicnum);
+	__dblog->put(DBL_RECNO, _recno);
+	__dblog->put(DBL_USER, user);
+	__dblog->put(DBL_SESSION, xvt_sys_get_session_id());
+	__dblog->put(DBL_DATA, date);
+	__dblog->put(DBL_ORA, time);
+	__dblog->put(DBL_TIMESTAMP, (long)timestamp);
+	head.SetAttr("cmd", op);
+  head.SetAttr("file", _logicnum);
+  head.SetAttr("recno", _recno);
+  head.SetAttr("user", user);
+  head.SetAttr("session", xvt_sys_get_session_id());
+	head.SetAttr("data", date.date2ansi());
+	head.SetAttr("ora", time);
+	head.SetAttr("timestamp", (long) timestamp);
+
+  TXmlItem & key = __root->AddChild("key");
+
+  for (byte i = 0; i < rec.rec_des().Ky[0].NkFields; i++)
+  {
+    const char * keyfieldname = rec.rec_des().Fd[rec.rec_des().Ky[0].FieldSeq[i]].Name;
+		const TString & value = rec.get(keyfieldname);
+		TXmlItem & field = key.AddChild("field");
+
+		field.SetAttr(keyfieldname, value);
+  }
+	__dblog->put(DBL_KEY, rec.key_token());
+
+	TXmlItem & data = __root->AddChild("data");
+
+  if (op != db_remove)
+  {
+	  for (byte i = 0; i < rec.rec_des().NFields; i++)
+	  {
+		const TString16 fieldname(rec.rec_des().Fd[i].Name);
+		TString value = rec.get_modified_field(i);
+	
+	    if (op == db_add)
+	    {
+				TXmlItem & field = data.AddChild("field");
+
+				field.SetAttr(fieldname, value);
+				changed = true;
+	    }
+			else
+				if (rec.field_modified(i))
+				{
+					bool fchanged = false;
+				
+					switch (TFieldtypes(rec.rec_des().Fd[i].TypeF))
+					{
+						case _nullfld:     // @emem Campo non definito
+							break;
+						case _alfafld:     // @emem Campo di tipo alfanumerico
+							fchanged = act_rec->get(fieldname) != value.trim();
+							break;
+						case _intfld:      // @emem Campo di tipo intero
+							fchanged = act_rec->get_int(fieldname) != atoi(value);
+							break;
+						case _longfld:   // @emem Campo di tipo intero lungo
+							fchanged = act_rec->get_long(fieldname) != atol(value);
+							break;
+						case _realfld:     // @emem Campo di tipo reale (vedi )
+							fchanged = act_rec->get_real(fieldname) != real(value);
+							break;
+						case _datefld:     // @emem Campo di tipo data (vedi )
+							fchanged = act_rec->get_date(fieldname) != TDate(value);
+							break;
+						case _wordfld:     // @emem Campo di tipo intero senza segno
+							fchanged = act_rec->get_long(fieldname) != atol(value);
+							break;
+						case _charfld:     // @emem Campo di tipo carattere
+							fchanged = act_rec->get_char(fieldname) != value[0];
+							break;
+						case _boolfld:    // @emem Campo di tipo booleano
+							{
+								const bool b = (value.full() && strchr("1STXY", toupper(value[0])) != NULL) ? true : false;
+								const bool b1 = act_rec->get_bool(fieldname);
+								
+								fchanged = b ^ b1;
+						}
+							break;
+						case _intzerofld:  // @emem Campo ditipo intero zero filled
+							fchanged = act_rec->get_int(fieldname) != atoi(value);
+							break;
+						case _longzerofld: // @emem Campo di tipo intero lungo zero filled
+							fchanged = act_rec->get_long(fieldname) != atol(value);
+							break;
+						case _memofld:
+							fchanged = true;
+						default:
+							break;
+					};   // @emem Campo di tipo memo
+					if  (fchanged)
+					{
+					  TXmlItem & field = data.AddChild("field");
+					
+	  				  changed = true;
+					  field.SetAttr(fieldname, value);
+					  if (rec.preserve_values() && act_rec != NULL)
+							act_rec->put(fieldname, value);
+					}
+				}
+	  }
+
+  }
+  else
+	  changed = true;
+  if (changed)
+  {
+		TString trans;
+
+		__root->AsString(trans);
+		__dblog->put(DBL_TRANS, trans);
+//		__dblog->write();
+//		__root->Append(logname);
+	  if (rec.preserve_values() &&(op == db_update) && (act_rec != NULL))
+		  rec.TRectype::operator =(*act_rec);
+  }
+  rec.clear_modified_fields();
+  return changed;
+}
+
 int TBaseisamfile::_write(const TRectype& rec)
 {
   CHECK(!rec.empty(), "Can't write an empty record");
 
   // Controlla che la chiave sia piena
-  TString256 key;
+   TString & key = get_tmp_string(384);
 
   __build_key(rec.rec_des(), 1, rec.string(), key.get_buffer(), true);
   if (key.blank())
@@ -948,13 +1155,23 @@ int TBaseisamfile::_write(const TRectype& rec)
 
   browse_null(rec.string(), dst_len);
   memcpy(DB_getrecord(fhnd), rec.string(), dst_len);
+	bool changed = false;
+
+	if (to_db_log(_logicnum))
+		changed = writelog(db_add, (TRectype&)rec, NULL, fhnd);
   _lasterr = DB_add(fhnd);
   _recno = DB_recno(fhnd);
   
   if (_lasterr == NOERR) 
   { 
+		if (changed && to_db_log(_logicnum))
+		{
+			__dblog->write();
+			__root->Append(logname());
+		}
 		if (rec.has_memo())
       ((TRectype&)rec).write_memo(_isam_handle, _recno );
+		if (_logicnum < 1000)
 			rec_cache(_logicnum).notify_change();
 
   }
@@ -997,27 +1214,40 @@ int TBaseisamfile::rewrite_write()
 int TBaseisamfile::_rewrite(const TRectype& rec)
 {
   CHECK(!rec.empty(), "Can't write an empty record");
+  TAuto_variable_rectype act_rec(rec);
 	bool changed = false;
     
-  TRectype save_rec(rec);
+	// Forza l'uso della chiave principale (per chiavi duplicate?)
 
   const int fhnd = handle(1);
-  _lasterr = cisread(fhnd, 1, save_rec, _isequal + _nolock, _recno); // Si Posiziona per sicurezza...
+  while ((_lasterr = cisread(fhnd, 1, act_rec, _isequal + _testandlock, _recno)) == _islocked) ;// Si Posiziona  e locca per sicurezza...
 
   if (_lasterr == NOERR)
   {
     const int len = DB_reclen(fhnd);
-    if (len != save_rec.len())
+    if (len != act_rec.len())
       NFCHECK("Record size mismatch on file %d: RecDes=%d, DB_reclen=%d", 
-              _logicnum, save_rec.len(), len);
+              _logicnum, act_rec.len(), len);
 
     browse_null(rec.string(), len);
-    if (memcmp(rec.string(), save_rec.string(), len) != 0)
+
+
+		if (to_db_log(_logicnum))
+			changed = writelog(db_update, (TRectype &)rec, &act_rec, fhnd);
+		else
+			changed = memcmp(rec.string(), act_rec.string(), len) != 0;
+    if (changed)
 		{
 	    memcpy(DB_getrecord(fhnd), rec.string(), len);
       _lasterr = DB_rewrite(fhnd);
 			if (_lasterr == NOERR)
-        rec_cache(_logicnum).notify_change();
+			{
+				if (to_db_log(_logicnum))
+				{
+					__dblog->write();
+					__root->Append(logname());
+				}
+			}
 			else
         _lasterr = get_error(_lasterr);
     }
@@ -1034,7 +1264,7 @@ int TBaseisamfile::_rewrite(const TRectype& rec)
 				if (changed)
 					((TRectype&)rec).write_memo(_isam_handle, _recno);
 			}
-			if (changed)
+			if (changed && _logicnum < 1000)
 				rec_cache(_logicnum).notify_change();
 		}
   }    
@@ -1058,10 +1288,30 @@ int TBaseisamfile::rewriteat(const TRectype& rec, TRecnotype nrec)
 
   if ((_lasterr=DB_go(fhnd,nrec))== NOERR)
   {           
+	  TRectype save_rec(rec);
+	  const int len = DB_reclen(fhnd);
+
+    memcpy(DB_getrecord(fhnd), save_rec.string(), len);
     browse_null(rec.string(),DB_reclen(fhnd));
-    memcpy(DB_getrecord(fhnd),rec.string(),DB_reclen(fhnd));
-    _lasterr=DB_rewrite(fhnd);
-    if (_lasterr != NOERR) _lasterr = get_error(_lasterr);
+		if (to_db_log(_logicnum))
+			changed = writelog(db_update, (TRectype &)rec, &save_rec, fhnd);
+		else
+			changed = memcmp(rec.string(), save_rec.string(), len) != 0 ;
+	  if (changed)
+		{
+			memcpy(DB_getrecord(fhnd), rec.string(), DB_reclen(fhnd));
+			_lasterr = DB_rewrite(fhnd);
+			if (_lasterr == NOERR)
+			{
+				if (to_db_log(_logicnum))
+				{
+					__dblog->write();
+					__root->Append(logname());
+				}
+			}
+			else
+				_lasterr = get_error(_lasterr);
+		}
   } 
   else
     _lasterr = get_error(_lasterr);
@@ -1076,7 +1326,7 @@ int TBaseisamfile::rewriteat(const TRectype& rec, TRecnotype nrec)
 			if (changed)
 				((TRectype&)rec).write_memo(_isam_handle, _recno);
 		}
-		if (changed)
+		if (changed && _logicnum < 1000)
 			rec_cache(_logicnum).notify_change();
 	}
   return _lasterr;
@@ -1098,11 +1348,21 @@ int TBaseisamfile::_remove(const TRectype& rec)
 
   if (_lasterr == NOERR)
   {
+		bool changed = false;
+
+		if (to_db_log(_logicnum))
+			writelog(db_remove, (TRectype &) rec, NULL, fhnd);
     _lasterr = DB_delete(fhnd);   // Put only deletion flag on record, must remove keys too!
     if (_lasterr == NOERR)         
     {
+			if (changed && to_db_log(_logicnum))
+			{
+				__dblog->write();
+				__root->Append(logname());
+			}
       if (curr().has_memo( ))
         curr().init_memo();
+			if (_logicnum < 1000)
 	      rec_cache(_logicnum).notify_change();
       DB_flush(fhnd);
     }
@@ -2498,6 +2758,15 @@ int TSystemisamfile::load(
         const int l = fldlen.get_int(j);
         s1 = s.mid(pos, l);
         s1.rtrim();
+				
+				const TFieldtypes t = curr().type((const TString&)fld[j]);
+				
+				if (t == _alfafld || t == _memofld)
+				{
+					TString s2 = s1;
+
+					s1 = esc(s2);
+				}
 				put(fld.row(j), s1);
         pos += l;
       }
@@ -2510,7 +2779,6 @@ int TSystemisamfile::load(
         s1 = s.get();
         if (fd) 
         {
-		      s1.rtrim(1);
 		      s1.ltrim(1);
         }
 				const TFieldtypes t = curr().type((const TString&)fld[j]);
@@ -3281,6 +3549,8 @@ void TRectype::init(int logicnum)
 
   if (_length > 0 && lf_has_memo(logicnum))
     init_memo(RECORD_NON_FISICO);
+ clear_modified_fields();
+ set_preserve_values();
 }
  
 bool TRectype::changed(const char* fieldname, const char* val, const char* compare_to) 
@@ -3321,6 +3591,7 @@ TRectype::TRectype(const TRectype& r)
     init_memo(r._memo_data->recno(), r._memo_data->file());
     *_memo_data = *r._memo_data;
   }               
+  _modified_fields = r._modified_fields;
   memcpy(_rec, r._rec, _length);
   memcpy(_tab, r._tab, sizeof(_tab));
   setempty(r.empty());
@@ -3784,6 +4055,7 @@ void TRectype::put_str(const char* fieldname, const char* val)
   if (ft == _boolfld)                            
     val = (*val && strchr("1STXY", toupper(*val)) != NULL) ? "T" : "F";
 
+  set_modified_field(nf, val);
   if (*val == '\0')
   {
     TRecfield f(*this, fieldname);
@@ -3830,6 +4102,7 @@ void TRectype::zero(const char* fieldname)
       const byte dec = recd.Fd[nf].Dec; 
       const TFieldtypes type = (TFieldtypes) recd.Fd[nf].TypeF;
 
+	  set_modified_field(nf, "");
       switch (type)
       {
       case _datefld:
@@ -3861,6 +4134,24 @@ void TRectype::zero(const char* fieldname)
   }
 }
 
+void TRectype::set_modified_field(int i, const char *val)
+{
+	const RecFieldDes& fd = rec_des().Fd[i];
+
+	TString * v = (TString *)_modified_fields.objptr(i);
+
+	if (v == NULL)
+	{
+		TString old_val = get(fd.Name);
+
+		if (old_val != val)
+			_modified_fields.add(val, i);
+	}
+	else
+		*v = val;
+}
+
+
 void TRectype::zero(char c)
 {
   memset(_rec, c, len());
@@ -3872,6 +4163,7 @@ void TRectype::zero(char c)
   if(has_memo())
     init_memo( RECORD_NON_FISICO );
   setempty(true);
+	clear_modified_fields();
 }
 
 // Certified 99%
@@ -3887,6 +4179,7 @@ TRectype& TRectype::operator =(const TRectype& rec)
   }
   memcpy(_tab, rec._tab, sizeof(_tab));
   setempty(rec.empty());                   // Copy emptiness status
+  _modified_fields = rec._modified_fields;
   return *this;
 }
 
@@ -4076,10 +4369,19 @@ TRectype& TRectype::operator =(const char* rec)
 const char* TRectype::key(int numkey) const
 {
   TString& tmp = get_tmp_string(256);
+
   __build_key(rec_des(), numkey, _rec, tmp.get_buffer(), false);
   return tmp;
 }
 
+const char* TRectype::key_token(int numkey) const
+{
+  TString& tmp = get_tmp_string(256);
+
+  __build_key(rec_des(), numkey, _rec, tmp.get_buffer(), false, true);
+  return tmp;
+}
+
 void TRectype::fill_transaction(TConfig& cfg, int row) const
 {                                   
   TString16 p; p << num();
@@ -4363,13 +4665,24 @@ void TRecfield::put_subfield(const char* s)
 			_rec->put(_name, out);
 		}
 	}
+	else 
+		if ((p < 0) && (s && *s))
+		{
+			TString out = str;
+			
+			out << '\n' << _sub_field << s;
+			_rec->put(_name, out);
+		}
 }
 
 int TRecfield::operator =(int i)
 {
   TString16 buff; buff << i;
   if (_sub_field.empty())
-		__putfieldbuff( _len, _dec, _type, buff, _p);
+  {
+	  _rec->set_modified_field(_nf, buff);
+	  __putfieldbuff(_len, _dec, _type, buff, _p);
+  }
   else
 	put_subfield(buff);
   _rec->setempty(FALSE);
@@ -4381,7 +4694,10 @@ long TRecfield::operator =(long l)
 {
   TString16 buff; buff << l;
 	if (_sub_field.empty())
+	{
+		_rec->set_modified_field(_nf, buff);
 		__putfieldbuff( _len, _dec, _type, buff, _p);
+	}
 	else
 		put_subfield(buff);
   _rec->setempty(false);
@@ -4390,9 +4706,13 @@ long TRecfield::operator =(long l)
 
 const real& TRecfield::operator =(const real& r)
 {
-  const char* buff = r.string();
+	const char * buff = r.string();
+	
 	if (_sub_field.empty())
+	{
+		_rec->set_modified_field(_nf, buff);
 		__putfieldbuff( _len, _dec, _type, buff, _p);
+	}
 	else
 		put_subfield(buff);
   _rec->setempty(FALSE);
@@ -4403,7 +4723,10 @@ const TDate& TRecfield::operator =(const TDate& d)
 { 
   const TString16 buff = d.stringa();
 	if (_sub_field.empty())
+	{
+		_rec->set_modified_field(_nf, buff);
 		__putfieldbuff( _len, _dec, _type, buff, _p);
+	}
 	else
 		put_subfield(buff);
   _rec->setempty(FALSE);
@@ -4417,8 +4740,11 @@ const char* TRecfield::operator =(const char* s)
 		if (_type == _memofld)
 			_rec->put(_name, s);
 	  else
-			__putfieldbuff( _len, _dec, _type, s, _p);
+		{
+			_rec->set_modified_field(_nf, s);
+			__putfieldbuff(_len, _dec, _type, s, _p);
 		}
+	}
 	else
 		put_subfield(s);
   _rec->setempty(FALSE);
diff --git a/src/include/isam.h b/src/include/isam.h
index 08932f11d..4e7d1d87d 100755
--- a/src/include/isam.h
+++ b/src/include/isam.h
@@ -31,6 +31,15 @@
 
 const int MAX_KEYS = 8;
 
+enum db_op {db_add = 1, db_remove, db_update};
+
+extern void db_log(bool on);
+extern bool db_log();
+extern bool to_db_log(int logic);
+extern void db_log_on();
+extern void db_log_off();
+
+
 class TBaseisamfile;
 class TLocalisamfile;
 class TRecfield;
@@ -86,6 +95,9 @@ protected:
   // @cmember:(INTERNAL) Campo "COD" della tabella 
   TMemo_data* _memo_data;
 
+  TString_array _modified_fields;
+	bool _preserve_values;
+
 // @access Protected Member
 protected:  
   // @cmember Segnalazione di un campo inesistente
@@ -104,6 +116,7 @@ protected:
   virtual void put_str(const char* fieldname, const char* val);
 
   bool set_edit_info(const char* ut, const char* dt, const char* or);
+  void set_modified_field(int i, const char * val);
 
 // @access Public Member
 public:
@@ -280,12 +293,19 @@ public:
   {return _rec[0] == ' ';}
   // @cmember Ritorna il valore  della chiave numero 
   const char* key(int numkey = 1) const;
-  // @cmember Ritorna se si tratta di un record valido
+  // @cmember Ritorna il valore  della chiave numero 
 come token string per le cache
+  const char* key_token(int numkey = 1) const;  // @cmember Ritorna se si tratta di un record valido
   virtual bool ok() const
   { return _rec != NULL; }
   // @cmember Ritorna true se sono uguali
   bool is_equal(const TRectype& r) const;
 
+	bool field_modified(int i) const { return _modified_fields.objptr(i) != NULL; }
+	const TString & get_modified_field(int i) const { return field_modified(i) ? _modified_fields.row(i) : EMPTY_STRING; }
+	void clear_modified_fields(int i = -1) { _modified_fields.destroy(i); }
+	bool preserve_values() { return _preserve_values; }
+	void set_preserve_values(bool on = true) { _preserve_values = on; }
+
   virtual void init_memo(const TRecnotype recno  = RECORD_NON_FISICO, TIsam_handle file = 0);
   virtual void reset_memo() { _memo_data->init(RECORD_NON_FISICO, 0); }
 	virtual void update_memo() {}
@@ -410,6 +430,7 @@ protected:
 // @access Protected Member
 protected:
   // @cmember:(INTERNAL) IO su file:
+  virtual bool writelog(const db_op op, TRectype & rec, TRectype * new_rec, int fhnd);
   virtual int _read(TRectype& rec, word op = _isequal, word lockop = _nolock);
   virtual int _readat(TRectype& rec, TRecnotype nrec, word lockop = _nolock);
   virtual int _write(const TRectype& rec);
diff --git a/src/include/mask.cpp b/src/include/mask.cpp
index 07f3b3637..68cce3c97 100755
--- a/src/include/mask.cpp
+++ b/src/include/mask.cpp
@@ -1194,6 +1194,7 @@ int TMask::win2page(WINDOW w) const
 TMask_field* TMask::parse_field(TScanner& scanner)
 {
   const TString& k = scanner.key();
+
   if (k == "BO") return new TBoolean_field(this);
   if (k == "BR") return new TBrowsefile_field(this);
   if (k == "BU") return new TButton_field(this);
diff --git a/src/include/mov.h b/src/include/mov.h
index 266340987..4f18392b6 100755
--- a/src/include/mov.h
+++ b/src/include/mov.h
@@ -61,7 +61,6 @@
 #define MOV_KEYFPPRO	 "KEYFPPRO"
 #define MOV_MOVCOLL		 "MOVCOLL"
 #define MOV_ELABF9		 "ELABF9"
-
 #define MOV_IDDOCSDI	"IDDOCSDI"
 #define MOV_DATADOCSDI "DATADOCSDI"  
 
diff --git a/src/include/msksheet.cpp b/src/include/msksheet.cpp
index f67b88e69..e05badcd2 100755
--- a/src/include/msksheet.cpp
+++ b/src/include/msksheet.cpp
@@ -3882,7 +3882,7 @@ void TSheet_field::save_columns_order()
   s.save_columns_order();
 }
 
-void TSheet_field::check_row(int n, int mode)
+void TSheet_field::check_row(int n, int mode, bool final)
 {
   TSpreadsheet* s = (TSpreadsheet*)_ctl;
   const int current = s->_cur_rec;
@@ -3903,7 +3903,9 @@ void TSheet_field::check_row(int n, int mode)
     if (f.has_check())
       f.set_dirty();
   }
-  row2mask(n, r, mode); 
+	row2mask(n, r, mode);
+	if (final) 
+		m.check_fields();
   mask2row(n, r);             
   m.set_mode(mask_mode);  
   s->_cur_rec = current;
diff --git a/src/include/msksheet.h b/src/include/msksheet.h
index bf86bcf09..4b50d7299 100755
--- a/src/include/msksheet.h
+++ b/src/include/msksheet.h
@@ -171,6 +171,8 @@ public:
 	virtual void set_row_cell(TToken_string & row, short id, const bool value) { row.add(value ? "X" : "", cid2index(id)); }
 	virtual int set_row_cell_currency(TToken_string& row, short id, const real& n);
 
+	virtual void clear_row_cell(TToken_string & row, short id) { set_row_cell(row, id, ""); }
+
 	virtual int set_row_cell(short id, const char * value, int nrow = -1);
 	virtual int set_row_cell(short id, char value, int nrow = -1);
 	virtual int set_row_cell(short id, long value, int nrow = -1);
@@ -180,6 +182,8 @@ public:
 	virtual int set_row_cell(short id, const bool value, int nrow = -1);
 	virtual int set_row_cell_currency(short id, const real& n, int nrow = -1);
 
+	virtual int clear_row_cell(short id, int nrow = -1) { return set_row_cell(id, "", nrow); }
+
 	virtual const char * get_str_row_cell(TToken_string & row, short id) { return row.get(cid2index(id)); }
 	virtual char get_char_row_cell(TToken_string & row, short id) { return row.get_char(cid2index(id)); }
 	virtual long get_long_row_cell(TToken_string & row, short id) { return row.get_long(cid2index(id)); }
@@ -328,7 +332,7 @@ public:
   virtual void post_insert(int) { }
 
   // @cmember Esegue tutti i check iniziali sulla riga 
-  void check_row(int n, int mode = 0x3);
+  void check_row(int n, int mode = 0x3, bool final = false);
 
   // @cmember Trasferisce i valori dalla maschera alla riga 
   void update_row(int n) { mask2row(n, row(n)); }
@@ -377,12 +381,12 @@ public:
 #define FOR_EACH_SHEET_ROW_BACK(__sheet, __r, __riga)      \
   TString_array& sheetof##__riga = (__sheet).rows_array(); \
   FOR_EACH_ARRAY_ROW_BACK(sheetof##__riga, __r, __riga)                           
+       
+#define FOR_EACH_SHEET_ROW_LOOP(__sheet, __r)                   \
+  int sheetit##__r = __sheet.items();																				 \
+  for (int __r = 0; r < sheetit##__r; r++)              
 
-#define FOR_EACH_SHEET_ROW_LOOP(__sheet, __r)           \
-  int it##__r = __sheet.items(); \
-  for( int __r = 0; r < it##__r; __r++)                           
-
-#define FOR_EACH_SHEET_ROW_BACK_LOOP(__sheet, __r)      \
-  int it##__r = __sheet.items(); \
-  for( int __r = it##__r - 1; r >= 0 ; __r--)   
+#define FOR_EACH_SHEET_ROW_BACK_LOOP(__sheet, __r, __riga)      \
+  int sheetit##__r = __sheet.items();																				 \
+  for (int __r = sheetit##__r - 1; r >= 0; r--)        
 #endif
diff --git a/src/include/relapp.cpp b/src/include/relapp.cpp
index 3a33576f7..9fd8dd070 100755
--- a/src/include/relapp.cpp
+++ b/src/include/relapp.cpp
@@ -7,10 +7,14 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 
+#include 
+#include 
+
 ///////////////////////////////////////////////////////////
 // TRelation_application
 ///////////////////////////////////////////////////////////
@@ -568,10 +572,15 @@ bool TRelation_application::modify_mode()
   {
     if (err == _islocked)
     {
-      _locked = true;
-      message_box(TR("I dati sono già usati da un altro programma, scrittura disabilitata"));
-    }
-    else
+			if (db_log())
+				_locked = !yesno_box(TR("I dati sono già usati da un altro programma, vuoi modificare ugualmente"));
+			else
+			{
+				_locked = true;
+				message_box(TR("I dati sono già usati da un altro programma, scrittura disabilitata"));
+			}
+		}
+		else
     {
       error_box(FR("Impossibile leggere i dati: errore %d"), err);
 		  if (!is_transaction())
@@ -1294,6 +1303,378 @@ int TRelation_application::rewrite(const TMask& m)
 const char* TRelation_application::record_description(const TRelation& r) const
 { return r.file().description(); }
 
+///////////////////////////////////////////////////////////
+// TLogtrans_report
+///////////////////////////////////////////////////////////
+
+class TLogtrans_report : public TReport
+{
+  TAssoc_array _vars;
+
+protected:
+  virtual bool use_mask() { return false; }
+  virtual bool set_usr_val(const TString& name, const TVariant& var);
+  virtual bool get_usr_val(const TString& name, TVariant& var) const;
+
+public:
+  TLogtrans_report(TRecordset* rs);
+};
+
+bool TLogtrans_report::set_usr_val(const TString& name, const TVariant& var)
+{
+  if (!TReport::set_usr_val(name, var))
+    _vars.add(name, new TVariant(var));
+  return true;
+}
+
+bool TLogtrans_report::get_usr_val(const TString& name, TVariant& var) const
+{
+  if (name[0] == '#')
+  {
+    TVariant* v = (TVariant*)_vars.objptr(name);
+    
+    if (v != nullptr)
+    {
+      var = *v;
+      return true;
+    }
+  }
+  if (name == "TRANSACTION")
+  {
+    const int fieldlen = ((TLogtrans_report *)this)->field("B1.114")->get_rect().width() / 100;
+    const TString &data = ((TISAM_recordset *)recordset())->cursor()->curr().get(DBL_TRANS);
+    TString outstring;
+    int pos = data.find("");
+    int rowlen = 0;
+
+    while ((pos = data.find("= 0)
+    {
+      pos += 6;
+      int end = data.find(" />", pos);
+      TString field = data.mid(pos, end - pos);
+
+      field.trim();
+      if ((rowlen + 3 + field.len() >= fieldlen) && outstring.full())
+      {
+        outstring << '\n';
+        rowlen = 0;
+      }
+      if (rowlen > 0)
+      {
+        outstring << "/";
+        rowlen += 1;
+      }
+      outstring << field;
+      rowlen += field.len();
+      pos += 3;
+    }
+    var = outstring;
+    return true;
+  }
+  return TReport::get_usr_val(name, var);
+}
+
+TLogtrans_report::TLogtrans_report(TRecordset* rs)
+{
+  load("bagn010b");
+
+  set_recordset(rs);
+}
+
+
+///////////////////////////////////////////////////////////
+// TLog_mask
+///////////////////////////////////////////////////////////
+
+static COLOR __row_colors[16] = { COLOR_WHITE, blend_colors(COLOR_WHITE, COLOR_RED),
+                                  blend_colors(COLOR_WHITE, COLOR_GREEN), blend_colors(COLOR_WHITE, COLOR_BLUE),
+                                  blend_colors(COLOR_WHITE, COLOR_CYAN), blend_colors(COLOR_WHITE, COLOR_MAGENTA),
+                                  blend_colors(COLOR_WHITE, COLOR_YELLOW), blend_colors(COLOR_WHITE, COLOR_DKGRAY),
+                                  blend_colors(COLOR_WHITE, COLOR_GRAY), blend_colors(COLOR_WHITE, COLOR_LTGRAY),
+                                  blend_colors(COLOR_WHITE, COLOR_DKCYAN), blend_colors(COLOR_WHITE, COLOR_LTYELLOW),
+                                  blend_colors(COLOR_WHITE, COLOR_DKGREEN), blend_colors(COLOR_WHITE, COLOR_DKBLUE),
+                                  blend_colors(COLOR_WHITE, COLOR_DKRED), blend_colors(COLOR_WHITE, COLOR_DKMAGENTA) };
+
+COLOR TLog_mask::row_color(bool change)
+{
+  return __row_colors[_curr_color = (_curr_color + (change ? 1 : 0) % 16)];
+}
+
+HIDDEN const TString & reformat_ora(const TString & ora)
+{
+  bool duepunti = ora.find(":") >= 0;
+  bool meno = ora.find("-") >= 0;
+  TToken_string tmp(ora, duepunti ? ':' : meno ? '-' : '|');
+  long long_ora = tmp.get_int();
+  int minuto = tmp.get_int();
+  int secondo = tmp.get_int();
+  TString & formatted_ora = get_tmp_string(16);
+
+  if (long_ora <= 0)
+    formatted_ora = "24:00:00";
+  else
+  {
+    if (long_ora > 24L)
+    {
+      if (long_ora > 2400L)
+      {
+        secondo = long_ora % 100L;
+        long_ora /= 100L;
+      }
+      else
+        secondo = 0;
+      minuto = long_ora % 100L;
+      long_ora /= 100L;
+    }
+    formatted_ora << format("%02d", long_ora) << ':' << format("%02d", minuto) << ':' << format("%02d", secondo);
+  }
+  return formatted_ora;
+}
+
+void TLog_mask::set_limit(bool on)
+{
+  TString filter;
+
+  if (on)
+  {
+    TDate datalim = get_date(F_DATALIM);
+    TString oralim = get(F_ORALIM);
+
+    if (datalim.ok())
+    {
+      oralim = reformat_ora(oralim);
+      filter << "(STR(" << DBL_DATA << "<" << datalim.date2ansi() << "))||(STR(" << DBL_DATA << "==" << datalim.date2ansi() << ")&&(" << DBL_ORA << "<=\"" << oralim << "\"))";
+    }
+  }
+  _log.setfilter(filter);
+}
+
+void TLog_mask::print_log()
+{
+  set_limit();
+
+;
+  TISAM_recordset * recset = new TISAM_recordset(_log);
+  const int items = _log.items();
+  TString line;
+  TString oralim = get(F_ORALIM);
+  TLogtrans_report transactions(recset);
+
+  transactions.set_var("#DATALIM", get_date(F_DATALIM));
+  transactions.set_var("#ORALIM", oralim = "24:00:00" ? "" : oralim);
+  transactions.set_recordset(recset);
+  transactions.print_or_preview();
+  set_limit(false);
+}
+
+void TLog_mask::replay_log()
+{
+  set_limit();
+  const int items = _log.items();
+  TLog_report logrep;
+
+  for (_log = 0L; _log.pos() < items; ++_log)
+  {
+    TXmlItem trans; trans << _log.curr().get(DBL_TRANS);
+    TToken_string key;
+    TXmlItem * keytag = trans.FindFirst("Key");
+    int n = keytag->GetChildren();
+
+    for (int i = 0; i < n; i++)
+    {
+      TXmlItem * item = keytag->GetChild(i);
+
+      if (item->GetTag() == "field")
+      {
+        TToken_string fieldval(item->GetText(), '=');
+
+        key.add(fieldval.get(1));
+      }
+    }
+
+    const int file = _log.curr().get_int(DBL_FILE);
+    TRectype& rec = (TRectype &) cache().get(file, key);
+    TXmlItem * valuetag = trans.FindFirst("Key");
+
+    n = valuetag->GetChildren();
+    for (int i = 0; i < n; i++)
+    {
+      TXmlItem * item = valuetag->GetChild(i);
+
+      if (item->GetTag() == "data")
+      {
+        TToken_string fieldval(item->GetText(), '=');
+        const TString fieldname(fieldval.get());
+
+        rec.put(fieldname, fieldval.get(1));
+      }
+    }
+
+    TLocalisamfile f(file);
+
+    const int err = rec.write_rewrite(f);
+
+    if (err != NOERR)
+    {
+      logrep.log(2, format("errore =  %d", err));
+    }
+  }
+  set_limit(false);
+}
+
+bool TLog_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
+{
+  switch (o.dlg())
+  {
+  case F_ORALIM:
+    if (e == fe_modify)
+      o.set(reformat_ora(o.get()));
+
+  case F_DATALIM:
+    if (e == fe_modify)
+    {
+      set_limit();
+      load_sheet();
+    }
+    break;
+  case F_PRINT:
+    if (e == fe_button)
+      print_log();
+  break;
+  case F_REPLAY:
+    if (e == fe_button)
+      replay_log();
+    break;
+  case F_SHEET:
+    if (e == se_enter)
+      set_key_values(curr_page(), ((TSheet_field &)o).selected());
+    break;
+  default:
+    break;
+  }
+  return true;
+}
+
+void TLog_mask::set_key_values(int page, long pos)
+{
+  _log = pos;
+  const int file = _log.curr().get_int(DBL_FILE);
+  const TRectype & rec = cache().get(file, _log.curr().get(DBL_KEY));
+
+  if (multi_file())
+    set_mask(page);
+  for (int i = 0; i < 20; i++)
+  {
+    TMask_field & f = field(F_KEYFIELD1 + i);
+    const TString & prompt(f.prompt());
+
+    if (prompt.full())
+      f.set(rec.get(prompt));
+  }
+}
+
+void TLog_mask::set_mask(int page)
+{
+  const TRectype & rec = _datarel->lfile().curr();
+  TTrec trec(rec.num());
+  TToken_string key(trec.keydef());
+  TToken_string fields(key.get(0), '+');
+  TSheet_field & sh = sfield(F_SHEET);
+
+  for (int i = 0; i < 20; i++)
+  {
+    TString prompt(fields.get(i));
+    TMask_field & f = field(F_KEYFIELD1 + i);
+
+    if (prompt.starts_with("UPPER"))
+      prompt = prompt.ltrim(6);
+
+    const int pos = prompt.find('[');
+
+    if (pos > 0)
+      prompt = prompt.left(pos);
+    f.show(prompt.full());
+    f.set_prompt(prompt);
+  }
+
+  if (_select)
+  {
+    RCT rect;
+    int deltay = 9 - (fields.items() - 1) / 2;
+
+    sh.get_rect(rect);
+    rect.top -= deltay;
+    sh.set_rect(rect);
+    sh.force_update();
+  }
+}
+
+void TLog_mask::load_sheet(int page)
+{
+  TSheet_field & sh = sfield(F_SHEET);
+  const int items = _log.items();
+  const TRectype & rec = _log.curr();
+  TString curr_key = rec.get(DBL_KEY);
+  
+  _curr_color = 0;
+  sh.reset_sheet();
+  for (_log = 0L; _log.pos() < items; ++_log)
+  {
+    const int r = sh.set_row_cell(F_DATA, _log.curr().get_date(DBL_DATA));
+
+    sh.set_row_cell(F_ORA, rec.get(DBL_ORA), r);
+    sh.set_row_cell(F_USER, rec.get(DBL_USER), r);
+    sh.set_row_cell(F_SESSION, rec.get_int(DBL_SESSION), r);
+    sh.set_row_cell(F_CONTENT, rec.get(DBL_TRANS), r);
+
+    const TString & key = rec.get(DBL_KEY);
+
+    sh.set_back_and_fore_color(row_color(!select() && key != curr_key), COLOR_BLACK, r);
+    curr_key = key;
+  }
+  sh.force_update();
+}
+
+TLog_mask::TLog_mask(TRelation * rel, bool select) : TAutomask("bagn010"),
+                                                     _select(select), _datarel(rel),
+                                                     _log(new TRelation(LF_DBLOG), "", rel == nullptr ? 1 : 2),
+                                                     _curr_color(-1)
+{
+  TRectype from(_log.curr());
+
+  if (_datarel != nullptr)
+  {
+    const int file = rel->lfile().num();
+
+    from.put(DBL_FILE, file);
+  }
+  set_mask();
+  if (_select)
+  {
+    const TRectype & rec = rel->lfile().curr();
+    const TString & key = rec.key_token();
+
+    from.put(DBL_KEY, key);
+  }
+  if (from.full())
+    _log.setregion(from, from);
+  load_sheet();
+
+}
+
+void TRelation_application::show_log()
+{
+  TLog_mask m(get_relation(), check_edit_mode());
+
+  m.run();
+}
+
+static bool show_log_handler(TMask_field& f, KEY key)
+{
+  if (key == K_SPACE)
+    main_app().show_log();
+  return true;
+}
 // @doc INTERNAL
 
 // @mfunc Cancella il record corrente
@@ -1382,6 +1763,11 @@ void TRelation_application::main_loop()
     
     // imposta la maschera in query mode
     query_mode();
+    if (_mask && _mask->find_by_id(DLG_LOG))
+    {
+      _mask->show(DLG_LOG, db_log() && admin());
+      _mask->set_handler(DLG_LOG, show_log_handler);
+    }
     _mask->open_modal();
     
     // Provoca l'autopremimento per il messaggio di LINK
diff --git a/src/include/relapp.h b/src/include/relapp.h
index 56b02778a..b1cf296df 100755
--- a/src/include/relapp.h
+++ b/src/include/relapp.h
@@ -21,6 +21,33 @@
 #include 
 #endif
 
+// @doc EXTERNAL
+// @class TLog_mask | Classe la visualizzazione e il replay del log delle transazioni
+//
+// @base public | TAutomask
+class TLog_mask : public TAutomask
+{
+  TRelation * _datarel;
+  TCursor _log;
+  bool _select;
+  int _curr_color;
+
+protected:
+  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
+  void set_key_values(int page, long pos);
+  void set_mask(int page = 1);
+  void load_sheet(int page = 1);
+  bool select() const { return _select || curr_page() > 1; }
+  bool multi_file() const { return _datarel == nullptr; }
+  COLOR row_color(bool change);
+  void set_limit(bool on = true);
+  void print_log();
+  void replay_log();
+
+public:
+  TLog_mask(TRelation * rel = nullptr, bool one_rec = false);
+};
+
 // @doc EXTERNAL
 
 // @class TRelation_application | Classe per la gestione di una applicazione di manutenzione di uno
@@ -249,6 +276,9 @@ protected:
 
 // @access Public Member  
 public:
+  // @cmember Visualizza il log
+  virtual void show_log();
+
   virtual void mask2ini(const TMask& m, TConfig& ini);
   // @cmember Ritorna la relazione da modificare
   virtual TRelation* get_relation() const pure;
diff --git a/src/include/tabapp.cpp b/src/include/tabapp.cpp
index 19c1be32a..5b45a511e 100755
--- a/src/include/tabapp.cpp
+++ b/src/include/tabapp.cpp
@@ -108,6 +108,8 @@ bool TTable_application::user_create()
     return false;
   
   _tabname = argv(2);
+	if (_tabname == "ÊU")
+		_tabname = "%CAU";
   _tabname.upper();
   _rel = new TRelation(_tabname);
   
diff --git a/src/include/tsdb.cpp b/src/include/tsdb.cpp
index 76cd1df5f..bf95a2c6b 100644
--- a/src/include/tsdb.cpp
+++ b/src/include/tsdb.cpp
@@ -26,28 +26,35 @@ const real SSimple_query::sq_get_real(const char * field)
 	return  app;
 }
 
-TString SSimple_query::sq_get(const char* field, bool rtrim)
+const TString & SSimple_query::sq_get(const char* field, const bool rtrim)
 {
-	TString fld = _rec.get(field);
+  TString & fld = get_tmp_string(1024);
+  
+  fld = _rec.get(field);
 	if (rtrim)
 		fld.rtrim();
 
 	return fld;
 }
 
-TString SSimple_query::sq_get(const string& field, const bool rtrim)
+const TString & SSimple_query::sq_get(const string& field, const bool rtrim)
 {
 	return sq_get(field.c_str(), rtrim);
 }
 
-TString SSimple_query::sq_get(TString& field, bool rtrim)
+const TString & SSimple_query::sq_get(TString& field, const bool rtrim)
 {
-	return  sq_get(static_cast(field), rtrim);
+	return  sq_get((const char *)field, rtrim);
 }
 
-TString SSimple_query::sq_get(unsigned int column, bool rtrim)
+const TString & SSimple_query::sq_get(unsigned int column, const bool rtrim)
 {
-	return	_rec.get(column);
+  TString & val = get_tmp_string(1024);
+
+  val << _rec.get(column);
+  if (rtrim)
+    val.rtrim();
+	return val;
 }
 
 unsigned SSimple_query::sq_get_num_fields() const
@@ -55,9 +62,12 @@ unsigned SSimple_query::sq_get_num_fields() const
 	return _rec.get_num_fields();
 }
 
-TString SSimple_query::sq_get_name_field(const unsigned column) const
+const TString & SSimple_query::sq_get_name_field(const unsigned column) const
 {
-	return _rec.get_name_field(column);
+  TString & name = get_tmp_string();
+
+  name = _rec.get_name_field(column);
+  return name;
 }
 
 int SSimple_query::sq_get_width_field(const unsigned column) const
@@ -75,6 +85,8 @@ TFieldtypes SSimple_query::sq_get_type_field(const unsigned column) const
 		return _boolfld;
 	if (type == "dtShort")
 		return _intfld;
+  if (type == "dtLong")
+    return _longfld;
 	if (type == "dtULong")
 		return _longfld;
 	if (type == "dtDouble")
diff --git a/src/include/tsdb.h b/src/include/tsdb.h
index 4a92a47ba..8fc0196aa 100644
--- a/src/include/tsdb.h
+++ b/src/include/tsdb.h
@@ -40,29 +40,22 @@
 
 #ifndef __STRINGS_H
 #include 
-#endif // !__STRINGS_H
-
+#endif // 
 #ifndef __DATE_H
 #include 
-#endif // !__DATE_H
+#endif // 
 
 #ifndef __REAL_H
 #include 
-#endif // !__REAL_H
+#endif // 
 
-#define CHIAVE_ID_  "_ID_" 
 #include "recset.h"
 
 /********************************************************************************
- * SSimpleQuery	(Sirio Simple Query)																						*
+ * SSimpleQuery	(Sirio Simple Query)                  				 									*
  * "Wrapper" di TXvt_recordset, implementa OGNI funzione in modo tale da				*
  * poterlo sostituire brutalmente in qualsiasi momento coś da non aver	 				*
- * problemi come durante il passaggio da ISAM a SQL (spero).										*
- * Se ti stai domandando perchè non è stata usata l'ereditarietà (magari con		*
- * un bel ": private TXvt_recordset" coś da bloccare il tutto) è per bloccare	*
- * qualsiasi riferimento a questa classe in eventuali reimplementazioni future.	*
- * Preferisco scrivere un po' di codice ridondante adesso che andare a fare			*
- * salti mortali dopo																														*
+ * problemi come durante il passaggio da ISAM a SQL (spero). che cazzata da riscrivere									*
  ********************************************************************************/
 class SSimple_query
 {
@@ -160,19 +153,19 @@ public:
 	/**< Ritorna il valore nel campo (field) in formato (SADateTime), Campo non gestisce le ore */
 	//SADateTime		sqGetDateTime(const char* field) { get_short(field); }
 	/**< Ritorna il valore nel campo (field) passato come (const char *) in formato (const char *) */
-	TString				sq_get(const char* field, bool rtrim = true);
+	const TString	&	sq_get(const char* field, bool rtrim = true);
 	/**< Ritorna il valore nel campo (field) passato come (string) in formato (const char *) */
-	TString				sq_get(const string& field, bool rtrim = true);
+	const TString	&	sq_get(const string& field, bool rtrim = true);
 	/**< Ritorna il valore nel campo (field) passato come (TString) in formato (const char *)  */
-	TString				sq_get(TString& field, bool rtrim = true);
+	const TString	&	sq_get(TString& field, bool rtrim = true);
 	/**< Ritorna il valore della colonna numero (column) passato come (unsigned int)  */ 
-	TString				sq_get(unsigned int column, bool rtrim = true);
+	const TString	&	sq_get(unsigned int column, bool rtrim = true);
 	/**< Ritorna il valore nel campo (field) in formato (char) */
 	const char		sq_get_char(const char* field) { return _rec.get_char(field); }
 	/**< Ritorna il numero di campi dopo l'ultimo comando di esecuzione effettuato; se il risultato esiste */
 	unsigned int	sq_get_num_fields() const;
-	/**< Ritorna il nome del campo numero (column) in formato (TString= */
-	TString				sq_get_name_field(unsigned column) const;
+	/**< Ritorna il nome del campo numero (column) in formato (TString) = */
+	const TString	& sq_get_name_field(unsigned column) const;
 	/**< Ritorna la grandezza del campo numero (column) */
 	int						sq_get_width_field(unsigned column) const;
 	/**< Ritorna il tipo del campo numero (column) in formato (TFieldtypes) */
@@ -198,12 +191,12 @@ public:
 	void defrost() { _rec.defrost(); }
 
 	/**< Costruttore, non inizializza nulla, da caricare successivamente */
-	SSimple_query() = default;
+  SSimple_query() {};
 	/**< Costruttore, Accetta in ingresso dei parametri per la connessione, volendo è anche possibile impostare una query ed eseguirla. Attenzione! Non risponde se la query ha avuto un esito positivo o negativo! */
 	SSimple_query(const char* db, const char* user, const char* pass, const TT_driver tipo_db, const char * query = "", const bool ex = false, const bool freezed = false) : _rec(db, user, pass, tipo_db, query, ex, freezed) {}
 	//SSimpleQuery(const TString& db, const TString& user, const TString& pass, TT_driver tipoDb, const char * query = "", const bool ex = false, const bool freezed = false) : _rec(db, user, pass, tipoDb, query, ex, freezed) {}
 	/**< Distruttore */
-	virtual ~SSimple_query() = default;
+  virtual ~SSimple_query() {};
 };
 
 #endif
\ No newline at end of file
diff --git a/src/include/winsock.h b/src/include/winsock.h
index 8b94a04cc..5894f661d 100755
--- a/src/include/winsock.h
+++ b/src/include/winsock.h
@@ -490,6 +490,7 @@ struct  linger {
 /*
  * Windows Sockets definitions of regular Microsoft C error constants
  */
+#ifndef WSAEINTR
 #define WSAEINTR                (WSABASEERR+4)
 #define WSAEBADF                (WSABASEERR+9)
 #define WSAEACCES               (WSABASEERR+13)
@@ -497,6 +498,7 @@ struct  linger {
 #define WSAEINVAL               (WSABASEERR+22)
 #define WSAEMFILE               (WSABASEERR+24)
 
+
 /*
  * Windows Sockets definitions of regular Berkeley error constants
  */
@@ -581,6 +583,7 @@ struct  linger {
 /*
  * Windows Sockets errors redefined as regular Berkeley error constants
  */
+
 #define EWOULDBLOCK             WSAEWOULDBLOCK
 #define EINPROGRESS             WSAEINPROGRESS
 #define EALREADY                WSAEALREADY
@@ -618,6 +621,7 @@ struct  linger {
 #define EDQUOT                  WSAEDQUOT
 #define ESTALE                  WSAESTALE
 #define EREMOTE                 WSAEREMOTE
+#endif
 
 /* Socket function prototypes */
 
diff --git a/src/lv/lv2500.cpp b/src/lv/lv2500.cpp
index c34edb369..9c33a57df 100755
--- a/src/lv/lv2500.cpp
+++ b/src/lv/lv2500.cpp
@@ -2284,21 +2284,22 @@ void TFatturazione_lav_app::main_loop()
     recset.cursor()->relation()->lfile().set_curr(new TDocumento);
     for (bool ok = recset.move_first(); ok && pi->add_status(); ok = recset.move_next())
     {
-      TDocumento & doc =(TDocumento &) recset.cursor()->curr();
-      const TCli_for &cli = cached_clifor('C', doc.get_long(DOC_CODCF));
+      TDocumento & doc =(TDocumento &) recset.cursor()->curr();		
+			const TCli_for &cli = doc.clifor();
+			const long codcli = cli.codice();
       //preparo la chiave e recupero da CFVEN i dati di quel cliente
 
-      if (cli.codice() != last_clifo)
+      if (codcli != last_clifo)
       {
-        key.format("C|%ld", cli.codice());
+				key.format("C|%ld", cli.codice());
         TString str; 
         str << TR("Cliente") << ' ' << cli.codice() << ' ' << cache().get(LF_CLIFO, key, CLI_RAGSOC);
         pi->set_text(str);
-        last_clifo = cli.codice();
+        last_clifo = codcli;
       }
       
       //se non è l'ultimo cliente, allora:
-      if (cli.codice() != lastcli)
+      if (codcli != lastcli)
       {
        //se effettivamente devo elaborare delle bolle per questo cliente, allora:
        if (docsin.items() > 0)
@@ -2344,7 +2345,7 @@ void TFatturazione_lav_app::main_loop()
 	         docsin.rewrite();
          docsin.destroy(-1);
        }
-       lastcli = cli.codice();
+       lastcli = codcli;
       }
 
       //se il documento che sto analizzando è corretto, allora:
@@ -2463,10 +2464,10 @@ void TFatturazione_lav_app::main_loop()
               doc.update(DOC_CODCABP, cab);
               doc.update(DOC_PROGBNP, progbnp);
             }
-						doc_updated |= doc.update_if_full(DOC_CODPAG, cli.get(CLI_CODPAG));
-            doc_updated |= doc.update_if_full(DOC_PERCSPINC, cli.vendite().get(CFV_PERCSPINC));
-						doc_updated |= doc.update_if_full(DOC_ADDBOLLI, cli.vendite().get_bool(CFV_ADDBOLLI));
-						doc_updated |= doc.update_if_full(DOC_CODAGVIS, cli.vendite().get(CFV_CODAG1));
+						doc_updated |= doc.update(DOC_CODPAG, cli.get(CLI_CODPAG)); // was update_if_full
+            doc_updated |= doc.update(DOC_PERCSPINC, cli.vendite().get(CFV_PERCSPINC));  // was update_if_full
+						doc_updated |= doc.update(DOC_ADDBOLLI, cli.vendite().get_bool(CFV_ADDBOLLI)); // was update_if_full
+						doc_updated |= doc.update(DOC_CODAGVIS, cli.vendite().get(CFV_CODAG1)); // was update_if_full
 						if (doc_updated)
 						{
 							TString msg(" Cli.");
diff --git a/src/lv/lv3100.cpp b/src/lv/lv3100.cpp
index 35d374f9a..fb9665b36 100755
--- a/src/lv/lv3100.cpp
+++ b/src/lv/lv3100.cpp
@@ -594,7 +594,7 @@ bool TGestione_bolle_msk::lv_bolla_handler(TMask_field& f, KEY k)
     if (dmsk._stcodcf == codcf && dmsk._stcodcont == codcont && nrighe > 0)
       return true;  
     
-    doc.clifor().cli2doc(doc);
+    doc.cli2doc();
     dmsk.mask2doc();  
 
     dmsk._stcodcf = codcf;
diff --git a/src/lv/lv4200.cpp b/src/lv/lv4200.cpp
index 80c82353b..d743f0f93 100755
--- a/src/lv/lv4200.cpp
+++ b/src/lv/lv4200.cpp
@@ -8,8 +8,7 @@
 #include 
 #include 
 
-#include "../cg/cglib01.h"
-#include "../cg/cg2103.h"
+#include "../cg/cglib.h"
 #include "../cg/cgsaldac.h"
 
 #include "lv4.h"
@@ -65,7 +64,7 @@ const TCausale& TCausali_cache::causale(const char tipocf, tipo_movimento tm)
 {
   // Metodo bastardo per evitare TToken_string temporanee "a randa"
   // creo chiave a lunghezza fissa TIPOCF+TIPOMOV+ANNO = C12010
-  const char key[4] = { tipocf, '0'+tm, '\0' };
+  const char key[4] = { tipocf, '0'+(char) tm, '\0' };
   return *(const TCausale*)objptr(key);
 }
 
diff --git a/src/lv/lv4500.cpp b/src/lv/lv4500.cpp
index 03c85cd6a..be27609ea 100755
--- a/src/lv/lv4500.cpp
+++ b/src/lv/lv4500.cpp
@@ -18,8 +18,7 @@
 #include "../ce/cespi.h"
 #include "../ce/salce.h"
 
-#include "../cg/cg2103.h"
-#include "../cg/cglib01.h"
+#include "../cg/cglib.h"
 
 #include "lv4.h"
 #include "lv4100.h"
diff --git a/src/mg/mg0100.cpp b/src/mg/mg0100.cpp
index 3b6019058..3ba93af55 100755
--- a/src/mg/mg0100.cpp
+++ b/src/mg/mg0100.cpp
@@ -426,6 +426,7 @@ TMask * Tab_app_mag::set_mask(TMask * _m)
   {
     const TString& tabname = get_tabname();
     TString maskname; get_mask_name(maskname);
+
     return Tab_application::set_mask(new TMask_tabmag(maskname, tabname));
   }
 }
diff --git a/src/np/np0200.cpp b/src/np/np0200.cpp
index 04c85c22d..3bd5f5aaa 100755
--- a/src/np/np0200.cpp
+++ b/src/np/np0200.cpp
@@ -8,8 +8,7 @@
 
 #include "np0.h"
 #include "np0200.h"
-#include "..\cg\cg2101.h"      
-#include "..\cg\cglib02.h"
+#include "..\cg\cglib.h"
 
 #include 
 #include 
@@ -564,7 +563,7 @@ bool TApertura_chiusura::set()
       (*_cur) = 0L;
       _sld->set_anno_es(_annoesch);
       _sld->set_movprovv(FALSE);
-      _sld->set_tipo_saldo(chiusura); 
+      _sld->set_tipo_saldo(saldo_chiusura); 
       _sld->set_movimentato(TRUE);       
 
       costi();
@@ -582,7 +581,7 @@ bool TApertura_chiusura::set()
       _totale_saldo = ZERO;
     
       _sld->set_anno_es(_annoesap);
-      _sld->set_tipo_saldo(apertura);    
+      _sld->set_tipo_saldo(saldo_apertura);    
       _sld->set_movimentato(TRUE);
       
       *_cur = 0l;
@@ -597,7 +596,7 @@ bool TApertura_chiusura::set()
 		(*_cur) = 0L;
 		_sld->set_anno_es(_annoesch);
 		_sld->set_movprovv(FALSE);
-		_sld->set_tipo_saldo(chiusura);
+		_sld->set_tipo_saldo(saldo_chiusura);
 		_sld->set_movimentato(TRUE);
 
 		costi();
@@ -615,7 +614,7 @@ bool TApertura_chiusura::set()
 		_totale_saldo = ZERO;
 
 		_sld->set_anno_es(_annoesap);
-		_sld->set_tipo_saldo(apertura);
+		_sld->set_tipo_saldo(saldo_apertura);
 		_sld->set_movimentato(TRUE);
 
 		*_cur = 0l;
@@ -769,7 +768,7 @@ void TApertura_chiusura::costi()
         }
 
         s               = saldi.get_long(SLD_SOTTOCONTO);
-        sale.saldo_cont_sep(g, c, s, _annoesch, botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
+        sale.saldo_cont_sep(Registrazione, g, c, s, _annoesch, botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
         _saldo          = sale.saldo();
 
         if (_saldo.is_zero())
@@ -915,7 +914,7 @@ void TApertura_chiusura::ricavi()
       
         //numrig++;
         s               = saldi.get_long(SLD_SOTTOCONTO);
-        sale.saldo_cont_sep(g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
+        sale.saldo_cont_sep(Registrazione, g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
         _saldo          = sale.saldo();
 
         if (_saldo.is_zero()) continue;
@@ -1154,7 +1153,7 @@ void TApertura_chiusura::chiudi_attivita()
         }
 
         s  = saldi.get_long(SLD_SOTTOCONTO);
-        sale.saldo_cont_sep(g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
+        sale.saldo_cont_sep(Registrazione, g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
         _saldo  = sale.saldo();
         const int dbkey = saldi.getkey();
         saldi.setkey(1);
@@ -1304,7 +1303,7 @@ void TApertura_chiusura::chiudi_passivita()
         //numrig++;
         s               = saldi.get_long(SLD_SOTTOCONTO);
         //sale.calcola_ultima_immissione(_annoesch,0,g,c,s,indbil);
-        sale.saldo_cont_sep(g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
+        sale.saldo_cont_sep(Registrazione, g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
         _saldo          = sale.saldo();
         
         if (_saldo.is_zero()) continue;
@@ -1449,7 +1448,7 @@ void TApertura_chiusura::chiudi_conti_ordine()
         }
 
         s               = saldi.get_long(SLD_SOTTOCONTO);
-        sale.saldo_cont_sep(g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
+        sale.saldo_cont_sep(Registrazione, g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
         _saldo          = sale.saldo();
         const int dbkey = saldi.getkey();
         saldi.setkey(1);
@@ -1646,7 +1645,7 @@ void TApertura_chiusura::apri_attivita()
 
         //numrig++;
         s               = saldi.get_long(SLD_SOTTOCONTO);
-        sale.saldo_cont_sep(g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
+        sale.saldo_cont_sep(Registrazione, g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
         _saldo          = sale.saldo();
 
         if (_saldo == ZERO) continue;
@@ -1792,7 +1791,7 @@ void TApertura_chiusura::apri_passivita()
       
         //numrig++;
         s               = saldi.get_long(SLD_SOTTOCONTO);
-        sale.saldo_cont_sep(g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
+        sale.saldo_cont_sep(Registrazione, g, c, s, _annoesch,  botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
         _saldo          = sale.saldo();
 
         if (_saldo.is_zero()) continue;
@@ -1938,7 +1937,7 @@ void TApertura_chiusura::apri_conti_ordine()
         //numrig++;
         s               = saldi.get_long(SLD_SOTTOCONTO);
 
-        sale.saldo_cont_sep(g, c, s, _annoesch, botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
+        sale.saldo_cont_sep(Registrazione, g, c, s, _annoesch, botime, indbil, _cod_cont_sep, 0, _cod_cont_sep.blank());
         _saldo          = sale.saldo();
 
         if (_saldo == ZERO) continue;
diff --git a/src/or/orlib01.cpp b/src/or/orlib01.cpp
index 9982657b4..bad004975 100755
--- a/src/or/orlib01.cpp
+++ b/src/or/orlib01.cpp
@@ -380,7 +380,7 @@ bool TOrdine_form::validate(TForm_item &cf, TToken_string &s)
             TDocumento&   documento = (TDocumento&)cf.form().cursor()->curr(LF_DOC);
             TCli_for&     cli_for   = documento.clifor();
             TOccasionale& cli_occ   = documento.occas();
-            const bool occasionale  = cli_for.occasionale();
+            const bool occasionale  = cli_for.is_occasionale();
             if (print_cod)
               ws << cli_for.get("CODCF") << " ";
             if (occasionale)
diff --git a/src/ps/CRPA/00004a/custom/crpftacq.msk b/src/ps/CRPA/00004a/custom/crpftacq.msk
index 54a4d1947..d9a2263e5 100644
--- a/src/ps/CRPA/00004a/custom/crpftacq.msk
+++ b/src/ps/CRPA/00004a/custom/crpftacq.msk
@@ -512,6 +512,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00004a/custom/crpparc.msk b/src/ps/CRPA/00004a/custom/crpparc.msk
index 0bfa811a5..0c3945dd3 100644
--- a/src/ps/CRPA/00004a/custom/crpparc.msk
+++ b/src/ps/CRPA/00004a/custom/crpparc.msk
@@ -496,6 +496,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00004a/custom/crprim.msk b/src/ps/CRPA/00004a/custom/crprim.msk
index 4a92d8555..3803e65c7 100644
--- a/src/ps/CRPA/00004a/custom/crprim.msk
+++ b/src/ps/CRPA/00004a/custom/crprim.msk
@@ -499,6 +499,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00004a/custom/fatacq.msk b/src/ps/CRPA/00004a/custom/fatacq.msk
index 18efff2c1..a514a0ca1 100644
--- a/src/ps/CRPA/00004a/custom/fatacq.msk
+++ b/src/ps/CRPA/00004a/custom/fatacq.msk
@@ -511,6 +511,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00005a/custom/crpftacq.msk b/src/ps/CRPA/00005a/custom/crpftacq.msk
index 54a4d1947..d9a2263e5 100644
--- a/src/ps/CRPA/00005a/custom/crpftacq.msk
+++ b/src/ps/CRPA/00005a/custom/crpftacq.msk
@@ -512,6 +512,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00005a/custom/crpparc.msk b/src/ps/CRPA/00005a/custom/crpparc.msk
index 0bfa811a5..0c3945dd3 100644
--- a/src/ps/CRPA/00005a/custom/crpparc.msk
+++ b/src/ps/CRPA/00005a/custom/crpparc.msk
@@ -496,6 +496,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00005a/custom/crprim.msk b/src/ps/CRPA/00005a/custom/crprim.msk
index 4a92d8555..3803e65c7 100644
--- a/src/ps/CRPA/00005a/custom/crprim.msk
+++ b/src/ps/CRPA/00005a/custom/crprim.msk
@@ -499,6 +499,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00005a/custom/fatacq.msk b/src/ps/CRPA/00005a/custom/fatacq.msk
index 18efff2c1..a514a0ca1 100644
--- a/src/ps/CRPA/00005a/custom/fatacq.msk
+++ b/src/ps/CRPA/00005a/custom/fatacq.msk
@@ -511,6 +511,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00006a/custom/crpftacq.msk b/src/ps/CRPA/00006a/custom/crpftacq.msk
index 54a4d1947..d9a2263e5 100644
--- a/src/ps/CRPA/00006a/custom/crpftacq.msk
+++ b/src/ps/CRPA/00006a/custom/crpftacq.msk
@@ -512,6 +512,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00006a/custom/crpparc.msk b/src/ps/CRPA/00006a/custom/crpparc.msk
index 0bfa811a5..0c3945dd3 100644
--- a/src/ps/CRPA/00006a/custom/crpparc.msk
+++ b/src/ps/CRPA/00006a/custom/crpparc.msk
@@ -496,6 +496,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00006a/custom/crprim.msk b/src/ps/CRPA/00006a/custom/crprim.msk
index 4a92d8555..3803e65c7 100644
--- a/src/ps/CRPA/00006a/custom/crprim.msk
+++ b/src/ps/CRPA/00006a/custom/crprim.msk
@@ -499,6 +499,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/00006a/custom/fatacq.msk b/src/ps/CRPA/00006a/custom/fatacq.msk
index 18efff2c1..a514a0ca1 100644
--- a/src/ps/CRPA/00006a/custom/fatacq.msk
+++ b/src/ps/CRPA/00006a/custom/fatacq.msk
@@ -511,6 +511,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/CUSTOM/VERIGA3.MSK b/src/ps/CRPA/CUSTOM/VERIGA3.MSK
index e14f3f3c0..e0dba3bb5 100644
--- a/src/ps/CRPA/CUSTOM/VERIGA3.MSK
+++ b/src/ps/CRPA/CUSTOM/VERIGA3.MSK
@@ -123,6 +123,24 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 14 "Rev.charge  "
+FI REVCHARGE
+EN
+ST 154 1
+BE
+PR 30 14 "Indetraib.  "
+US %DET
+IN CODTAB 154
+DI "Codice" CODTAB
+DI "Tipo" I0
+DI "Descrizione@50" S0
+OU 154 CODTAB
+CH NORMAL
+FI TIPODET
+FL "U"
+EN
 NU 133 3
 BE
 PR 2 15 "Gruppo "
diff --git a/src/ps/CRPA/CUSTOM/VERIGI1.MSK b/src/ps/CRPA/CUSTOM/VERIGI1.MSK
index ae0e1255b..3c288465d 100644
--- a/src/ps/CRPA/CUSTOM/VERIGI1.MSK
+++ b/src/ps/CRPA/CUSTOM/VERIGI1.MSK
@@ -277,6 +277,24 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 14 "Rev.charge  "
+FI REVCHARGE
+EN
+ST 154 1
+BE
+PR 30 14 "Indetraib.  "
+US %DET
+IN CODTAB 154
+DI "Codice" CODTAB
+DI "Tipo" I0
+DI "Descrizione@50" S0
+OU 154 CODTAB
+CH NORMAL
+FI TIPODET
+FL "U"
+EN
 ST 127 5
 BE
 PR 2 18 "Caus.mag.   "
diff --git a/src/ps/CRPA/CUSTOM/VERIGI5.MSK b/src/ps/CRPA/CUSTOM/VERIGI5.MSK
index c96b30653..7df56a9f6 100644
--- a/src/ps/CRPA/CUSTOM/VERIGI5.MSK
+++ b/src/ps/CRPA/CUSTOM/VERIGI5.MSK
@@ -277,6 +277,24 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 14 "Rev.charge  "
+FI REVCHARGE
+EN
+ST 154 1
+BE
+PR 30 14 "Indetraib.  "
+US %DET
+IN CODTAB 154
+DI "Codice" CODTAB
+DI "Tipo" I0
+DI "Descrizione@50" S0
+OU 154 CODTAB
+CH NORMAL
+FI TIPODET
+FL "U"
+EN
 ST 127 5
 BE
 PR 2 18 "Caus.mag.   "
diff --git a/src/ps/CRPA/CUSTOM/crpaordc.msk b/src/ps/CRPA/CUSTOM/crpaordc.msk
index fa73dcfd0..95682c605 100644
--- a/src/ps/CRPA/CUSTOM/crpaordc.msk
+++ b/src/ps/CRPA/CUSTOM/crpaordc.msk
@@ -487,7 +487,7 @@ CO OU 113
 EN
 ST 226 6
 BE
-PR 2 20 "Contabilità separata  "
+PR 2 19 "Contabilità separata  "
 FL "U"
 CH NORMAL
 FI CONTSEP
diff --git a/src/ps/CRPA/CUSTOM/crpparc.msk b/src/ps/CRPA/CUSTOM/crpparc.msk
index 4162fa961..3824265b8 100644
--- a/src/ps/CRPA/CUSTOM/crpparc.msk
+++ b/src/ps/CRPA/CUSTOM/crpparc.msk
@@ -498,7 +498,7 @@ ADD RU ba3 -6
 EN
 ST 226 6
 BE
-PR 2 20 "Contabilità separata  "
+PR 2 19 "Contabilità separata  "
 FL "U"
 CH NORMAL
 FI CONTSEP
diff --git a/src/ps/CRPA/CUSTOM/crprim.ini b/src/ps/CRPA/CUSTOM/crprim.ini
index a425c2645..cc3b00898 100644
--- a/src/ps/CRPA/CUSTOM/crprim.ini
+++ b/src/ps/CRPA/CUSTOM/crprim.ini
@@ -6,8 +6,6 @@ CAMPICALC=TOTMER|TOTPRE|SPESE|SPESINC|SPESIMB|SPESTRA|BOLLI|IMPONIBILI|IMPOSTE|T
 CALCOLI=*
 TOTPROVV =
 TIPOCF=F
-QTA=
-QTAEVASA=
 [PROFILO]
 OCCASEDIT = 3
 OCFPI = 1
diff --git a/src/ps/CRPA/CUSTOM/crprim.msk b/src/ps/CRPA/CUSTOM/crprim.msk
index 629750aea..1b79e080c 100644
--- a/src/ps/CRPA/CUSTOM/crprim.msk
+++ b/src/ps/CRPA/CUSTOM/crprim.msk
@@ -501,7 +501,7 @@ ADD RU ba3 -6
 EN
 ST 226 6
 BE
-PR 2 20 "Contabilità separata  "
+PR 2 19 "Contabilità separata  "
 FL "U"
 CH NORMAL
 FI CONTSEP
diff --git a/src/ps/CRPA/CUSTOM/fatacq.msk b/src/ps/CRPA/CUSTOM/fatacq.msk
index 8ae9db78f..8e85775c0 100644
--- a/src/ps/CRPA/CUSTOM/fatacq.msk
+++ b/src/ps/CRPA/CUSTOM/fatacq.msk
@@ -513,7 +513,7 @@ ADD RU ba3 -6
 EN
 ST 226 6
 BE
-PR 2 20 "Contabilità separata  "
+PR 2 19 "Contabilità separata  "
 FL "U"
 CH NORMAL
 FI CONTSEP
diff --git a/src/ps/CRPA/CUSTOM/fatturac.msk b/src/ps/CRPA/CUSTOM/fatturac.msk
index 5e12d3677..76bc63870 100644
--- a/src/ps/CRPA/CUSTOM/fatturac.msk
+++ b/src/ps/CRPA/CUSTOM/fatturac.msk
@@ -487,7 +487,7 @@ CO OU 113
 EN
 ST 226 6
 BE
-PR 2 20 "Contabilità separata  "
+PR 2 19 "Contabilità separata  "
 FL "U"
 CH NORMAL
 FI CONTSEP
diff --git a/src/ps/CRPA/CUSTOM/incf.msk b/src/ps/CRPA/CUSTOM/incf.msk
index 4ec8e2ff7..ce751a111 100644
--- a/src/ps/CRPA/CUSTOM/incf.msk
+++ b/src/ps/CRPA/CUSTOM/incf.msk
@@ -469,6 +469,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 20 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/CUSTOM/orfm.msk b/src/ps/CRPA/CUSTOM/orfm.msk
index 4d2e2c742..ba6d1d046 100644
--- a/src/ps/CRPA/CUSTOM/orfm.msk
+++ b/src/ps/CRPA/CUSTOM/orfm.msk
@@ -469,6 +469,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 20 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/CUSTOM/parc.msk b/src/ps/CRPA/CUSTOM/parc.msk
index fc9734273..dd615775d 100644
--- a/src/ps/CRPA/CUSTOM/parc.msk
+++ b/src/ps/CRPA/CUSTOM/parc.msk
@@ -437,6 +437,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/CUSTOM/rim.msk b/src/ps/CRPA/CUSTOM/rim.msk
index 90b194016..29adb8218 100644
--- a/src/ps/CRPA/CUSTOM/rim.msk
+++ b/src/ps/CRPA/CUSTOM/rim.msk
@@ -440,6 +440,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/CRPA/CUSTOM/verig01.msk b/src/ps/CRPA/CUSTOM/verig01.msk
index d496589c8..710afbffb 100644
--- a/src/ps/CRPA/CUSTOM/verig01.msk
+++ b/src/ps/CRPA/CUSTOM/verig01.msk
@@ -300,9 +300,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 272 S0
 EN
+BO 187 
+BE
+PR 2 16 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 16 "Indetraib.  "
+PR 30 16 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/CRPA/CUSTOM/verig06.msk b/src/ps/CRPA/CUSTOM/verig06.msk
index c4f2533fc..d2d687479 100644
--- a/src/ps/CRPA/CUSTOM/verig06.msk
+++ b/src/ps/CRPA/CUSTOM/verig06.msk
@@ -135,9 +135,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 272 S0
 EN
+BO 187 
+BE
+PR 2 16 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 16 "Indetraib.  "
+PR 30 16 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/CRPA/CUSTOM/verigA3.ini b/src/ps/CRPA/CUSTOM/verigA3.ini
index 5d35c219b..2fe97860b 100644
--- a/src/ps/CRPA/CUSTOM/verigA3.ini
+++ b/src/ps/CRPA/CUSTOM/verigA3.ini
@@ -3,10 +3,6 @@
 CALCOLI = *
 CAMPICALC =
 IMPONIBILE = IMPNS
-PROVV =
-QTARES =
-RIGAVALORE =
-RIGAVALRES =
 SELCLIFO = X
 VARP+ = 0
 VARP- = 0
diff --git a/src/ps/CRPA/CUSTOM/verigI6.msk b/src/ps/CRPA/CUSTOM/verigI6.msk
index 73d159a3a..e55ee361e 100644
--- a/src/ps/CRPA/CUSTOM/verigI6.msk
+++ b/src/ps/CRPA/CUSTOM/verigI6.msk
@@ -130,6 +130,24 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 14 "Rev.charge  "
+FI REVCHARGE
+EN
+ST 154 1
+BE
+PR 30 14 "Indetraib.  "
+US %DET
+IN CODTAB 154
+DI "Codice" CODTAB
+DI "Tipo" I0
+DI "Descrizione@50" S0
+OU 154 CODTAB
+CH NORMAL
+FI TIPODET
+FL "U"
+EN
 EN
 ENDMASK
 
diff --git a/src/ps/CRPA/CUSTOM/veriga4.msk b/src/ps/CRPA/CUSTOM/veriga4.msk
index 786bdfdcf..8d09ba5e6 100644
--- a/src/ps/CRPA/CUSTOM/veriga4.msk
+++ b/src/ps/CRPA/CUSTOM/veriga4.msk
@@ -90,6 +90,24 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 12 "Rev.charge  "
+FI REVCHARGE
+EN
+ST 154 1
+BE
+PR 30 12 "Indetraib.  "
+US %DET
+IN CODTAB 154
+DI "Codice" CODTAB
+DI "Tipo" I0
+DI "Descrizione@50" S0
+OU 154 CODTAB
+CH NORMAL
+FI TIPODET
+FL "U"
+EN
 EN
 ENDMASK
 
diff --git a/src/ps/Dinamica/CUSTOM/crpaorcv.msk b/src/ps/Dinamica/CUSTOM/crpaorcv.msk
index af158058a..7c1303f31 100644
--- a/src/ps/Dinamica/CUSTOM/crpaorcv.msk
+++ b/src/ps/Dinamica/CUSTOM/crpaorcv.msk
@@ -488,6 +488,20 @@ DI "Descrizione@50" S0
 DI "Codice" CODTAB
 CO OU 113
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/crpaordc.msk b/src/ps/Dinamica/CUSTOM/crpaordc.msk
index b170085f9..5d937c8ac 100644
--- a/src/ps/Dinamica/CUSTOM/crpaordc.msk
+++ b/src/ps/Dinamica/CUSTOM/crpaordc.msk
@@ -485,6 +485,20 @@ DI "Descrizione@50" S0
 DI "Codice" CODTAB
 CO OU 113
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/crpaordf.msk b/src/ps/Dinamica/CUSTOM/crpaordf.msk
index 6feb63d7d..2e448b48d 100644
--- a/src/ps/Dinamica/CUSTOM/crpaordf.msk
+++ b/src/ps/Dinamica/CUSTOM/crpaordf.msk
@@ -525,9 +525,23 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 NU 378 3
 BE
-PR 2 19 "Unità loc. "
+PR 2 20 "Unità loc. "
 FLAG "U"
 CH REQUIRED
 US 11 KE 1
@@ -546,7 +560,7 @@ HE "Codice dell'unita' locale"
 EN
 ST 379 50
 BE
-PR 24 19 ""
+PR 24 20 ""
 FLAG "D"
 EN
 NU 380 5
diff --git a/src/ps/Dinamica/CUSTOM/crpaorfv.msk b/src/ps/Dinamica/CUSTOM/crpaorfv.msk
index 9b1a2e564..6b0bf5466 100644
--- a/src/ps/Dinamica/CUSTOM/crpaorfv.msk
+++ b/src/ps/Dinamica/CUSTOM/crpaorfv.msk
@@ -525,9 +525,23 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 NU 378 3
 BE
-PR 2 19 "Unità loc. "
+PR 2 20 "Unità loc. "
 FLAG "U"
 CH REQUIRED
 US 11 KE 1
@@ -546,7 +560,7 @@ HE "Codice dell'unita' locale"
 EN
 ST 379 50
 BE
-PR 24 19 ""
+PR 24 20 ""
 FLAG "D"
 EN
 NU 380 5
diff --git a/src/ps/Dinamica/CUSTOM/crpbol.msk b/src/ps/Dinamica/CUSTOM/crpbol.msk
index 62946517a..915f31a64 100644
--- a/src/ps/Dinamica/CUSTOM/crpbol.msk
+++ b/src/ps/Dinamica/CUSTOM/crpbol.msk
@@ -424,6 +424,20 @@ DI "Descrizione@50" S0
 DI "Codice" CODTAB
 CO OU 113
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/crpftacq.msk b/src/ps/Dinamica/CUSTOM/crpftacq.msk
index 11c59fedc..c1ca9a506 100644
--- a/src/ps/Dinamica/CUSTOM/crpftacq.msk
+++ b/src/ps/Dinamica/CUSTOM/crpftacq.msk
@@ -512,6 +512,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/crporfm.msk b/src/ps/Dinamica/CUSTOM/crporfm.msk
index 186068042..b45eaf374 100644
--- a/src/ps/Dinamica/CUSTOM/crporfm.msk
+++ b/src/ps/Dinamica/CUSTOM/crporfm.msk
@@ -525,9 +525,23 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 20 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 NU 378 3
 BE
-PR 2 19 "Unità loc. "
+PR 2 20 "Unità loc. "
 FLAG "U"
 CH REQUIRED
 US 11 KE 1
diff --git a/src/ps/Dinamica/CUSTOM/crpparc.msk b/src/ps/Dinamica/CUSTOM/crpparc.msk
index 93e86b565..2a0c4701c 100644
--- a/src/ps/Dinamica/CUSTOM/crpparc.msk
+++ b/src/ps/Dinamica/CUSTOM/crpparc.msk
@@ -433,6 +433,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/crprim.msk b/src/ps/Dinamica/CUSTOM/crprim.msk
index 55c0d6bbb..8bb47563e 100644
--- a/src/ps/Dinamica/CUSTOM/crprim.msk
+++ b/src/ps/Dinamica/CUSTOM/crprim.msk
@@ -499,6 +499,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/dinfdrv.msk b/src/ps/Dinamica/CUSTOM/dinfdrv.msk
index 11c59fedc..c1ca9a506 100644
--- a/src/ps/Dinamica/CUSTOM/dinfdrv.msk
+++ b/src/ps/Dinamica/CUSTOM/dinfdrv.msk
@@ -512,6 +512,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/fatacq.msk b/src/ps/Dinamica/CUSTOM/fatacq.msk
index dfc651a3a..201f2652a 100644
--- a/src/ps/Dinamica/CUSTOM/fatacq.msk
+++ b/src/ps/Dinamica/CUSTOM/fatacq.msk
@@ -511,6 +511,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/fatclval.msk b/src/ps/Dinamica/CUSTOM/fatclval.msk
index 395969ae3..7dddb47cf 100644
--- a/src/ps/Dinamica/CUSTOM/fatclval.msk
+++ b/src/ps/Dinamica/CUSTOM/fatclval.msk
@@ -489,6 +489,20 @@ DI "Descrizione@50" S0
 DI "Codice" CODTAB
 CO OU 113
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/fatturac.msk b/src/ps/Dinamica/CUSTOM/fatturac.msk
index d6dceff84..27594762a 100644
--- a/src/ps/Dinamica/CUSTOM/fatturac.msk
+++ b/src/ps/Dinamica/CUSTOM/fatturac.msk
@@ -485,6 +485,20 @@ DI "Descrizione@50" S0
 DI "Codice" CODTAB
 CO OU 113
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pagamenti" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/ftacqv.msk b/src/ps/Dinamica/CUSTOM/ftacqv.msk
index 8be037540..afdd7fed7 100644
--- a/src/ps/Dinamica/CUSTOM/ftacqv.msk
+++ b/src/ps/Dinamica/CUSTOM/ftacqv.msk
@@ -449,6 +449,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/incf.msk b/src/ps/Dinamica/CUSTOM/incf.msk
index 1c3106024..8dace9a28 100644
--- a/src/ps/Dinamica/CUSTOM/incf.msk
+++ b/src/ps/Dinamica/CUSTOM/incf.msk
@@ -461,6 +461,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 20 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/orfm.msk b/src/ps/Dinamica/CUSTOM/orfm.msk
index 803aa4a6c..180ae094c 100644
--- a/src/ps/Dinamica/CUSTOM/orfm.msk
+++ b/src/ps/Dinamica/CUSTOM/orfm.msk
@@ -461,6 +461,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 20 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/parc.msk b/src/ps/Dinamica/CUSTOM/parc.msk
index 09fa0a4d1..c38f55ab6 100644
--- a/src/ps/Dinamica/CUSTOM/parc.msk
+++ b/src/ps/Dinamica/CUSTOM/parc.msk
@@ -433,6 +433,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/rim.msk b/src/ps/Dinamica/CUSTOM/rim.msk
index 509df555f..6b6b20ac9 100644
--- a/src/ps/Dinamica/CUSTOM/rim.msk
+++ b/src/ps/Dinamica/CUSTOM/rim.msk
@@ -435,6 +435,20 @@ HE "Inserisci il codice del tipo di pagamento"
 WA "Codice tipo pagamento non trovato"
 ADD RU ba3 -6
 EN
+ST 226 6
+BE
+PR 2 19 "Contabilità separata  "
+FL "U"
+CH NORMAL
+FI CONTSEP
+US &NPENT
+IN CODTAB 226
+DI "Codice@6" CODTAB
+DI "Descrizione@50" S0
+OU 226 CODTAB
+ADD RUN np0 -0 &ENT
+MO NP
+EN
 EN
 PA "Pag. 2" 11 60 14
 GR -1 78 6
diff --git a/src/ps/Dinamica/CUSTOM/verig06.msk b/src/ps/Dinamica/CUSTOM/verig06.msk
index 4757ae026..112062e99 100644
--- a/src/ps/Dinamica/CUSTOM/verig06.msk
+++ b/src/ps/Dinamica/CUSTOM/verig06.msk
@@ -135,9 +135,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 14 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 14 "Indetraib.  "
+PR 30 14 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/Dinamica/CUSTOM/verigI2.msk b/src/ps/Dinamica/CUSTOM/verigI2.msk
index b6a36dd65..de1993fa2 100644
--- a/src/ps/Dinamica/CUSTOM/verigI2.msk
+++ b/src/ps/Dinamica/CUSTOM/verigI2.msk
@@ -89,9 +89,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 272 S0
 EN
+BO 187 
+BE
+PR 2 12 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 12 "Indetraib.  "
+PR 30 12 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/Dinamica/CUSTOM/verigI3.msk b/src/ps/Dinamica/CUSTOM/verigI3.msk
index b6a36dd65..de1993fa2 100644
--- a/src/ps/Dinamica/CUSTOM/verigI3.msk
+++ b/src/ps/Dinamica/CUSTOM/verigI3.msk
@@ -89,9 +89,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 272 S0
 EN
+BO 187 
+BE
+PR 2 12 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 12 "Indetraib.  "
+PR 30 12 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/Dinamica/CUSTOM/verigI4.msk b/src/ps/Dinamica/CUSTOM/verigI4.msk
index b6a36dd65..de1993fa2 100644
--- a/src/ps/Dinamica/CUSTOM/verigI4.msk
+++ b/src/ps/Dinamica/CUSTOM/verigI4.msk
@@ -89,9 +89,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 272 S0
 EN
+BO 187 
+BE
+PR 2 12 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 12 "Indetraib.  "
+PR 30 12 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/Dinamica/CUSTOM/verigI5.msk b/src/ps/Dinamica/CUSTOM/verigI5.msk
index 2e2d4461b..c63c2de05 100644
--- a/src/ps/Dinamica/CUSTOM/verigI5.msk
+++ b/src/ps/Dinamica/CUSTOM/verigI5.msk
@@ -130,9 +130,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 14 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 14 "Indetraib.  "
+PR 30 14 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/Dinamica/CUSTOM/verigI6.msk b/src/ps/Dinamica/CUSTOM/verigI6.msk
index 2e2d4461b..c63c2de05 100644
--- a/src/ps/Dinamica/CUSTOM/verigI6.msk
+++ b/src/ps/Dinamica/CUSTOM/verigI6.msk
@@ -130,9 +130,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 14 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 14 "Indetraib.  "
+PR 30 14 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/Dinamica/CUSTOM/veriga4.msk b/src/ps/Dinamica/CUSTOM/veriga4.msk
index 25369205a..b57d98ec4 100644
--- a/src/ps/Dinamica/CUSTOM/veriga4.msk
+++ b/src/ps/Dinamica/CUSTOM/veriga4.msk
@@ -90,9 +90,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 12 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 12 "Indetraib.  "
+PR 30 12 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/Dinamica/CUSTOM/verigi1.msk b/src/ps/Dinamica/CUSTOM/verigi1.msk
index 4e767fe50..353c2a312 100644
--- a/src/ps/Dinamica/CUSTOM/verigi1.msk
+++ b/src/ps/Dinamica/CUSTOM/verigi1.msk
@@ -135,9 +135,14 @@ DI "Codice@20" CODTAB
 OU 124 CODTAB
 OU 252 S0
 EN
+BO 187 
+BE
+PR 2 14 "Rev.charge  "
+FI REVCHARGE
+EN
 ST 154 1
 BE
-PR 2 14 "Indetraib.  "
+PR 30 14 "Indetraib.  "
 US %DET
 IN CODTAB 154
 DI "Codice" CODTAB
diff --git a/src/ps/ps0330100.cpp b/src/ps/ps0330100.cpp
index 996ea0cfd..11fcc52a7 100755
--- a/src/ps/ps0330100.cpp
+++ b/src/ps/ps0330100.cpp
@@ -132,10 +132,6 @@ bool TMultimarche::create()
   if (!has_module(VEAUT))
     return error_box(TR("Modulo non autorizzato"));
   
-  Tdninst dninst;
-  if (!dninst.can_I_run(true))
-    return error_box(TR("Programma non autorizzato!"));
-  
   return TSkeleton_application::create();
 }
 
diff --git a/src/ps/ps0330200.cpp b/src/ps/ps0330200.cpp
index f0f4a5996..eb979bb7a 100755
--- a/src/ps/ps0330200.cpp
+++ b/src/ps/ps0330200.cpp
@@ -213,9 +213,6 @@ bool TDisp_by_ftp::create()
   //se non ha VE non pụ proseguire
   if (!has_module(VEAUT))
     return error_box(TR("Modulo non autorizzato"));
-  Tdninst dninst;
-  if (!dninst.can_I_run(true))
-    return error_box(TR("Programma non autorizzato!"));
   return TSkeleton_application::create();
 }
 
diff --git a/src/ps/ps0398100.cpp b/src/ps/ps0398100.cpp
index b6277929f..1d4699c88 100755
--- a/src/ps/ps0398100.cpp
+++ b/src/ps/ps0398100.cpp
@@ -528,9 +528,6 @@ bool TTrasferimento_ordini::elabora()
 
 bool TTrasferimento_ordini::create()
 {
-  Tdninst dninst;
-  if (!dninst.can_I_run(true))
-    return error_box(TR("Programma non autorizzato!"));
   return TSkeleton_application::create();
 }
 
diff --git a/src/ri/rilib01.cpp b/src/ri/rilib01.cpp
index a9b6a2982..914523fa7 100755
--- a/src/ri/rilib01.cpp
+++ b/src/ri/rilib01.cpp
@@ -22,14 +22,14 @@ class TSaldo_ricl : public TSaldo
 	TArray _progavere;
 
 public:
-  const real& saldo_periodo(int g, int c, long s, const TArray & dal, const TArray& al, bool provv);
+  const real& saldo_periodo(TTipo_data tipo_data, int g, int c, long s, const TArray & dal, const TArray& al, bool provv);
   const real& progdare(int p) const { return (real&) _progdare[p];}
   const real& progavere(int p) const { return (real&) _progavere[p];}
 	TSaldo_ricl() { }
   virtual ~TSaldo_ricl() {}
 };
 
-const real& TSaldo_ricl::saldo_periodo(int g, int c, long s, const TArray & dal, const TArray & al, bool provv)
+const real& TSaldo_ricl::saldo_periodo(TTipo_data tipo_data, int g, int c, long s, const TArray & dal, const TArray & al, bool provv)
 {
 	saldoini_ref() = ZERO;
   saldo_ref() = ZERO;
@@ -107,19 +107,19 @@ const real& TSaldo_ricl::saldo_periodo(int g, int c, long s, const TArray & dal,
 			  const char sezione  = rmov.get_char(RMV_SEZIONE);
 			  // "Se la causale del movimento e' di chiusura, 
 			  //  o di apertura il movimento non va considerato"
-				const TRectype& mov = cache().get(LF_MOV, num_reg);  
-				const TDate & datacomp = mov.get_date(MOV_DATACOMP);
+				const TRectype& mov = cache().get(LF_MOV, num_reg);
+				const TDate data = get_date_mov(mov, tipo_data);
 				const TRectype& cau = cache().get(LF_CAUSALI, mov.get(MOV_CODCAUS));  
 
 			  if ((provv || !mov.get_bool(MOV_PROVVIS)) && cau.get(CAU_MOVAP).blank())
 			  {
-				  if (datacomp >= da && datacomp <= a)
+				  if (data >= da && data <= a)
 				  {
 						int per = 0;
 
 						set_movimentato();
 						for (per = 0; per < nper; per++)
-							if (datacomp <= (const TDate &) al[per])
+							if (data <= (const TDate &) al[per])
 								break;
 					  if (sezione == 'D') 
 						{
@@ -135,7 +135,7 @@ const real& TSaldo_ricl::saldo_periodo(int g, int c, long s, const TArray & dal,
 						}
 				  }
 				  else
-					  if (datacomp >= inizio && datacomp < da)
+					  if (data >= inizio && datacomp < da)
 					  {   
 						  if (sezione == 'D')  
 							  saldoini_ref() += importo;
@@ -182,7 +182,7 @@ public:
 	virtual ~TSaldo_periodo() {}
 };
 
-void TSaldo_periodo::update(char tcf, int gruppo, int conto, long sottoconto, bool provv, const TArray & from, const TArray & to, bool prog)
+void TSaldo_periodo::update(bool compcr, char tcf, int gruppo, int conto, long sottoconto, bool provv, const TArray & from, const TArray & to, bool prog)
 {
 	TSaldo_ricl sal;
 	const int nper = from.items();
@@ -221,7 +221,7 @@ void TSaldo_periodo::update(char tcf, int gruppo, int conto, long sottoconto, bo
 				const long sottocontocli = clifo.get_long(CLI_CODCF);
 				real si[255], pa[255], pd[255], sf[255];
 
-				sal.saldo_periodo(gruppo, conto, sottocontocli, from, to, provv);
+				sal.saldo_periodo(compcr, gruppo, conto, sottocontocli, from, to, provv);
 				real sld = sal.saldoini();
 
 				_movimentato |= sal.movimentato();
@@ -341,9 +341,9 @@ TSaldo_periodo::TSaldo_periodo(int items)
 	_movimentato = false;
 }
 
-TSaldo_periodo::TSaldo_periodo(char tcf, int gruppo, int conto, long sottoconto, bool provv, const TArray & from, const TArray & to, bool prog)
+TSaldo_periodo::TSaldo_periodo(compcr, char tcf, int gruppo, int conto, long sottoconto, bool provv, const TArray & from, const TArray & to, bool prog)
 {
-	update(tcf, gruppo, conto, sottoconto, provv, from, to, prog);
+	update(compcr, tcf, gruppo, conto, sottoconto, provv, from, to, prog);
 	_movimentato = false;
 }
 
diff --git a/src/sv/sv1200.cpp b/src/sv/sv1200.cpp
index b69423ee4..02a63ac90 100755
--- a/src/sv/sv1200.cpp
+++ b/src/sv/sv1200.cpp
@@ -1,3 +1,4 @@
+#include 
 #include 
 #include 
 #include 
@@ -19,7 +20,10 @@
 #include "../mg/mglib.h"
 #include "../mg/umart.h"
 #include "../pr/agenti.h"
-#include "../ve/clifor.h"
+
+#ifndef __CGLIB_H
+#include "../cg/cglib.h"
+#endif
 
 #define  STR_TOTGEN   "T"
 #define  STR_TIPODOC  "D"
@@ -365,22 +369,28 @@ TDate TFrequenza_colonne::column_last_day(int n) const
   return d;
 }
 
+
 ///////////////////////////////////////////////////////////
 // Stampa statistiche
 ///////////////////////////////////////////////////////////
+enum { MAX_ROWS = 8 }; // numero massimo di raggruppamenti
+
+class TSel_mask;
+class TPrint_mask;
 
 class TStampa_stat : public TPrint_application
 {
-  enum { MAX_ROWS = 8 }; // numero massimo di raggruppamenti
 
-  enum { LINEA_DATI='D', LINEA_RAFFRONTI='R', LINEA_TARGET='T'}; // codici per le righe
-  
-  TMask * _msk, *_print_msk,*_export_msk;
+
+  enum { LINEA_DATI = 'D', LINEA_RAFFRONTI = 'R', LINEA_TARGET = 'T' }; // codici per le righe
+
+  TSel_mask * _msk;
+  TPrint_mask *_print_msk;
   TStats_agg _stats;
   TFrequenza_colonne _freq;
   TCodart_livelli* _liv_art;
   TCodgiac_livelli* _liv_giac;
-  TRecord_cache *_tipodoc,*_catven, *_umart;
+  TRecord_cache *_tipodoc, *_catven, *_umart;
 
   TToken_string _key;
   TString _last_key;
@@ -396,29 +406,29 @@ class TStampa_stat : public TPrint_application
   // ******************
   // costruzione file di Output
   TStat_cache * _svcache;         // cache R/W per le statistiche
-  
+
   int         _last_lev_grp,    // livello dell'ultimo raggruppamento incontrato
-              _liv_riga;        // livello della riga
+    _liv_riga;        // livello della riga
   TArray      _group_recs;      // array dei record dei raggruppamenti
   TArray      _group_recs_raff;      // array dei record dei raggruppamenti (raffronti)
   int         _indent[MAX_ROWS];// array delle posizione di indentazione
   real        _totval_riga[SVS_NUMCOLONNE]; //array dei totali degli "anni" della riga
   real        _totqta_riga[SVS_NUMCOLONNE]; //array dei totali degli "anni" della riga
-  
+
   int       _colpage,    // numero di pagina ripetuta per contenere in larghezza tutte le colonne
-            _last_page;   // ultima pagina della "prima copia"
+    _last_page;   // ultima pagina della "prima copia"
   int _larg[7];
   int _largcol,        // larghezza di una colonna
-      _numcol_dati,         // numero di colonne contenenti dati
-      _numcol,         // numero totale di colonne (dati+totali)
-      _pagewidth,      // larghezza di una pagina
-      _col_anno ;      // numero di colonne che formano un "Anno" (=periodo di rif.)
+    _numcol_dati,         // numero di colonne contenenti dati
+    _numcol,         // numero totale di colonne (dati+totali)
+    _pagewidth,      // larghezza di una pagina
+    _col_anno;      // numero di colonne che formano un "Anno" (=periodo di rif.)
   bool _st_totr;       // flag stampa totali di riga
   bool _st_totc;       // flag stampa totali di colonna
   bool _st_tota;       // flag stampa totali di "anno"
   bool _st_val;        // Stampa valori   
   bool _st_qta;        // Stampa quantita'
-	bool _st_um;				 // Stampa UM
+  bool _st_um;				 // Stampa UM
   bool _st_uni;        // Stampa valori/quantita'
   TString16 _valid_types;// Stringa contenente i tipi di riga da stampare
   // ******************
@@ -427,40 +437,27 @@ class TStampa_stat : public TPrint_application
   TRelation * _rel;     // relazione per la stampa
 private:
 
-  
-  void put_column(TRectype & statrec,int col, const TSVriep_record& curr);
-	const real fc_um(const TRectype& statrec,const TSVriep_record& rieprec);
-	void invalid_columns(TRectype & statrec);
-  void standardize_um(TSVriep_record& rieprec, bool force=FALSE);
+
+  void put_column(TRectype & statrec, int col, const TSVriep_record& curr);
+  const real fc_um(const TRectype& statrec, const TSVriep_record& rieprec);
+  void invalid_columns(TRectype & statrec);
+  void standardize_um(TSVriep_record& rieprec, bool force = FALSE);
 
   // generazione del file di output
   void set_ragg_per_um();
   bool filtro_chiavi(TSVriep_record &curr);
-  void update_file(const char * key, const char * code,const char tipo, const int level, const int col, TSVriep_record& curr, const TString & fld, int row);
+  void update_file(const char * key, const char * code, const char tipo, const int level, const int col, TSVriep_record& curr, const TString & fld, int row);
   void genera_file(const char *outfn);
 
-  // handler per i campi di maschera
   static bool chiave_notify(TSheet_field& f, int r, KEY k);
-  static bool chiave_handler(TMask_field& f, KEY k);
-  static bool campo_handler(TMask_field& f, KEY k);
-  static bool artfld_handler(TMask_field& f, KEY k);
 
-  static bool filename_handler(TMask_field& f, KEY k);
-  static bool codice_handler(TMask_field& f, KEY k);
-  static bool multiplo_handler(TMask_field& f, KEY k);
-  static bool numero_handler(TMask_field& f, KEY k);
-  static bool periodo_handler(TMask_field& f, KEY k);
-  static bool dataini_handler(TMask_field& f, KEY k);
-  static bool datafin_handler(TMask_field& f, KEY k);
-  static bool raffronto_handler(TMask_field& f, KEY k);
-  static bool dataraf_handler(TMask_field& f, KEY k);
 protected:
   virtual bool user_create();
   virtual bool user_destroy();
   virtual bool set_print(int i);
   virtual void set_page(int file, int count);
 
-  virtual bool preprocess_print(int file, int counter) ;
+  virtual bool preprocess_print(int file, int counter);
   virtual print_action postprocess_print(int file, int counter);
   virtual bool preprocess_page(int file, int counter);
   virtual print_action postprocess_page(int file, int counter);
@@ -470,20 +467,16 @@ protected:
   virtual void on_config_change();
 
   void set_descr(int& row);
-  int handle_levchange(int row,const int level);
+  int handle_levchange(int row, const int level);
   int set_rows_colonne(int row, const TRectype &strec);
-  void set_row_atpos(char section,int row,const char * f,int pos);
-  void set_filled_row(char section,int row,char c,int pos, int len);
+  void set_row_atpos(char section, int row, const char * f, int pos);
+  void set_filled_row(char section, int row, char c, int pos, int len);
   void reset_grplevels();
-  
-  bool test_field(const TString& cod, TMask_field& f) const;
 
   void set_printmask();
 
   void fill_field_list(TMask& m);
   void set_frequency();
-  bool set_column_frequency();
-  bool recalc_period();
 
   TString& build_key(const TRectype& rec);
 
@@ -494,17 +487,340 @@ protected:
   const TString& get_part(TString & lev_code, TSVriep_record & rieprec, const TString & fld); // const;
   const TString& get_descrpart(const char *lev_code, TSVriep_record &rieprec, const TString & fld, int row);
   void adjust_record(TRectype &strec, int from) const;
-  int numlevels() const { return selmask().sfield(F_CHIAVE).items(); }
 
 public:
-  TMask& selmask() const { return *_msk; }
-  TMask& printmask() const { return *_print_msk; }
-  TMask& expmask() const { return *_export_msk; }
+  TFrequenza_colonne frequenza_colonne() { return _freq; }
+  bool set_column_frequency();
+  bool recalc_period();
+  bool test_field(const TString& cod, TMask_field& f) const;
+
+  TSel_mask& selmask() const { return *_msk; }
+  TPrint_mask& printmask() const { return *_print_msk; }
   virtual bool menu(MENU_TAG);
 };
 
 inline TStampa_stat& app() { return (TStampa_stat&)main_app(); }
 
+///////////////////////////////////////////////////////////
+// Maschera di selezione
+///////////////////////////////////////////////////////////
+
+class TSel_mask : public TAutomask
+{
+  TString _last_iso;
+  short _stato, _check, _cin, _abi, _cab, _conto, _iban, _bban, _desban;
+  int _pres;
+
+protected:
+  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
+  bool on_sheet_event(TOperable_field& o, TField_event e, long jolly);
+
+public:
+  int numlevels() const { return sfield(F_CHIAVE).items(); }
+
+  TSel_mask() : TAutomask("sv1200a") {}
+};
+
+bool TSel_mask::on_sheet_event(TOperable_field& o, TField_event e, long jolly)
+{
+  switch (o.dlg())
+  {
+    case S_CAMPO :
+      if (e == fe_modify)
+      {
+        const TString val = o.get();
+        const bool is_fld = val == STR_ARTFIELD || val == STR_CLIFIELD;
+
+        if (!is_fld)
+          reset(S_ARTFLD);
+        field(S_ARTFLD).check_type(is_fld ? CHECK_REQUIRED : CHECK_NONE);
+        enable(S_ARTFLD, is_fld);
+        return app().test_field(val, o);
+      }
+      break;
+    case S_ARTFLD:
+      if (e == fe_modify || e == fe_close)
+      {
+        if (!o.empty())
+        {
+          const bool is_anamag = get(S_CAMPO) == "B";
+          const TRectype rec(is_anamag ? LF_ANAMAG : LF_CLIFO);
+          TString16 field = o.get();
+          int pos = field.find('[');
+
+          if (pos > 0)
+            field.cut(pos);
+          if (!rec.exist(field))
+            return error_box(FR("Il campo '%s' non esiste."), (const char*)field);
+        }
+      }
+      else
+        if (e == fe_button)
+        {
+          const bool is_anamag =get(S_CAMPO) == "B";
+          TRelation rel(is_anamag ? LF_ANAMAG : LF_CLIFO);
+          TRelation_description rd(rel);
+          TString16 field = o.get();
+
+          if (rd.choose_field(field))
+            o.set(rd.field_name());
+        }
+    break;
+    default:
+    break;
+  }
+  return true;
+}
+
+bool TSel_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
+{
+  switch (o.dlg())
+  {
+    case F_CODICE :
+      if (e == fe_modify)
+      {
+        if (app().set_column_frequency())
+        {
+          int col = get_int(F_RAFFRONTO);
+          if (col > 0)
+          {
+            TDate data = app().frequenza_colonne().column_first_day(-col);
+            set(F_DATARAF, data);
+          }
+        }
+
+        // Record corrente della tabella statistiche
+        const TRectype& rec = ((TEdit_field&)o).browse()->cursor()->curr();
+
+        TSheet_field& sheet = sfield(F_CHIAVE);
+        sheet.destroy();
+
+        TToken_string s1 = rec.get("S1");
+        TToken_string s2 = rec.get("S2");
+        TToken_string s4 = rec.get("S4");
+        TString s5 = rec.get("S5");
+
+        if (s4.not_empty())
+          if (s4[s4.len() - 1] == '|' && s5[0] == '|') s4 << " ";
+        s4 << s5;
+
+        int r = 0;
+        for (const char* cod = s1.get(0); cod; cod = s1.get(), r++)
+        {
+          TToken_string& row = sheet.row(r);
+          row = cod;
+          cod = s2.get(r);
+          row.add(cod);
+          row.add("");
+          row.add("");
+          row.add("");
+          cod = s4.get(r);
+          row.add(cod);
+          sheet.check_row(r);
+        }
+        sheet.force_update();
+      }
+      break;
+    case F_MULTIPLO :
+      if (e == fe_modify || e == fe_close)
+      {
+        TFrequenza_statistiche base = char2frequency(get(F_FREQUENZA)[0]);
+        TFrequenza_statistiche freq = char2frequency(o.get()[0]);
+
+        if (base == freq)
+          enable(F_NUMERO);
+        else
+        {
+          int n = divide(freq, base);
+          set(F_NUMERO, n);
+          disable(F_NUMERO);
+        }
+        // setta la durata dell'anno
+        set(F_COL_ANNO, last_period(1992, freq));
+        app().recalc_period();
+      }
+      break;
+    case F_NUMERO : 
+    case F_DATAFIN :
+      if (e == fe_modify)
+        app().recalc_period();
+      break;
+      case F_PERIODO : 
+        if (e == fe_modify)
+        {
+          int col = o.get_int();
+
+          if (col > 0 && col <= 36)
+          {
+            if (app().set_column_frequency())
+            {
+              TDate d = app().frequenza_colonne().column_last_day(col - 1);
+
+              set(F_DATAFIN, d);
+            }
+          }
+        }
+      break;
+      case F_DATAINI :
+        if (e == fe_modify)
+        {
+          TDate data = o.get_date();
+          const TFrequenza_statistiche base = char2frequency(get(F_FREQUENZA)[0]);
+          const TFrequenza_statistiche freq = char2frequency(get(F_MULTIPLO)[0]);
+
+          floor(data, freq);
+          o.set(data);
+          app().recalc_period();
+        }
+      break;
+    case F_RAFFRONTO :
+      if (e == fe_modify)
+      {
+        if (app().set_column_frequency())
+        {
+          const int col = o.get_int();
+          if (col > 0)
+          {
+            TDate data = app().frequenza_colonne().column_first_day(-col);
+            
+            set(F_DATARAF, data);
+          }
+          else
+            reset(F_DATARAF);
+        }
+      }
+      break;
+    case F_DATARAF : 
+      if (e == fe_modify)
+      {
+        TDate data = o.get_date();
+
+        if (data.ok())
+        {
+          if (app().set_column_frequency())
+          {
+            int col = app().frequenza_colonne().date2column(data);
+            if (col < 0)
+            {
+              set(F_RAFFRONTO, -col);
+              data = app().frequenza_colonne().column_first_day(col);
+              o.set(data);
+            }
+            else
+              data = botime;
+          }
+        }
+        if (!data.ok())
+          reset(F_RAFFRONTO);
+      }
+      break;
+    case F_CHIAVE :
+      if (e == fe_close)
+      {
+        TSheet_field& sheet = (TSheet_field&)o;
+        TToken_string used;
+        TString16 campo;
+
+        for (int r = 0; r < sheet.items(); r++)
+        {
+          TToken_string& row = sheet.row(r);
+
+          campo = row.get(0);
+
+          if (campo.blank())
+            continue;
+
+          if (!app().test_field(campo, o))
+            return false;
+
+          bool found = used.get_pos(campo) >= 0;
+
+          if (!found && (campo[0] == CHR_ARTICOLO || campo[0] == CHR_LIVGIAC))
+          {
+            const char str[2] = { campo[0], '\0' };
+
+            found = used.get_pos(str) >= 0;
+          }
+
+          if (campo[0] != CHR_ARTFIELD && found)
+          {
+            return error_box(FR("Il codice %s inserito alla riga %d e' gia'\n"
+              "utilizzato in una riga precedente."),
+              (const char*)campo, r + 1);
+          }
+          else
+            used.add(campo);
+        }
+      }
+      else
+      {
+        TSheet_field& sheet = (TSheet_field&)o;
+
+        if (e == se_query_add)
+        {
+          if (sheet.items() >= MAX_ROWS)
+            return false;
+        }
+        else
+          if (e == se_notify_add)
+          {
+            sheet.set_row_cell(S_SELECT, true, jolly);
+          }
+          else
+            if (e == se_leave)
+            {
+              const int maxr = sheet.items();
+              // elimina il flag calcolo totali
+              if (jolly < maxr)
+              {
+                if (sheet.get_bool_row_cell(jolly, S_SELECT))
+                {
+                  // posso tenere abilitato il totale?
+                  if (jolly > 0 && sheet.get_bool_row_cell(jolly, S_SELECT))
+                  {
+                    sheet.set_row_cell(S_SELECT, false, jolly);
+                    sheet.force_update(jolly);
+                  }
+                }
+                else
+                {
+                  // disabilito i totale seguenti
+                  for (jolly++; jolly < maxr; jolly++)
+                    if (sheet.get_bool_row_cell(jolly, S_SELECT))
+                    {
+                      sheet.set_row_cell(S_SELECT, false, jolly);
+                      sheet.force_update(jolly);
+                    }
+                }
+              }
+            }
+      }
+      break;
+      default:
+        if (jolly > 0)
+          return on_sheet_event(o, e, jolly);
+      break;
+  }
+  return true;
+}
+
+///////////////////////////////////////////////////////////
+// Maschera di stampa
+///////////////////////////////////////////////////////////
+
+class TPrint_mask : public TAutomask
+{
+  TString _last_iso;
+  short _stato, _check, _cin, _abi, _cab, _conto, _iban, _bban, _desban;
+  int _pres;
+
+protected:
+  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly) { return true; }
+
+public:
+  TPrint_mask() : TAutomask("sv1200b") {}
+};
+
 print_action TStampa_stat::postprocess_print(int file, int count)
 {
   reset_footer();
@@ -525,7 +841,6 @@ print_action TStampa_stat::postprocess_page(int file, int count)
   return TPrint_application::postprocess_page(file,count);
 }
 
-
 bool TStampa_stat::set_print(int i)
 { 
   if (printmask().run() == K_QUIT)
@@ -889,7 +1204,7 @@ void TStampa_stat::set_descr(int& row)
   TRectype& strec = current_cursor()->curr();
   TParagraph_string descr("",MAX_DESC_LEN); // Spezzatura manuale, per evitare righe accavallate
   TString r(255);
-  const int lastlev = numlevels();
+  const int lastlev = selmask().numlevels();
   const int level = strec.get_int(SVS_LIVELLO);
   int lencode = 0;
 
@@ -934,7 +1249,7 @@ void TStampa_stat::set_page(int file, int count)
   // prepara la pagina di stampa 
   TRectype& strec = current_cursor()->curr();
   const int level = strec.get_int(SVS_LIVELLO);
-  const int lastlev = numlevels();
+  const int lastlev = selmask().numlevels();
 
   int row=0;
   
@@ -1001,7 +1316,7 @@ void TStampa_stat::set_page(int file, int count)
   // totale generale e break di livello
   if (current_cursor()->pos() == current_cursor()->items()-1)
   {
-    handle_levchange(row, numlevels());
+    handle_levchange(row, selmask().numlevels());
   }
 }
 
@@ -1159,7 +1474,7 @@ int TStampa_stat::set_rows_colonne(int row, const TRectype &strec)
         // riga con i totali di colonna
         if (_st_totc && aggiungi_perc ) 
         {
-          TRectype & _rec_totale=(TRectype &)_group_recs[numlevels()];
+          TRectype & _rec_totale=(TRectype &)_group_recs[selmask().numlevels()];
           const real tot = _rec_totale.get_real(colname);
           if (!tot.is_zero())
           { 
@@ -1251,8 +1566,8 @@ int TStampa_stat::handle_levchange(int row, const int level)
   {
     // ho lasciato un livello "basso"
     _last_lev_grp++;
-    if (_last_lev_grp > _liv_riga && printmask().get_bool(F_FLAGSTOTALI+numlevels()-_last_lev_grp)
-        || _last_lev_grp==numlevels())
+    if (_last_lev_grp > _liv_riga && printmask().get_bool(F_FLAGSTOTALI+ selmask().numlevels()-_last_lev_grp)
+        || _last_lev_grp==selmask().numlevels())
     {  
       if (_group_recs.objptr(_last_lev_grp) == NULL)
       {
@@ -1262,7 +1577,7 @@ int TStampa_stat::handle_levchange(int row, const int level)
       {
         TRectype& rec_grp1=(TRectype &)_group_recs[_last_lev_grp];
         int lencode=0;
-        if (_last_lev_grp < numlevels())
+        if (_last_lev_grp < selmask().numlevels())
         {
           TRectype & rec_grp2=(TRectype &)_group_recs[_last_lev_grp+1];
           lencode=rec_grp2.get(SVS_CODICE).len();
@@ -1271,7 +1586,7 @@ int TStampa_stat::handle_levchange(int row, const int level)
   
         set_filled_row('R',++row,'_',POS_PRIMACOL,_largcol * _numcol );
         
-        partkey_name(rec_grp1.get(SVS_LEVCODE), numlevels() - _last_lev_grp - 1, _wrk_row);
+        partkey_name(rec_grp1.get(SVS_LEVCODE), selmask().numlevels() - _last_lev_grp - 1, _wrk_row);
         _wrk_row.insert(FR("@bTotale "), 0);
 
         _wrk_row << ' ' << rec_grp1.get(SVS_CODICE).mid(lencode);
@@ -1300,7 +1615,7 @@ int TStampa_stat::handle_levchange(int row, const int level)
 
 void TStampa_stat::reset_grplevels()
 {
-  _last_lev_grp = numlevels();    
+  _last_lev_grp = selmask().numlevels();    
   _liv_riga = _last_lev_grp+1;
   _group_recs.destroy();
   _group_recs_raff.destroy();
@@ -1339,24 +1654,9 @@ bool TStampa_stat::user_create()
 
   // ************
   // maschere
-  _msk = new TMask("sv1200a");                  
-  _msk->set_handler(F_CODICE, codice_handler);
-  _msk->set_handler(F_MULTIPLO, multiplo_handler);
-  _msk->set_handler(F_NUMERO, numero_handler);
-  _msk->set_handler(F_PERIODO, periodo_handler);
-  _msk->set_handler(F_DATAINI, dataini_handler);
-  _msk->set_handler(F_DATAFIN, datafin_handler);
-  _msk->set_handler(F_RAFFRONTO, raffronto_handler);
-  _msk->set_handler(F_DATARAF, dataraf_handler);
-  _msk->set_handler(F_CHIAVE, chiave_handler);  
-  TMask& sm = _msk->sfield(F_CHIAVE).sheet_mask();
-  sm.set_handler(S_CAMPO, campo_handler);
-  sm.set_handler(S_ARTFLD, artfld_handler);  
+  _msk = new TSel_mask;                  
+  _print_msk  = new TPrint_mask;
 
-  _print_msk  = new TMask("sv1200b");
-
-  _export_msk = new TMask("sv1200c");
-  _export_msk->set_handler(F_FILENAME, filename_handler);
   // ************
   // oggetti per la gestione delle parti del codice
   _liv_art = new TCodart_livelli;
@@ -1389,7 +1689,6 @@ bool TStampa_stat::user_destroy()
   // maschere
   delete _msk;
   delete _print_msk;
-  delete _export_msk;
   // livelli di codice
   delete _liv_art;
   delete _liv_giac;          
@@ -1479,31 +1778,16 @@ bool TStampa_stat::menu(MENU_TAG )
       }
     }
     
-    if (k == K_SAVE)
-    {
-      set_ragg_per_um();
-      TTable psv("PSV");
-      psv.put("CODTAB", m.get(F_CODICE));
-      if (psv.read() == NOERR)
-        expmask().set(F_FILENAME, psv.get("S3")); // File precaricato da PSV->S3
-      if (expmask().run()!=K_ESC)
-      {
-        TFilename fname(expmask().get(F_FILENAME));
-        fname.insert("%");
-        genera_file(fname);
-      }
-    } else {
-      TFilename fname("svs");
-      genera_file(fname);
-      TIsamtempfile * f = new TIsamtempfile(LF_SVSTAT,fname,FALSE,TRUE);
-      set_printmask();
-      current_cursor()->relation()->replace(f);
-      // Forza la ricostruzione del cursore...
-      current_cursor()->setfilter("CODICE>=\"A\"");
-      current_cursor()->setfilter("");
-      do_print(1);
-      current_cursor()->relation()->replace(new TLocalisamfile(LF_SVSTAT));
-    }
+    TFilename fname("svs");
+    genera_file(fname);
+    TIsamtempfile * f = new TIsamtempfile(LF_SVSTAT,fname,FALSE,TRUE);
+    set_printmask();
+    current_cursor()->relation()->replace(f);
+    // Forza la ricostruzione del cursore...
+    current_cursor()->setfilter("CODICE>=\"A\"");
+    current_cursor()->setfilter("");
+    do_print(1);
+    current_cursor()->relation()->replace(new TLocalisamfile(LF_SVSTAT));
   } 
   return FALSE;
 }
@@ -2416,234 +2700,6 @@ bool TStampa_stat::recalc_period()
   return ok;
 }
 
-bool TStampa_stat::multiplo_handler(TMask_field& f, KEY k)
-{   
-  bool ok = TRUE;
-  TMask& m = f.mask();         
-  if (k == K_SPACE || k == K_ENTER)
-  {
-    TFrequenza_statistiche base = char2frequency(m.get(F_FREQUENZA)[0]);
-    TFrequenza_statistiche freq = char2frequency(f.get()[0]);
-    if (base == freq)
-    {
-      m.enable(F_NUMERO);
-    }  
-    else
-    {            
-      int n = divide(freq, base);
-      m.set(F_NUMERO, n);
-      m.disable(F_NUMERO);
-    }  
-    // setta la durata dell'anno
-    m.set(F_COL_ANNO, last_period(1992,freq)); 
-    app().recalc_period();
-  }
-  return ok;
-} 
-
-bool TStampa_stat::numero_handler(TMask_field& f, KEY k)
-{                
-  bool ok = TRUE;
-  if (f.to_check(k))
-    app().recalc_period();
-  return ok;  
-}
-
-bool TStampa_stat::periodo_handler(TMask_field& f, KEY k)
-{    
-  bool ok = TRUE;
-  if (f.to_check(k))
-  {
-    int col = atoi(f.get());
-    if (col > 0 && col <= 36)
-    {
-      if (app().set_column_frequency())
-      {
-        TDate d = app()._freq.column_last_day(col-1);
-        f.mask().set(F_DATAFIN, d);
-      }
-    }
-  }
-  return ok;
-}
-
-bool TStampa_stat::dataini_handler(TMask_field& f, KEY k)
-{           
-  bool ok = TRUE;
-  if (k == K_TAB && f.focusdirty())
-  {       
-    TMask& m = f.mask();
-    TDate data(f.get());             
-    const TFrequenza_statistiche base = char2frequency(m.get(F_FREQUENZA)[0]);
-    const TFrequenza_statistiche freq = char2frequency(m.get(F_MULTIPLO)[0]);
-    // floor(data, divide(freq, base) == 0 ? freq : base); // perche'?
-    floor(data, freq);
-    f.set(data.string());
-    app().recalc_period();
-  }
-  return ok;
-}
-
-bool TStampa_stat::datafin_handler(TMask_field& f, KEY k)
-{           
-  bool ok = TRUE;
-  if (k == K_TAB && f.focusdirty())
-  {   
-    app().recalc_period();
-  }
-  return ok;
-}
-
-bool TStampa_stat::raffronto_handler(TMask_field& f, KEY k)
-{
-  if (f.to_check(k))
-  {
-    if (app().set_column_frequency())
-    {   
-      const int col = atoi(f.get());
-      if (col > 0)
-      {
-        TDate data = app()._freq.column_first_day(-col);
-        f.mask().set(F_DATARAF, data);
-      }
-      else
-        f.mask().reset(F_DATARAF);
-    }
-  }
-  return TRUE;
-}
-
-bool TStampa_stat::dataraf_handler(TMask_field& f, KEY k)
-{
-  if (f.to_check(k))
-  {       
-    TMask& m = f.mask();
-    TDate data(f.get());             
-    if (data.ok())
-    {            
-      if (app().set_column_frequency())
-      {
-        int col = app()._freq.date2column(data);
-        if (col < 0) 
-        {
-          m.set(F_RAFFRONTO, -col);
-          data = app()._freq.column_first_day(col);
-          f.set(data.string());
-        }  
-        else
-          data = botime;
-      }  
-    }
-    if (!data.ok())
-      m.reset(F_RAFFRONTO);
-  }
-  return TRUE;
-}
-
-bool TStampa_stat::codice_handler(TMask_field& f, KEY k)
-{
-  if (k == K_TAB && f.focusdirty())
-  {    
-    TMask& m = f.mask();
-    
-    if (app().set_column_frequency())
-    {
-      int col = m.get_int(F_RAFFRONTO);
-      if (col > 0)
-      {
-        TDate data = app()._freq.column_first_day(-col);
-        m.set(F_DATARAF, data);
-      }
-    }
-    
-    // Record corrente della tabella statistiche
-    const TRectype& rec = ((TEdit_field&)f).browse()->cursor()->curr();
-  
-    TSheet_field& sheet = m.sfield(F_CHIAVE);
-    sheet.destroy();
-    
-    TToken_string s1 = rec.get("S1");
-    TToken_string s2 = rec.get("S2");
-    TToken_string s4 = rec.get("S4");
-    TString s5 = rec.get("S5");
-  
-    if (s4.not_empty())
-      if (s4[s4.len() - 1] == '|' && s5[0] == '|') s4 << " ";
-    s4 <0 && *s.row(r-1).get(1)==' ')
-        {
-          s.row(r).add(" ",1);
-          s.force_update(r);
-        }
-      } else {
-        // disabilito i totale seguenti
-        for (r++;r < maxr; r++)
-          if (*s.row(r).get(1)!=' ')
-          {
-            s.row(r).add(" ",1);
-            s.force_update(r);
-          }
-      }
-    }
-  }
-    
-  return ok;
-}
-
 bool TStampa_stat::test_field(const TString& cod, TMask_field& f) const
 { 
   bool ok = TRUE;
@@ -2652,122 +2708,36 @@ bool TStampa_stat::test_field(const TString& cod, TMask_field& f) const
   {              
   case CHR_ARTICOLO: 
     if (cod[1] != '\0' && !_liv_art->enabled())
-      ok = f.error_box(TR("I livelli di codice articolo non sono abilitati"));
+     return error_box(TR("I livelli di codice articolo non sono abilitati"));
     break;  
   case CHR_LIVGIAC: 
     if (!_stats.grp_giacenza())
-      ok = f.error_box(TR("Le statistiche sono raggruppate per livello di giacenza"));
-    else if (!_liv_giac->enabled())
-      ok = f.error_box(TR("I livelli di giacenza non sono abilitati"));
+      return f.error_box(TR("Le statistiche sono raggruppate per livello di giacenza"));
+    else
+      if (!_liv_giac->enabled())
+        return error_box(TR("I livelli di giacenza non sono abilitati"));
     break;  
   case CHR_CLIFOR: 
     if (!_stats.grp_cliente())
-      ok = f.error_box(TR("Le statistiche sono raggruppate per cliente/fornitore"));
+      return error_box(TR("Le statistiche sono raggruppate per cliente/fornitore"));
     break;  
   case CHR_AGENTE: 
     if (!_stats.grp_agente())
-      ok = f.error_box(TR("Le statistiche sono raggruppate per agente"));
+      return error_box(TR("Le statistiche sono raggruppate per agente"));
     break;  
   case CHR_MAGAZZ: 
     if (!_stats.grp_magazzino())
-      ok = f.error_box(TR("Le statistiche sono raggruppate per magazzino"));
+      return error_box(TR("Le statistiche sono raggruppate per magazzino"));
     break;  
   case CHR_ZONA: 
     if (!_stats.grp_zona())
-      ok = f.error_box(TR("Le statistiche sono raggruppate per zona"));
+      return error_box(TR("Le statistiche sono raggruppate per zona"));
     break;  
   default : break;
   }
   return ok;
 }
 
-bool TStampa_stat::chiave_handler(TMask_field& f, KEY k)
-{       
-  bool ok = TRUE;
-  if (k == K_ENTER)
-  {              
-    TSheet_field& sheet = (TSheet_field&)f;
-    TToken_string used;
-    TString16 campo;
-    for (int r = 0; r < sheet.items(); r++)
-    {
-      TToken_string& row = sheet.row(r);
-      campo = row.get(0);
-      
-      if (campo.blank())
-        continue;
-      
-      ok = app().test_field(campo, f);
-      
-      bool found = used.get_pos(campo) >= 0;
-      if (!found && (campo[0] == CHR_ARTICOLO || campo[0] == CHR_LIVGIAC))
-      {
-        const char str[2] = { campo[0], '\0' };
-        found = used.get_pos(str) >= 0;
-      }
-      
-      if (campo[0] != CHR_ARTFIELD && found)
-      {       
-        ok = error_box(FR("Il codice %s inserito alla riga %d e' gia'\n"
-                       "utilizzato in una riga precedente."),
-                       (const char*)campo, r+1);
-      }
-      else
-        used.add(campo);
-    }
-  }
-  return ok;
-}
-
-bool TStampa_stat::campo_handler(TMask_field& f, KEY k)
-{  
-  if (f.to_check(k, TRUE))            
-  {         
-    const bool is_fld = f.get()== STR_ARTFIELD || f.get()== STR_CLIFIELD;
-    
-    if (!is_fld)
-      f.mask().reset(S_ARTFLD);
-    f.mask().field(S_ARTFLD).check_type(is_fld ? CHECK_REQUIRED : CHECK_NONE);
-    f.mask().enable(S_ARTFLD, is_fld);
-    return app().test_field(f.get(), f);
-  }
-  return TRUE;
-}  
-
-bool TStampa_stat::artfld_handler(TMask_field& f, KEY k)
-{                 
-  bool ok = TRUE;      
-  switch (k)
-  {       
-    case K_TAB:
-    case K_ENTER:
-      if (!f.empty() && f.to_check(k))
-      {
-        const bool is_anamag = f.mask().get(S_CAMPO) == "B";
-        const TRectype rec(is_anamag ? LF_ANAMAG : LF_CLIFO);        
-        TString16 field = f.get();
-        int pos = field.find('[');
-        if (pos > 0)
-          field.cut(pos);
-        if (!rec.exist(field))
-          ok = f.error_box(FR("Il campo '%s' non esiste."), (const char*)field);
-      }
-      break;
-    case K_F9:
-      {                                                      
-        const bool is_anamag = f.mask().get(S_CAMPO) == "B";
-        TRelation rel(is_anamag ? LF_ANAMAG : LF_CLIFO);
-        TRelation_description rd(rel);
-        if (rd.choose_field(f.get()))
-          f.set(rd.field_name());
-      }
-      break;
-    default:
-      break;
-  }
-  return ok;
-}
-
 ///////////////////////////////////////////////////////////
 // Pseudo main
 ///////////////////////////////////////////////////////////
diff --git a/src/sv/sv1200a.h b/src/sv/sv1200a.h
index 3ba1dec09..508e738da 100755
--- a/src/sv/sv1200a.h
+++ b/src/sv/sv1200a.h
@@ -23,7 +23,7 @@
 #define F_TIPOART4       226
 #define F_STAMPA_UM			 227
 
-
+#define S_SELECT    100
 #define S_CAMPO     101
 #define S_TOTALE    102
 #define S_DAL       103
diff --git a/src/sv/sv1200a.uml b/src/sv/sv1200a.uml
index dbb4e7edc..c0afa90bc 100755
--- a/src/sv/sv1200a.uml
+++ b/src/sv/sv1200a.uml
@@ -2,12 +2,6 @@
 
 TOOLBAR "Toolbar" 0 0 0 2
 
-BUTTON DLG_SAVEREC 10 2
-BEGIN
-  PROMPT -23 -1 "~Registra"
-  PICTURE TOOL_SAVEREC
-END
-
 #include 
 
 ENDPAGE
diff --git a/src/sv/sv1200b.uml b/src/sv/sv1200b.uml
index 4a9a4e9af..e7d4a908c 100755
--- a/src/sv/sv1200b.uml
+++ b/src/sv/sv1200b.uml
@@ -2,7 +2,9 @@
 
 TOOLBAR "Toolbar" 0 0 0 2
 
-#include 
+#define EXPORT_EXCEL
+
+#include 
 
 ENDPAGE
 
diff --git a/src/sv/sv2100.cpp b/src/sv/sv2100.cpp
index f3f9ea57a..6ac0bbb7f 100755
--- a/src/sv/sv2100.cpp
+++ b/src/sv/sv2100.cpp
@@ -50,7 +50,7 @@ void TRicalcolo_stats::on_config_change()
   for (bool ok = tip.move_first(); ok; ok = tip.move_next())
   {
     if (rec_tip.get_bool("B2")) // E' un tipo per le statistiche
-      _tipi_doc.add(rec_tip.get("CODTAB"), NULL);
+      _tipi_doc.add(rec_tip.get("CODTAB"));
   }
 
   TDate datamin = TDate(TODAY); datamin.set_day(1); datamin.set_month(1);
diff --git a/src/tc/tc9100.cpp b/src/tc/tc9100.cpp
index 1fb7f9c9f..6605fb1e3 100755
--- a/src/tc/tc9100.cpp
+++ b/src/tc/tc9100.cpp
@@ -636,6 +636,7 @@ bool TInvioP::i_proforma_righe(TCursor& cur, TInvioP_file* trasfilerighe)
     const real imponibile = pn.iva(l).get_real(RMI_IMPONIBILE);
     const real imposta = pn.iva(l).get_real(RMI_IMPOSTA);
     const TString4 codind = pn.iva(l).get(RMI_TIPODET);
+
     pn.analizza_riga_IVA(imponibile, imposta, caus, anno, codiva, codind, imp_detr, 
                          iva_detr, imp_indetr, iva_indetr);
 		*tot_imp += imp_detr + imp_indetr + iva_indetr;
diff --git a/src/xi/xi.h b/src/xi/xi.h
index 72d86b6a2..798a600b2 100755
--- a/src/xi/xi.h
+++ b/src/xi/xi.h
@@ -840,6 +840,14 @@ typedef struct _xi_event
   ( objp )->v.row = row_nbr, \
   ( objp )->nbr_children = 0 )
 
+#define XI_MAKE_LIST( objp, listobj, row_nbr ) \
+  memset(( char* )objp, '\0', ( size_t )sizeof( XI_OBJ )), \
+  (( objp )->v.list = ( listobj )->parent, \
+  ( objp )->parent = listobj, \
+  ( objp )->type = XIT_LIST, \
+  ( objp )->v.row = row_nbr, \
+  ( objp )->nbr_children = 0 )
+
 #ifndef max
 #define max(A, B) ((A) > (B) ? (A) : (B))
 #endif
diff --git a/src/xvaga/xvaga.cpp b/src/xvaga/xvaga.cpp
index e57e50649..c826be031 100755
--- a/src/xvaga/xvaga.cpp
+++ b/src/xvaga/xvaga.cpp
@@ -3542,7 +3542,7 @@ long xvt_sys_execute(const char* cmdline, BOOLEAN sync, BOOLEAN iconizetask)
         delete p;
     }
     else
-      exitcode = wxExecute(cmd, wxEXEC_ASYNC /* | wxEXEC_HIDE_CONSOLE*/);
+      exitcode = wxExecute(cmd, wxEXEC_ASYNC);
   }
 
   return exitcode;
diff --git a/src/xvtdb/xvtdb.cpp b/src/xvtdb/xvtdb.cpp
index 9025866be..ac6aa2673 100644
--- a/src/xvtdb/xvtdb.cpp
+++ b/src/xvtdb/xvtdb.cpp
@@ -534,7 +534,7 @@ int TXvt_recordset::get_int(const char* field)
 {
 	try
 	{
-		return static_cast(_RCS(_recset)->Field(field).asLong());
+    return atoi(get(field));
 	}
 	catch (SAException &x)
 	{
@@ -549,7 +549,7 @@ short TXvt_recordset::get_short(const char* field)
 {
 	try
 	{
-		return _RCS(_recset)->Field(field).asShort();
+    return (short)atol(get(field));
 	}
 	catch (SAException &x)
 	{
@@ -564,7 +564,7 @@ long TXvt_recordset::get_long(const char* field)
 {
 	try
 	{
-		return _RCS(_recset)->Field(field).asLong();
+    return atol(get(field));
 	}
 	catch (SAException &x)
 	{
@@ -594,7 +594,7 @@ bool TXvt_recordset::get_bool(const char* field)
 {
 	try
 	{
-		return _RCS(_recset)->Field(field).asBool();
+    return get(field)[0] == 'T' || get(field)[0] == 'X';
 	}
 	catch (SAException &x)
 	{