Numero fattura incrementale

giovedì 17 febbraio 2011 - 10.52
Tag Elenco Tags  C#  |  .NET 4.0  |  Windows Vista  |  Windows XP  |  Visual Studio 2010  |  Access (.mdb)  |  Chrome  |  Firefox

Romanaderoma Profilo | Newbie

ciao, sono all'inizio della programmazione in c# e vorrei un piccolo aiuto sto creando un piccolo programma che mi permette di gestire le fatture, ho piccolo database su access, mancano alcune cosette e poi è terminato.
partiamo con il primo piccolo problema.
numero fatture, ad ogni nuova fattura il numero deve aumentare e poi come posso fare affinchè con l'anno nuovo riparta da 1?
grazie x l'aiuto

boccia75 Profilo | Junior Member

Occorre che prima dell'inserimento di una nuova fattura il programma vada a testare il progressivo massimo per l'anno in corso.
Se il progressivo non esiste (è la prima fattura dell'anno) valorizzi il campo a 1, altrimenti lo valorizzi con il valore trovato +1.
Ciao.

Romanaderoma Profilo | Newbie

Grazie per la tempestiva risposta puoi farmi un esempio per favore?

e poi un altra cosa il numero fattura non lo devo inserire io ma si deve incrementare da solo quando faccio una nuova fattura

alx_81 Profilo | Guru

>Occorre che prima dell'inserimento di una nuova fattura il programma
>vada a testare il progressivo massimo per l'anno in corso.
>Se il progressivo non esiste (è la prima fattura dell'anno) valorizzi
>il campo a 1, altrimenti lo valorizzi con il valore trovato +1.
>Ciao.
Ciao a tutti, soluzione corretta logicamente. Vorrei solo porre l'attenzione su eventuali problemi di prestazioni e di concorrenza.
Una soluzione del genere comincia a scricchiolare quando le fatture diventano tante se non è stato opportunamente disegnato un indice.
Questo perchè bisogna sempre fare la MAX del contatore prima dell'inserimento e se l'insieme non è ordinato ed indicizzato si rischiano scan della tabella dall'inizio alla fine (per ricavare il massimo).
Quindi, comunque disegnare l'indice adatto sul contatore per anno ad esempio.
Secondo problema, la concorrenza. Fai attenzione al fatto che se non gestisci bene le transazioni rischi di trovarti lo stesso contatore per due fatture diverse. Immagina due utenti che inseriscono nello "stesso" tempo due fatture. Entrambi leggono la stessa MAX. Anche qui serve un constraint di univocità del contatore per anno, per fare in modo che l'ultimo che salva la fattura riceva un errore di duplicazione (magari proponendo il nuovo contatore valido).
Semplicemente, fare attenzione a questi punti

--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

boccia75 Profilo | Junior Member

Sono d'accordo con te, è stata fatta una domanda con poche precisazioni (vedi la seconda mail) è stata data una risposta con poche precisazioni.....
Ovvio che occorre inserire indici (per l'utilizzo di una max) e fare attenzione alla concorrenzialità delle operazioni ma, in fin dei conti, queste sono cose che deve considerare chi fa il progetto (anzi per me sono cose superflue, nel senso che ci devo già aver pensato prima di fare qualunque query di inserimento o selezione, non credi? )
Ciao

Romanaderoma Profilo | Newbie

volevo solo sapere a livello di codice all'indice e alla concorrenzialità ci ho già pensato

alx_81 Profilo | Guru

>Sono d'accordo con te, è stata fatta una domanda con poche precisazioni
>(vedi la seconda mail) è stata data una risposta con poche precisazioni.....
non sindacavo su domanda/risposta.. facevo solo un appunto che può tornare utile, solo questo

>Ovvio che occorre inserire indici (per l'utilizzo di una max)
non credere che lo sia , ho visto cose che voi umani.......

>(anzi per me sono cose superflue, nel senso che ci
>devo già aver pensato prima di fare qualunque query di inserimento
>o selezione, non credi? )
eh magari, purtroppo chi scrive non sempre ha in mano il requisito che si spera o che tutto sommato dovrebbe avere. Concordo che sono cose a cui pensare, ma sono del parere che consigliarle, anche se scontate, non fa mai male. In fin dei conti una domanda può nascondere insidie che nemmeno chi domanda vede a volte.. E a volte si danno per scontati dettagli che servirebbero sempre nella risposta..

>Ciao
Ciao!
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

boccia75 Profilo | Junior Member

Io farei in questo modo:
il campo ID non lo farei autoincrementale ma farei:

declare @id int
declare @id2 int
set @id=(select isnull(max(ID),0) from tabella where anno=....)
set @id2=@id+1
insert into tabella(id,.....) values (@id2.........)

Ciao

boccia75 Profilo | Junior Member

Corretto, corretto alx_81, non posso che quotarti!
Ciao!

Romanaderoma Profilo | Newbie

Concordo con te alx_81

boccia75 grazie

alx_81 Profilo | Guru

>Io farei in questo modo:
>il campo ID non lo farei autoincrementale ma farei:
>
>declare @id int
>declare @id2 int
>set @id=(select isnull(max(ID),0) from tabella where anno=....)
>set @id2=@id+1
>insert into tabella(id,.....) values (@id2.........)

mamma mia come rompo le scatole.. ma è access
quindi ricorda che per l'isnull devi usare IIF(condizione, allora, altrimenti)
e per le declare, forse ti conviene fare uno statement e farti tornare il progressivo attuale su VBA.
Poi controlli quello, se è vuoto imposti il primo progressivo dell'anno, se non lo è sommi 1.
Comunque vada lanci la procedura di inserimento via VBA usando ADO.
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

Romanaderoma Profilo | Newbie

ma a me serve in c# no in vba

alx_81 nn sei un rompiscatole grazie

alx_81 Profilo | Guru

>ma a me serve in c# no in vba
ok allora non avevo letto bene. Hai un'app in c#, sorry.
diciamo che puoi procedere così:

- inizi una transazione applicativa
- fai la query sulla tua tabella che ti torni il max
- dichiari una var int counter = 0
- tramite ExecuteScalar in ADO.Net vai a leggere il max dalla query
- se non ottieni valori (risultato null) fai solo counter++
- se leggi il max corrente invece counter diventa il maxcorrente + 1
- a questo punto inserisci passando il nuovo counter in try catch
- se va tutto ok committi la transazione (ti consiglio il TransactionScope)
- se va male fai rollback e gestisci una sqlexception

ora, di tutto questo, posso farti un esempio, ma intanto prova a dirmi dove avresti problemi.
Ciao!

--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

Romanaderoma Profilo | Newbie

>>ma a me serve in c# no in vba
>ok allora non avevo letto bene. Hai un'app in c#, sorry.
tranquillo :-)
>diciamo che puoi procedere così:
>
>- inizi una transazione applicativa
cos'è?
>- fai la query sulla tua tabella che ti torni il max
>- dichiari una var int counter = 0
>- tramite ExecuteScalar in ADO.Net vai a leggere il max dalla
>query
mi devo importare la libreria di ADO.Net?
>- se non ottieni valori (risultato null) fai solo counter++
>- se leggi il max corrente invece counter diventa il maxcorrente
>+ 1
io ho provato a fare così
private Boolean numerofatt()
Sql = "Select max (N_Fatt) from Fatture
int numerofattura;
DB.Sql = Sql;
DB.TableName = "Fatture";
numerofattura = non so cosa associare al numero fattura
return numerofattura +1;

>- a questo punto inserisci passando il nuovo counter in try catch
>- se va tutto ok committi la transazione (ti consiglio il TransactionScope)
come si fa?
>- se va male fai rollback e gestisci una sqlexception

>ora, di tutto questo, posso farti un esempio, ma intanto prova a dirmi dove avresti problemi.
se m faresti un esempio lo preferirei

>Ciao!
Ciao e grazie

alx_81 Profilo | Guru

>>- inizi una transazione applicativa
>cos'è?
una BEGIN TRAN, che rende atomica l'operazione. Ciò significa che se hai una transazione con n istruzioni che modificano dati e strutture, e se questa fallisce, puoi decidere di tornare allo stato precedente (ROLLBACK).

>mi devo importare la libreria di ADO.Net?
in. net basta fare using System.Data, using System.Data.Oledb
poi importi System.Transactions per il TransactionScope

>se m faresti un esempio lo preferirei
eccotelo, non ho potuto provare a vedere se funziona, ma l'idea è quella. Partiamo da qui:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

Romanaderoma Profilo | Newbie

grazie ora provo e ti faccio sapere

Romanaderoma Profilo | Newbie

vorrei qualcosa di più semplice se è possibile

alx_81 Profilo | Guru

>vorrei qualcosa di più semplice se è possibile
?
sono due comandi lanciati con ado.net.. cosa intendi "più semplice"?
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

Romanaderoma Profilo | Newbie

>sono due comandi lanciati con ado.net.. cosa intendi "più semplice"?
lavoro cn le classi e trovarmi tutto insieme mi spiazzo


alx_81 Profilo | Guru

>lavoro cn le classi e trovarmi tutto insieme mi spiazzo
perdonami, non ti seguo.. lavorando in oop usiamo classi, certo.. ma questo è solo un metodo, di un'ipotetica classe fatta da te per il colloquio a database.
Se lavori a moduli, ben stratificato, avrai un livello di comunicazione verso il database, ecco, lì puoi usare questo metodo, modificato per le tue esigenze.
--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

Romanaderoma Profilo | Newbie

grazie mille mi ci sono messa l'ho scritto e pare che funziona grazie mille

alx_81 Profilo | Guru

>grazie mille mi ci sono messa l'ho scritto e pare che funziona
>grazie mille
Figurati, cerca sempre di usare i costrutti che ti ho indicato, gestiscono in automatico Dispose per le classi che implementano la IDisposable, migliorando la leggibilità del codice e facendo in modo che tu ti perda la disallocazione della memoria

Se la risposta ti è stata di aiuto, accettala così chiudiamo il thread.
un saluto!

--
Alessandro Alpi | SQL Server MVP
MCP|MCITP|MCTS|MCT

http://www.alessandroalpi.net
http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi

Romanaderoma Profilo | Newbie

>Figurati, cerca sempre di usare i costrutti che ti ho indicato,
>gestiscono in automatico Dispose per le classi che implementano
>la IDisposable, migliorando la leggibilità del codice e facendo
>in modo che tu ti perda la disallocazione della memoria
Grazie per la pazienza e la disponibilità kmq certamente li userò

>
>Se la risposta ti è stata di aiuto, accettala così chiudiamo
>il thread.
>un saluto!

un saluto anche a te!

Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5