Xuân Thanh > 07-04-20, 11:39 AM
Public Function TinhTonKho(Thang, Nam)
    Dim DB As DAO.Database, rnx As DAO.Recordset, rTon As DAO.Recordset, rTonCu As DAO.Recordset
    Dim dStart As Date, dEnd As Date, KhoaCu As String, KhoaMoi As String
    Dim LThang As Integer, LNam As Integer
    Dim TonDau As Double, TienDau As Double, MaKho As String, MaVT As String
    If Thang = 1 Then
        LThang = 12: LNam = Nam - 1
    Else
        LThang = Thang - 1: LNam = Nam
    End If
    KhoaCu = LNam & Right("0" & LThang, 2)
    KhoaMoi = Nam & Right("0" & Thang, 2)
    dStart = Format(DateSerial(Nam, Thang, 1), "yyyy/mm/dd")
    dEnd = Format(DateSerial(Nam, Thang + 1, 1) - 1, "yyyy/mm/dd")
    Set DB = CurrentDb
    Set rnx = DB.OpenRecordset("Select a.NgayCT,""PN"" As LoaiCT, b.MaKho, b.MaVT, b.SoLuong, b.ThanhTien" & _
            " From tblPhieuNhap As a, tblPhieuNhapChiTiet As b" & _
            " Where a.RecKey = b.RecKey And a.NgayCT Between #" & dStart & "# And #" & dEnd & "#" & _
            " Union All Select c.NgayCT, ""PX"" As LoaiCT, d.MaKho, d.MaVT, d.SoLuong, d.ThanhTien" & _
            " From tblPhieuXuat As c, tblPhieuXuatChiTiet As d" & _
            " Where c.RecKey = d.Reckey And c.NgayCT Between #" & dStart & "# And #" & dEnd & "#" & _
            " Order By NgayCT")
    Set rTon = DB.OpenRecordset("tblTonKho", dbOpenTable)
    rTon.Index = "RecKey"
    
'Chuyen Ton thang truoc sang thang moi
    Set rTonCu = DB.OpenRecordset("Select * From tblTonKho Where RecKey Like '" & "%" & KhoaCu & "%" & "'")
    If rTonCu.RecordCount > 0 Then rTonCu.MoveFirst
    Do Until rTonCu.EOF
        MaKho = rTonCu!MaKho: MaVT = rTonCu!MaVT
        TonDau = rTonCu!TonCuoi: TienDau = rTonCu!TienCuoi
        rTon.AddNew
        rTon!RecKey = KhoaMoi & "-" & MaKho & "-" & MaVT
        rTon!MaKho = MaKho
        rTon!MaVT = MaVT
        rTon!TonDau = TonDau: rTon!TienDau = TienDau
        rTon!TongNhap = 0: rTon!TienNhap = 0: rTon!TongXuat = 0: rTon!TienXuat = 0
        rTon!TonCuoi = 0: rTon!TienCuoi = 0
        rTon.Update
        rTonCu.MoveNext
    Loop
    
'Tinh Nhap Xuat trong ky
    If rnx.RecordCount > 0 Then rnx.MoveFirst
    Do Until rnx.EOF
        rTon.Seek "=", KhoaMoi & "-" & rnx!MaKho & "-" & rnx!MaVT
        If rTon.NoMatch Then
            rTon.AddNew
            rTon!RecKey = KhoaMoi & "-" & rnx!MaKho & "-" & rnx!MaVT
            rTon!MaKho = rnx!MaKho
            rTon!MaVT = rnx!MaVT
            rTon!TonDau = 0: rTon!TienDau = 0: rTon!TongNhap = 0: rTon!TienNhap = 0
            rTon!TongXuat = 0: rTon!TienXuat = 0: rTon!TonCuoi = 0: rTon!TienCuoi = 0: rTon!DGBQ = 0
            rTon.Update
            rTon.Bookmark = rTon.LastModified
        End If
        rTon.Edit
        If rnx!LoaiCT = "PN" Then
            rTon!TongNhap = rTon!TongNhap + rnx!SoLuong
            rTon!TienNhap = rTon!TienNhap + rnx!ThanhTien
        ElseIf rnx!LoaiCT = "PX" Then
            rTon!TongXuat = rTon!TongXuat + rnx!SoLuong
            rTon!TienXuat = rTon!TienXuat + rnx!ThanhTien
        End If
        GoSub TinhTonCuoi
        rTon.Update
        rnx.MoveNext
    Loop
    Exit Function
'Tinh Ton Cuoi Ky
TinhTonCuoi:
    rTon!TonCuoi = rTon!TonDau + rTon!TongNhap - rTon!TongXuat
    rTon!TienCuoi = rTon!TienDau + rTon!TienNhap - rTon!TienXuat
    If (rTon!TienDau + rTon!TienNhap) > 0 And (rTon!TonDau + rTon!TongNhap) > 0 Then
        rTon!DGBQ = (rTon!TienDau + rTon!TienNhap) / (rTon!TonDau + rTon!TongNhap)
    End If
    Return
    
End FunctionXuân Thanh > 07-04-20, 02:07 PM
mrsiro > 07-04-20, 06:04 PM
dotrung > 07-04-20, 09:22 PM
Trích dẫn:Sau khi chạy thử hàm trên có ai phát hiện ra điều gì không?
Trích dẫn:Nếu gặp trường hợp 1 kho có 1 mặt hàng với 2 mức giá khác nhau thì sao.
ongke0711 > 07-04-20, 09:30 PM
mrsiro > 07-04-20, 10:20 PM
tranthanhan1962 > 07-04-20, 10:21 PM
Xuân Thanh > 08-04-20, 11:00 AM
(07-04-20, 10:21 PM)tranthanhan1962 Đã viết: Khác mọi người, mình vẫn trung thành với 1 table nhập xuất hàng hoá chung. Bởi vì kiểu gì thì kiểu vẫn phải có 1 thao tác gom 2 table này thành 1 thì mới xử lý được bài toán nhập - xuất - tồn, vậy thì hà cớ vì phải chia nó ra rồi gom lại cho thêm việc. Đôi khi cái việc chia ra rồi gom lại sinh ra lỗi.
Về nguyên tắc để bảo mật dữ liệu, nếu không dấu được query thì bảo mật cái gì. Một phần mềm CSDL access cho dù không sử dụng query để tính tồn kho thì cũng phải có một số query làm việc khác. Không thể chỉ VBA xử lý hết được mọi công việc vì phần mềm đâu chỉ tính tồn kho. Vả lại ngoài query còn table, không vào query thì vào table. Chỉ cần mở table sửa vài ba số là đủ lòi con mắt rồi.
Về vấn đề tồn kho, nếu phải tính giá vốn mới phức tạp cho dù là BQGQ hay nhập giá nào xuất gía đó, mỗi thứ đều có cái phức tạp ra nó. Hồi xưa, tôi còn nhớ (cái thời office 95) tôi có đoạn code VBA tính giá vốn BQGQ của bác Ông Văn Thông xử lý thẳng trên table nhập xuất hàng hoá (1table), ngay sau khi nhập record phát sinh, tiếc thay quyển sách đó tôi đã tặng cho ai rồi (không nhớ cho ai luôn) nếu không nhầm đại loại tên quyển đó là Microsoft Access version 2.0 trong quản lý xuất nhập tồn kho. Tập 2, tôi còn nhớ bác Thông viết cho access ver 2.0. Cả ổ cứng lưu demo cũng bị hỏng từ lâu. Bạn nào có cái này post lên cho tôi xin lại. Code của bác ấy xử lý trực tiếp lên table nhập xuất rất nhẹ viết cho access 2.0 mà.
Còn nếu viết tồn kho mà không quan tâm đến giá vốn thì rất dễ, thậm chí không cần VBA, không cần query luôn đẩy thẳng một phát lên report xong luôn (thực ra query nằm trên query builder nên không hiển thị ra ngoài) rất gọn và truy xuất nhập xuất tồn bất kỳ thời gian nào số lượng record vài trăm ngàn cũng chỉ cần một chớp mắt là xong
demo
Xuân Thanh > 08-04-20, 11:11 AM
(07-04-20, 09:22 PM)dotrung Đã viết:Trích dẫn:Sau khi chạy thử hàm trên có ai phát hiện ra điều gì không?
Theo em, Demo anh Thanh không có tồn kho đầu, có lẽ do ý đồ tác giả, yêu cầu người dùng phải khai báo trong các trường hợp (kiểm kê, chuyển năm quyết toán, nhập tồn ban đầu Chương trình ...). em test năm trước, giá trị không hiện trong năm nay.
Trích dẫn:Nếu gặp trường hợp 1 kho có 1 mặt hàng với 2 mức giá khác nhau thì sao.
Theo dotrung 1 đơn vị lớn họ chỉ đăng ký 1 giá duy nhất và áp dụng chính sách bán hàng (CK, giảm giá, HH ...) để tăng giảm nhu cầu. Còn đơn vị nhỏ lẻ (thuế khoán hoặc không) thì sẽ có nhiều giá bán nhưng không khai thuế DN.
dotrung > 08-04-20, 01:12 PM