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;