In una contabilità di magazzino a quantità e a valori, occorre valorizzare i movimenti di magazzino e la scorta esistente. La valorizzazione dei carichi avviene al costo che può essere costo di acquisto o costo di produzione a seconda dell’origine esterna o interna dei beni. La valorizzazione degli scarichi è invece più complessa, poiché non è sempre possibile individuare con certezza la corrispondenza tra le unità entrate in magazzino e quelle uscite. Gli scarichi possono essere valorizzati al costo medio ponderato, con il metodo FIFO o LIFO. Il metodo FIFO (First In First Out) ipotizza che le materie o le merci entrate per prime (first in) siano le prime a essere prelevate dal magazzino (first out). Con questo metodo gli scarichi sono valorizzati utilizzando i prezzi delle partite acquistate per prime fino alloro esaurimento.
Consideriamo un modello elementare per valorizzare il magazzino in access, partiamo da una tabella movimenti così formata: DATA, CODICE, SEGNO, QT, COSTO (nel campo segno avremo A per gli Acquisti e V per le Vendite)
Per prima generiamo le tabelle Acquisti e venduto con le seguenti query:
SELECT MOVIMENTI.CODICE, MOVIMENTI.DATA, MOVIMENTI.QT, MOVIMENTI.COSTO, 0 AS CUM INTO Acquisto FROM MOVIMENTI WHERE (((MOVIMENTI.SEGNO)="A")) ORDER BY MOVIMENTI.CODICE, MOVIMENTI.DATA; |
SELECT MOVIMENTI.CODICE, MOVIMENTI.DATA, MOVIMENTI.QT, MOVIMENTI.COSTO, 0 AS CUM INTO Acquisto FROM MOVIMENTI WHERE (((MOVIMENTI.SEGNO)="A")) ORDER BY MOVIMENTI.CODICE, MOVIMENTI.DATA;
SELECT MOVIMENTI.CODICE, SUM(MOVIMENTI.QT) AS Q INTO venduto FROM MOVIMENTI WHERE (((MOVIMENTI.SEGNO)="V")) GROUP BY MOVIMENTI.CODICE; |
SELECT MOVIMENTI.CODICE, Sum(MOVIMENTI.QT) AS Q INTO venduto FROM MOVIMENTI WHERE (((MOVIMENTI.SEGNO)="V")) GROUP BY MOVIMENTI.CODICE;
a questo punto calcoliamo la QT cumulata degli acquisti con questa funzione:
cumulata "Acquisto", "CODICE", "QT", "CUM" Function cumulata(tabella, campocodice, campoqt, campocum) Dim db As DAO.Database Dim tabel As DAO.Recordset Dim campo As DAO.Field Dim CUM(10000) Dim CODICE(10000) Set db = CurrentDb Set tabel = db.OpenRecordset(tabella, dbOpenDynaset) Set campo = tabel.Fields(campocum) Do Until tabel.EOF C = C + 1 CODICE(C) = tabel.Fields(campocodice) QT = tabel.Fields(campoqt) If CODICE(C) <> CODICE(C - 1) Then t = 0 CUM(t) = QT Else CUM(t) = CUM(t) + QT End If tabel.Edit campo = CUM(t) tabel.Update tabel.MoveNext Loop tabel.Close db.Close End Function |
cumulata "Acquisto", "CODICE", "QT", "CUM" Function cumulata(tabella, campocodice, campoqt, campocum) Dim db As DAO.Database Dim tabel As DAO.Recordset Dim campo As DAO.Field Dim CUM(10000) Dim CODICE(10000) Set db = CurrentDb Set tabel = db.OpenRecordset(tabella, dbOpenDynaset) Set campo = tabel.Fields(campocum) Do Until tabel.EOF C = C + 1 CODICE(C) = tabel.Fields(campocodice) QT = tabel.Fields(campoqt) If CODICE(C) <> CODICE(C - 1) Then t = 0 CUM(t) = QT Else CUM(t) = CUM(t) + QT End If tabel.Edit campo = CUM(t) tabel.Update tabel.MoveNext Loop tabel.Close db.Close End Function
A questo punto generiamo la tabella giacenze in cui andiamo ad individuare con una funzione successiva la QT residua dal valorizzare.
SELECT Acquisto.CODICE, Acquisto.DATA, Acquisto.CUM, venduto.Q, Acquisto.COSTO, Acquisto.QT, [CUM]-[Q] AS D, 0 AS QDV INTO giacenze FROM Acquisto INNER JOIN venduto ON Acquisto.CODICE = venduto.CODICE ORDER BY Acquisto.CODICE, Acquisto.DATA; |
SELECT Acquisto.CODICE, Acquisto.DATA, Acquisto.CUM, venduto.Q, Acquisto.COSTO, Acquisto.QT, [CUM]-[Q] AS D, 0 AS QDV INTO giacenze FROM Acquisto INNER JOIN venduto ON Acquisto.CODICE = venduto.CODICE ORDER BY Acquisto.CODICE, Acquisto.DATA;
Function QTVAL() Dim db As DAO.Database Dim tabella As DAO.Recordset Dim campo As DAO.Field Dim D(10000) Dim CODICE(10000) Set db = CurrentDb Set tabella = db.OpenRecordset("giacenze", dbOpenDynaset) Set campo = tabella.Fields("QDV") Do Until tabella.EOF C = C + 1 CODICE(C) = tabella.Fields("CODICE") D(C) = tabella.Fields("D") Q = tabella.Fields("QT") If CODICE(C) <> CODICE(C - 1) Then If D(C) >= 0 Then QDV = Q Else QDV = 0 Else If D(C) > 0 Then QDV = 0 Else If D(C - 1) > 0 Then QDV = D(C) Else QDV = Q End If End If tabella.Edit campo = QDV tabella.Update tabella.MoveNext Loop tabella.Close db.Close End Function |
Function QTVAL() Dim db As DAO.Database Dim tabella As DAO.Recordset Dim campo As DAO.Field Dim D(10000) Dim CODICE(10000) Set db = CurrentDb Set tabella = db.OpenRecordset("giacenze", dbOpenDynaset) Set campo = tabella.Fields("QDV") Do Until tabella.EOF C = C + 1 CODICE(C) = tabella.Fields("CODICE") D(C) = tabella.Fields("D") Q = tabella.Fields("QT") If CODICE(C) <> CODICE(C - 1) Then If D(C) >= 0 Then QDV = Q Else QDV = 0 Else If D(C) > 0 Then QDV = 0 Else If D(C - 1) > 0 Then QDV = D(C) Else QDV = Q End If End If tabella.Edit campo = QDV tabella.Update tabella.MoveNext Loop tabella.Close db.Close End Function
Infine valorizziamo la QT residua ed otteniamo la valorizzazione FIFO:
SELECT giacenze.CODICE, SUM([QDV]*[COSTO]) AS VALORE FROM giacenze GROUP BY giacenze.CODICE; |
SELECT giacenze.CODICE, Sum([QDV]*[COSTO]) AS VALORE FROM giacenze GROUP BY giacenze.CODICE;