thucgia > 12-09-15, 04:33 PM
ongke0711 > 13-09-15, 09:52 PM
tranthanhan1962 > 13-09-15, 10:07 PM
Private Sub XEM_Click()
On Error GoTo Biloi
Dim stDocName As String
Dim CSDL As Database
Dim BangHH As Recordset
Dim MAHANG As String
Dim SLT, GTT, BQT As Double
Dim STT As Integer
Set CSDL = CurrentDb
Set BangHH = CSDL.OpenRecordset("SOHANGHOACHITIET", DB_OPEN_DYNASET)
SLT = 0
GTT = 0
STT = 0
MAHANG = ""
BangHH.MoveFirst
Do While Not BangHH.EOF
BangHH.Edit
BangHH![TT] = STT + 1
If BangHH![TENHANG] = MAHANG Then
BangHH![SLTDK] = SLT
BangHH![GTTDK] = GTT
BangHH![GTXTK] = BangHH![SLXTK] * BangHH![BQTK]
BangHH![SLTCK] = BangHH![SLTDK] + BangHH![SLNTK] - BangHH![SLXTK] - BangHH![SLHTK]
BangHH![GTHTK] = BangHH![SLHTK] * BangHH![BQTK]
BangHH![GTTCK] = BangHH![GTTDK] + BangHH![GTNTK] - BangHH![GTXTK] - BangHH![GTHTK]
SLT = BangHH![SLTCK]
GTT = BangHH![GTTCK]
Else
If BangHH![NGAY] < Form_NXTHANGHOA.NGAYDAU.Value Then
BangHH![GTTDK] = BangHH![SLTDK] * BangHH![BQDK]
BangHH![GTXTK] = BangHH![SLXTK] * BangHH![BQTK]
BangHH![GTHTK] = BangHH![SLHTK] * BangHH![BQTK]
BangHH![GTTCK] = BangHH![SLTCK] * BangHH![BQCK]
SLT = BangHH![SLTCK]
GTT = BangHH![GTTCK]
Else
BangHH![GTTDK] = BangHH![SLTDK] * BangHH![BQDK]
BangHH![GTXTK] = BangHH![SLXTK] * BangHH![BQTK]
BangHH![SLTCK] = BangHH![SLTDK] + BangHH![SLNTK] - BangHH![SLXTK] - BangHH![SLHTK]
BangHH![GTHTK] = BangHH![SLHTK] * BangHH![BQTK]
BangHH![GTTCK] = BangHH![GTTDK] + BangHH![GTNTK] - BangHH![GTXTK] - BangHH![GTHTK]
SLT = BangHH![SLTCK]
GTT = BangHH![GTTCK]
End If
End If
STT = BangHH![TT]
MAHANG = BangHH![TENHANG]
BangHH.Update
BangHH.MoveNext
Loop
BangHH.Close
stDocName = "RNXTONHANGCHITIET"
DoCmd.OpenReport stDocName, acPreview
Biloi:
End Sub
thucgia > 13-09-15, 11:15 PM
(13-09-15, 10:07 PM)tranthanhan1962 Đã viết: Mình thấy bài bạn post lên mấy ngày nay. Nhưng suy nghĩ mãi mà không biết phải hỗ trợ bạn như thế nào. Khác với excel, BQGQ trên access không hề đơn giản. khi chạy BQGQ không thể xử lý bằng cách thay đổi 1 record là nó chạy ngay ra kết quả được. Vì không khéo nó rất dễ bị lỗi “Out Of Memory”.
Thông thường báo cáo tài chính có 2 báo cáo sử dụng đơn giá BQGQ là báo cáo kho (tháng, năm) và sổ hàng hóa.
Công thức của nó cho từng loại hàng hóa là:
Đơn giá BQGQ = (Giá trị tồn đầu + Giá trị nhập) / (Số lượng tồn đầu + Số lượng nhập)
Vì vậy chỉ khi hàng nhập là có đơn giá khác với đơn giá BQGQ cũ thì đơn giá BQGQ mới sẽ thay đổi ngay. Hàng hóa xuất trong khoảng giữa hai lần nhập sẽ lấy đơn giá vốn chính là đơn giá BQGQ giữa 2 lần nhập. Lý do số lượng nhập xuất trong năm rất nhiều dễ bị thiếu bộ nhớ khi chạy code.
Một điều nữa nếu trong tháng có một loại hàng hóa nào không được nhập xuất thì trên bảng báo cáo kho sẽ không có tên hàng đó. Vì vậy, trên table để tính BQGQ bạn phải bổ sung thêm một record có các giá trị = 0 cho các hàng hóa không có nhập xuất nếu là BC tháng.
Bạn không thể xử lý một Báo cáo chung cho cả ứng dụng mà phải xử lý ngắt ra từng năm. Lấy các số liệu tồn cuối của năm trước làm tồn đầu năm sau để tránh lỗi thiếu bộ nhớ.
Thêm nữa nếu chỉ xử lý đơn giản thì sẽ xảy ra rất nhiều chuyện. Lỗi khi hết hàng, âm hàng. Số lượng hàng hóa đã hết mà giá trị hàng hóa vẫn còn (do đơn giá BQGQ là số lẽ khi nhân với số lượng bán sẽ nhỏ hơn giá trị tồn).
Vì vậy cách xử lý của tôi rất phức tạp, tôi đưa nhiều đoạn mã vào nhiều event xử lý từng phần để bảo đảm tốc độ của phần mềm. Tôi chỉ có thể gởi cho bạn một đoạn code chung để hỗ trợ cho bạn. Đoạn code này chỉ có giá trị tham khảo. Còn cách xử lý là do bạn quyết định. Đoạn code này sẽ căn cứ vào một table đã được sắp xếp lại theo thứ tự nhập xuất theo ngày để xử lý tạo sổ hàng hóa. Tất cả các record phát sinh của một loại hàng hóa / ngày trong được cộng lại trên một record (Nếu báo cáo tháng của sổ hàng hóa sẽ bổ sung record có giá trị 0 cho loại hàng nào không có phát sinh, nếu báo cáo năm thì không cần) – Đối với báo cáo hàng tồn kho thì gom các phát sinh hàng hóa trong tháng thành 1 record cho từng loai hàng bổ sung hàng không phát sinh trong tháng.
Chú giải trong code SOHANGHOACHITIET là table. Table SOHANGHOACHITIET được sắp xếp như sau:
Các record trong cùng 1 loại hàng sắp liên tục theo ngày, hết loại hàng này mới đến loại hàng khác.
Các field của SOHANGHOACHITIET.
[TT] = Thứ tự
[TENHANG] = Tên hàng
[BQTK] = Đơn giá bình quân trong kỳ
[SLTDK] = Số lượng tồn đầu kỳ
[GTTDK] = Giá trị tồn đầu kỳ
[SLNTK] = Số lượng nhập trong kỳ
[GTNTK] = Giá trị nhập trong kỳ
[SLXTK] = Số lượng xuất
[GTXTK] = Giá trị xuất trong kỳ
[SLHTK] = Số lượng hao hụt trong kỳ (Nếu không có hao hụt thì bỏ phần này)
[GTHTK] = Giá trị hao hụt trong kỳ
[SLTCK] = Số lượng tồn cuối kỳ
[GTTCK] = Giá trị tồn cuối kỳ
Các tham số trong code
MAHANG = Tham số cho tên hàng
SLT = Tham số số lượng tồn cuối
GTT = Tham số giá trị tồn cuối
BQT = Tham số đơn giá bình quân
STT = Tham số cho Số thứ tự
Code này xử lý trên form Form_NXTHANGHOA. Trong table SOHANGHOACHITIET có các giá trị tồn đầu của record đầu tiên / từng loại hàng hóa được lấy từ giá trị tồn cuối kỳ trước, và trên record đầu tiên của từng loại hàng không tính các giá trị tồn đầu.
Mã:Private Sub XEM_Click()
On Error GoTo Biloi
Dim stDocName As String
Dim CSDL As Database
Dim BangHH As Recordset
Dim MAHANG As String
Dim SLT, GTT, BQT As Double
Dim STT As Integer
Set CSDL = CurrentDb
Set BangHH = CSDL.OpenRecordset("SOHANGHOACHITIET", DB_OPEN_DYNASET)
SLT = 0
GTT = 0
STT = 0
MAHANG = ""
BangHH.MoveFirst
Do While Not BangHH.EOF
BangHH.Edit
BangHH![TT] = STT + 1
If BangHH![TENHANG] = MAHANG Then
BangHH![SLTDK] = SLT
BangHH![GTTDK] = GTT
BangHH![GTXTK] = BangHH![SLXTK] * BangHH![BQTK]
BangHH![SLTCK] = BangHH![SLTDK] + BangHH![SLNTK] - BangHH![SLXTK] - BangHH![SLHTK]
BangHH![GTHTK] = BangHH![SLHTK] * BangHH![BQTK]
BangHH![GTTCK] = BangHH![GTTDK] + BangHH![GTNTK] - BangHH![GTXTK] - BangHH![GTHTK]
SLT = BangHH![SLTCK]
GTT = BangHH![GTTCK]
Else
If BangHH![NGAY] < Form_NXTHANGHOA.NGAYDAU.Value Then
BangHH![GTTDK] = BangHH![SLTDK] * BangHH![BQDK]
BangHH![GTXTK] = BangHH![SLXTK] * BangHH![BQTK]
BangHH![GTHTK] = BangHH![SLHTK] * BangHH![BQTK]
BangHH![GTTCK] = BangHH![SLTCK] * BangHH![BQCK]
SLT = BangHH![SLTCK]
GTT = BangHH![GTTCK]
Else
BangHH![GTTDK] = BangHH![SLTDK] * BangHH![BQDK]
BangHH![GTXTK] = BangHH![SLXTK] * BangHH![BQTK]
BangHH![SLTCK] = BangHH![SLTDK] + BangHH![SLNTK] - BangHH![SLXTK] - BangHH![SLHTK]
BangHH![GTHTK] = BangHH![SLHTK] * BangHH![BQTK]
BangHH![GTTCK] = BangHH![GTTDK] + BangHH![GTNTK] - BangHH![GTXTK] - BangHH![GTHTK]
SLT = BangHH![SLTCK]
GTT = BangHH![GTTCK]
End If
End If
STT = BangHH![TT]
MAHANG = BangHH![TENHANG]
BangHH.Update
BangHH.MoveNext
Loop
BangHH.Close
stDocName = "RNXTONHANGCHITIET"
DoCmd.OpenReport stDocName, acPreview
Biloi:
End Sub
Public Sub CapNhat_nhap_xuat()
Dim rs As DAO.Recordset
Dim st As String
Set rs = CurrentDb.OpenRecordset("nhap_xuat", dbOpenDynaset)
Do While Not rs.EOF
rs.Edit
If (rs!loai = "N") Then
'do nothing
Else
rs!don_gia = thekho.don_gia_bq_ngay(rs!hang_id, rs!ngay)
End If
rs!tien = rs!solg * rs!don_gia
rs.Update
rs.MoveNext
Loop
Set rs = Nothing
End Sub
tranthanhan1962 > 13-09-15, 11:41 PM
Public Sub CapNhat_nhap_xuat()
Dim rs As DAO.Recordset
Dim st As String
Set rs = CurrentDb.OpenRecordset("nhap_xuat", dbOpenDynaset)
Do While Not rs.EOF
rs.Edit
If (rs!loai = "N") Then
'tại dây bạn không thể do nothing mà phải xử lý đơn giá bình quân mới nếu có nhập. Nhưng nếu chỉ có thekho.don_gia_bq_ngay thì bạn sẽ không đủ tham số để tính đơn giá bình quân mới. (thekho.don_gia_bq_ngay mới sẽ thay đổi khi có hàng hóa nhập mới)
Else
rs!don_gia = thekho.don_gia_bq_ngay(rs!hang_id, rs!ngay)
End If
rs!tien = rs!solg * rs!don_gia
rs.Update
rs.MoveNext
Loop
Set rs = Nothing
End Sub
thucgia > 14-09-15, 09:13 AM
(13-09-15, 11:41 PM)tranthanhan1962 Đã viết:Mã:Public Sub CapNhat_nhap_xuat()
Dim rs As DAO.Recordset
Dim st As String
Set rs = CurrentDb.OpenRecordset("nhap_xuat", dbOpenDynaset)
Do While Not rs.EOF
rs.Edit
If (rs!loai = "N") Then
'tại dây bạn không thể do nothing mà phải xử lý đơn giá bình quân mới nếu có nhập. Nhưng nếu chỉ có thekho.don_gia_bq_ngay thì bạn sẽ không đủ tham số để tính đơn giá bình quân mới. (thekho.don_gia_bq_ngay mới sẽ thay đổi khi có hàng hóa nhập mới)
Else
rs!don_gia = thekho.don_gia_bq_ngay(rs!hang_id, rs!ngay)
End If
rs!tien = rs!solg * rs!don_gia
rs.Update
rs.MoveNext
Loop
Set rs = Nothing
End Sub
tranthanhan1962 > 14-09-15, 12:58 PM
thucgia > 14-09-15, 07:26 PM
(14-09-15, 12:58 PM)tranthanhan1962 Đã viết: Cho dù bạn nhập đơn giá nhập và số lượng nhập bằng input box hay lấy từ đâu, thì cũng phải có công thức tính lại đơn giá bình quân mới [Đơn giá BQGQ mới = (Giá trị hàng tồn ? + giá trị hàng mới nhập) / (Số lượng hàng tồn ? + số lượng hàng mới nhập)]. Thiếu GT hàng tồn và SL hàng tồn bạn sẽ không xử lý được đơn giá BQGQ mới.
Public Sub CapNhat_nhap_xuat()
Dim rs As DAO.Recordset
Dim st As String
Set rs = CurrentDb.OpenRecordset("nhap_xuat", dbOpenDynaset)
Do While Not rs.EOF
rs.Edit
If (rs!loai = "N") Then
'tại dây bạn không thể do nothing mà phải xử lý đơn giá bình quân mới nếu có nhập. Nhưng nếu chỉ có thekho.don_gia_bq_ngay thì bạn sẽ không đủ tham số để tính đơn giá bình quân mới. (thekho.don_gia_bq_ngay mới sẽ thay đổi khi có hàng hóa nhập mới)
'with me this is must do nothing!!!!
Else
rs!don_gia = thekho.don_gia_bq_truoc_ngay(rs!hang_id, rs!ngay)
End If
rs!tien = rs!solg * rs!don_gia
rs.Update
rs.MoveNext
Loop
Set rs = Nothing
End Sub
tranthanhan1962 > 14-09-15, 11:06 PM
thucgia > 15-09-15, 12:23 AM
(14-09-15, 11:06 PM)tranthanhan1962 Đã viết: Hì hì! Chiều nay trời mưa tầm tã. Nhưng có hẹn với mấy anh em cục thuế đi nhậu. Phải đi thôi. Đồng thời hẹn anh em ngày mai chuyển mail bảng excel hàng tồn cho anh em kiểm tra (trùng hợp quá nhỉ). Về mở máy thấy bạn phán một câu: Mình suy nghĩ thế, có gì cứ tiếp tranh luận nhé… Sorry. Mình không cần phải tranh luận với bạn đâu. Phương pháp hạch toán hàng tồn kho là do Tổng cục thuế quy định. Khi kinh doanh bạn phải đăng ký với đơn vị báo cáo thuế (cục hay chi cục tùy theo ngành nghề) Phương pháp tính giá trị hàng tồn kho. Có mấy cách hạch toán như sau:
1/ Phương pháp tính theo giá đích danh.
2/ Phương pháp bình quân gia quyền.
3/ Phương pháp nhập trước xuất trước (FIFO).
4/ Phương pháp nhập sau xuất trước (LIFO).
Vậy thôi. Chương trình của bạn chạy như thế nào không biết. Khi cơ quan thuế kiểm tra. Bạn in report cho bộ phận kiểm tra. Nhưng bổng nhiên bộ phận kiểm tra báo với bạn: Chuyển cho tôi thành file excel báo cáo tồn kho của anh. Bạn phải biến report của bạn thành file excel (chỉ cần số liệu không có công thức cũng được). Nhưng nếu report của bạn có số liệu không đúng với phương pháp hạch toán bạn đã đăng ký thì bạn phải xuất toán, bạn phải nộp phạt.
Vì vậy. Công thức hàng tồn kho tính giá vốn (giá vốn là giá xuất kho, căn cứ vào giá xuất kho cơ quan thuế sẽ xác định lãi gộp, và bạn sẽ nộp thuế % hoặc theo tỷ lệ ngàng nghề = % nào đó trên lãi ròng [lãi ròng = lãi gộp – chi phí]) nếu theo đơn giá bình quân gia quyền sẽ = (giá trị hàng tồn + cộng giá trị hàng nhập) / (số lượng hàng tồn + số lượng hàng nhập). Nếu bạn không chứng minh được số liệu của bạn đúng công thức này là bạn sẽ bị phạt (căn cứ theo cơ quan thế tính). Vì vậy, ngoài chuyện bạn tính đúng hay sai. Bảng kế toán hàng tồn của bạn phải có đầy đủ các cột theo quy định.
Đơn giá bình quân trong kỳ – Giá trị tồn đầu – số lượng tồn đầu – Giá trị nhập – số lượng nhập – Số lượng xuất – Giá trị xuất – Số lượng tồn cuối – Giá trị tồn cuối.
Những cái bạn cảm thấy tưởng như hợp lý trong các bài bạn đã post lên đều không thể ra được một report như thế.
Thực sự mình không dám nói bạn làm sai (thực ra là thiếu) nhưng rõ ràng kiểu tính của bạn không đủ để thực hiện một báo cáo bình quân gia quyền hàng tồn kho. Bạn không thể tranh luận với cơ quan thuế. Bạn chỉ có một quyền khẳng định với cơ quan thuế là “tôi làm đúng công thức”, Nếu bạn không khẳng định được điều đó là bạn sai và bạn sẽ bị phạt theo luật thuế. Vì vậy, Điều quan trọng là từ cách tính của bạn có tạo được một report như thế không. Với cách tính của bạn chắc chắn là không!
Sorry! Nếu có gì làm bạn mất lòng.