Newsgroup: it.comp.lang.delphi
Titolo: Numerare una Fattura del 07/05/2003

Nell'ascoltare i diversi suggerimento che mi sono arrivati nella mia
richiesta del 07/05/03 Numerare una fattura ho seguito la seguente
soluzione:
Ho creato una Tabella di supporto con due campi : Anno, LastNumber
La mia necessità era quella di numerare le fatture come segue: 2003/01 --
2003/02 ecc ... 2004/01
Ad ogni inserimento di una nuova fattura controllo nella TabellaNumerazione
se esiste lo stesso anno della fattura che sto inserendo .... nel qual caso
incremento di 1 il valore del Campo LastNumber e lo inserisco nella campo
della fatturazione insieme all'anno.... se l'anno invece non esiste lo crea
automaticamente e inserisce come campo lastnumber a 0.
Grazie per i consigli
P.S. il codice che ho scritto non è sicuramente dei più puliti e belli -.---
quindi evito di copiarlo qui se non necessariamente richiesto.
Stefano

poichè alcuni gestiscono + serie di numerrazione diverse per fatture, ddt
etc
ti suggerisco la aggiunta di un altro campo: SERIE CHAR(1) not null
Questo campo può essere uno spazio vuoto (#32) ma non nullo.
Ove specificato, indica la serie e va stampato sul documento.
Ancora: sarebbe utile che il lavoro di "fornitura di un nuovo progressico"
fosse delegato ad una stored procedure (qualora il tuo db le prevede....)
che, accettando in input:
Anno
Serie
restituisce un nuovo progressivo nascondendo cio che viene fatto sul db per
produrlo.
Bye
A.

 produrlo.
Mi era sfuggito il thread iniziale.
In un database firebird io ho usato questa soluzione:
1 - Tabella numeratori che contiene il tipo di documento ed il numero
dell'ultimo documento generato per quel tipo documento;
2 - Un tabella di log per ogni tipo documento che contiente oltre al numero
del documento, lo stato del documento. Non è la soluzione ottimale, nel
senso che si sarebbe potuta utilizzare anche una tabella di log unica.
Lo scopo della tabella di log è quello di permettere il riutilizzo di un
numero documento che potrebbe eventualmente essere cancellato.
3 - Una stored procedure che interroga prima il file di log per verificare
eventuali numeri da riutilizzare, ed in caso non ce ne siano, incrementa la
tabella numeratori.
Per questa soluzione ho preso spunto da questo articolo
http://www.ibobjects.com/docs/ti_AuditableSeries.ZIP
Ciao,
MM

Eccovi la soluzione senza tabbelle aggiuntive o artifici;
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, DBTables, StdCtrls, Grids, DBGrids;
type
  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    Table1: TTable;
    Table1Id: TAutoIncField;
    Table1Data: TDateField;
    Table1Anno: TIntegerField;
    Table1Num: TIntegerField;
    Table1NumFatt: TStringField;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Table1CalcFields(DataSet: TDataSet);
  private
    { Private declarations }
  public
    procedure NumFatt;
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.NumFatt;
var
  N : Integer;
  Anno: TDateTime;
  Year, Month, Day: Word;
begin
  Table1.Last;
  N := Table1Num.Value;
  Anno:= Now;
  DecodeDate(Anno, Year, Month, Day);
  if Table1Anno.Value = Year then
  begin
    Table1.Insert;
    Table1Num.Value := N + 1;
    Table1Anno.Value := Year;
    Table1Data.Value := Date;
    Table1.Refresh;
  end
  else
  begin
    Table1.Insert;
    Table1Num.Value := 1;
    Table1Anno.Value := Year;
    Table1Data.Value := Date;
    Table1.Refresh;
  end
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  NumFatt;
end;
procedure TForm1.Table1CalcFields(DataSet: TDataSet);
begin
    Table1NumFatt.Value := Table1Num.AsString + '/' + Table1Anno.AsString;
end;
end.
--------------------------------
Inviato via 
http://usenet.libero.it

 Eccovi la soluzione senza tabbelle aggiuntive o artifici;
Gli artifici sono purtroppo necessari in ambiente client/server, dove può
accadere che mentre un utente sta inserendo un nuovo documento un altro
utente ne cancella uno precedentemente inserito.
La tua soluzione non gestisce questa situazione. Dal codice che hai allegato
non vedo nessuna verifica di un documento cancellato ma soltanto inserimenti
di nuovi numeri di documento.
Ciao,
MM

A livello di performance, il calcolo del nyuovo numero aumenta ad ogni
inserimento di una nuova fattura.
Avendo una tabella solo con i contatori il tempo rimane costante in quanto i
records da processare sarebbero al massimo pari a
numerodianni*numerodiserie.
Poi, non è ben chiaro cosa succede se un ipotetico utente2 legge l'ultimo
record dopo che è già stato letto da utente1 e prima che utente1 stesso
abbia il tempo si salvare il nuovo record.
Se esiste un costraint unique come è giusto che sia, probabilmente si
avrebbe una eccezione per la violazione di tale costraint al momento che
utente2 tenta di scrivere il suo record.
Infine, il codice è un po ridondante e andrebbe messo, insieme ai relativi
componenti di accesso ai dati in un data module e non su un form:
 procedure TForm1.NumFatt;
 var
   N : Integer;
   Anno: TDateTime;
   Year, Month, Day: Word;
 begin
   Table1.Last;
   N := Table1Num.Value;
   Anno:= Now;
   DecodeDate(Anno, Year, Month, Day);
   if Table1Anno.Value = Year then
   inc(n)
else
  n := 1;
     Table1.Insert;
     Table1Num.Value := N;
     Table1Anno.Value := Year;
     Table1Data.Value := Date;
     Table1.Refresh;
end;
Bye
A.

dimenticavo: risulta alquanto complesso gestire + serie numerazione.
Bye
A.

abbia il tempo si salvare il nuovo record.
Il problema della concorrenza si risolve utilizzando la tecnica descritta da
me nel thread precedente, e' cioe' utilizzando una tabella apposita, e
assegnando il numero documento al momento della scrittura, non prima.
Con questa tecnica, virtualmente, infiniti utenti possono aprire in
inserimento un documento nuovo, e fare il post nel medesimo istante: un buon
sistema di locking fornirebbe il numero di documento progressivo, senza
duplicazioni di sorta.
L'unica penalizzazione di questo mio metodo consiste nel fatto che non si
conosce il numero di documento fintanto che non viene salvato.
-- 
Morde. 
morde[at]programmer[.]net

 conosce il numero di documento fintanto che non viene salvato.
Molti gestionali lo assegnano appena si seleziona la serie numerazione per
poi eseguire un check prima del salvataggio.
Ad esempio...
L'ultimo contatore è 100.
Io propongo 101 all'utente
L'utente carica la fattura e ne richiede il salvataggio
Sul salvataggio rileggo il contatore
se è diverso da 100
  lo rileggo
  lo incremento
  aggiorno la tabella
  uso il nuovo contatore avvisando l'utente che il numero del documento è
cambiato
  end
altrimenti
  lo incremento
  aggiorno la tabella
  end
Salvo la fattura
Bye
A.

cambiato
GOOD!
ciao


 GOOD!
:)))
Bye
A