Mình vừa mới mở file của bạn
tuanhungkcs xem trong office 2019. Có mốt số ý kiến như sau:
Như bác Noname đã nói dữ liệu trong database chưa đủ để xử lý BQGQ được. từ các table trên phải xử lý chuyển về thành 1 table với đầy đủ các field như sau:
Ở đây như bác Noname nói có 2 cách xử lý, 1 là thời điểm, 2 là giai đoạn. Tôi chọn cách 2 vì báo cáo kế toán theo giai đoạn hàng tháng, hàng năm.
Cách này sẽ có 1 điểm sẽ xảy ra chuyện khuyết dữ liệu hàng hóa tháng nếu tháng đó không phát sinh (không nhập, không xuất) cần phải bổ sung (nhập = 0, xuất = 0)
Field [
NAMTHANG] (Năm tháng) tôi chuyển sang dạng text dưới dạng
yyyymm để dễ dàng sắp xếp không ảnh hưởng gì đến việc tạo report báo cáo, các field khác gồm có:
TENHANG (Tên hàng)-
DVT(Đơn vị tính)-
GTTDK(Giá trị tồn đầu kỳ)-
SLTDK(Số lượng tồn đầu kỳ)-
GTNTT(Giá trị nhập trong kỳ)-
SLNTT(Số lượng nhập trong kỳ)-
GTXTT(Giá trị xuất trong kỳ)-
SLXTT(Số lượng xuất trong kỳ)-
GTTCK(Giá trị tồn cuối kỳ)-
SLTCK(Số lượng tồn cuối kỳ), Ngoài ra còn bổ sung các field
BQDK(Bình quân đầu kỳ)-
BQTT(Bình quân trong tháng)-
BQCK(Bình quân cuối kỳ) . Trong đó các field:
GTNTT, SLNTT, SLXTT là các giá trị thực tế phát sinh được cập nhật, các field khác sẽ do code chương trình tính toán
Đặc điểm của code tính toán do nhiều loại hàng hóa, mỗi loại chạy nhiều tháng liên tục nên table phải được sắp xêp từ A->Z ưu tiên là tên hàng kế tiếp là năm tháng. Code sẽ chạy hết tên hàng này đến tên hàng khác và tuần tự từ record tháng đầu tiên đến record thàng cuối cùng sau đó chuyển sang tên hàng khác.
Một vài lưu ý: Một lưu ý, do mỗi năm có 12 tháng số lượng record = số lượng tên hàng x 12 x số năm nên khi chạy code sẽ có số lương record có thể rất lớn news chạy trên access 2003 khi chạy toàn bộ record có thể gây lỗi do giới hạn record, giới hạn bộ nhớ, trong trường hợp này phải xử lý nhiều cách chia ra nhiều đợt chạy code khống chế chạy giới hạn trong khoảng record bị thay đổi giá trị (do mỗi database xử lý mỗ khác nên không thể đưa ra một phương pháp chung được) tốt nhất chuyển từ mdb sang accdb và máy mạnh hơn (ví dụ core i5 - ram 4g) có thể chạy thẳng 1 mạch từ record đầu -> record cuối một cách OK.
Dưới đây là code để y BQGQ:
Sub BQGQ()
Dim CSDL As Database
Dim B01 As DAO.Recordset ' Khai báo với accdb, nếu mdb:
Dim B01 As Recordset
Dim MAHANG As String
Dim SLT, GTT, BQT As Double ' SLT (số lượng tồn), GTT (giá trị tồn), BQT (bình quân tồn)
Set CSDL = CurrentDb
Set B01 = CSDL.OpenRecordset("table_NHAPXUAT", DB_OPEN_DYNASET) ' table_NHAPXUAT là bảng nhập xuất hàng hóa
SLT = 0
GTT = 0
MAHANG = ""
B01.MoveFirst
Do While Not B01.EOF ' Chạy vòng lập
If B01![TENHANG] = MAHANG Then ' Nếu Tên hàng = Mã cũ thì tính theo Công thức dưới đây
B01.Edit
B01![BQTK] = BQT
B01![SLTDK] = SLT
B01![GTTDK] = GTT
If B01![SLTDK] + B01![SLNTT] = 0 Then ' Nếu bị lỗi 0/0 thì = 0
B01![BQTK] = 0
Else
B01![BQTK] = (B01![GTTDK] + B01![GTNTT]) / (B01![SLTDK] + B01![SLNTT])
End If
B01![GTXTT] = B01![BQTK] * B01![SLXTT]
B01![SLTCK] = B01![SLTDK] + B01![SLNTT] - B01![SLXTT]
B01![GTTCK] = B01![GTTDK] + B01![GTNTT] - B01![GTXTT]
B01![BQCK] = B01![BQTK]
B01.Update
Else
If B01![SLNTT] > 0 Then
B01.Edit
B01![BQTK] = B01![GTNTT] / B01![SLNTT]
B01![GTXTT] = B01![BQTK] * B01![SLXTT]
B01![SLTCK] = B01![SLNTT] - B01![SLXTT]
B01![GTTCK] = B01![GTNTT] - B01![GTXTT]
B01![BQCK] = B01![BQTK]
B01.Update
End If
End If
MAHANG = B01![TENHANG]
BQT = B01![BQCK]
SLT = B01![SLTCK]
GTT = B01![GTTCK]
B01.MoveNext
Loop
B01.Close
End Sub
Chúc bạn thành công. Chú ý Không đưa giá trị đầu kỳ vào các field tồn đầu mà phải tạo một record nhập tồn đầu kỳ rồi đưa giá trị vào các field nhập
Đ/c nào có p/p hay hơn góp ý dùm.