Xuân Thanh > 08-04-20, 02:46 PM
(08-04-20, 01:12 PM)dotrung Đã viết: Anh Thanh ơi, việc chuyển tồn (mã hàng của 1 kho) sang năm sau thì demo của anh không chuyển qua được, em nghĩ do RecKey ràng buộc bằng năm hiện hành. Có lẽ phải có 1 lệnh nữa để chuyển tồn qua năm sau.
Đây là link file em test file của anh Xuân Thanh http://www.mediafire.com/file/90av12mdzv...accdb/file
Xuân Thanh > 08-04-20, 03:44 PM
Private Sub btnTinhTon_Click()
     'Bay loi khi txtThang và txtNam = ""
     Call TinhTonKho(Me.txtThang, Me.txtNam)
     MsgBox "Xong"
End SubSELECT tblPhieuNhap.NgayCT, "PN" AS LoaiCT, tblPhieuNhapChiTiet.MaKho, tblPhieuNhapChiTiet.MaVT, tblPhieuNhapChiTiet.SoLuong, tblPhieuNhapChiTiet.ThanhTien
FROM tblPhieuNhap INNER JOIN tblPhieuNhapChiTiet ON tblPhieuNhap.RecKey = tblPhieuNhapChiTiet.RecKey
WHERE (((tblPhieuNhap.NgayCT) Between [TuNgay] And [DenNgay]));
UNION ALL SELECT tblPhieuXuat.NgayCT, "PX" AS LoaiCT, tblPhieuXuatChiTiet.MaKho, tblPhieuXuatChiTiet.MaVT, tblPhieuXuatChiTiet.SoLuong, tblPhieuXuatChiTiet.ThanhTien
FROM tblPhieuXuat INNER JOIN tblPhieuXuatChiTiet ON tblPhieuXuat.RecKey = tblPhieuXuatChiTiet.RecKey
WHERE (((tblPhieuXuat.NgayCT) Between [TuNgay] And [DenNgay]));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, qryNX As QueryDef
    Dim TonDau As Double, TienDau As Double, MaKho As String, MaVT As String, Rec 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 = DateSerial(Nam, Thang, 1)
    dEnd = DateSerial(Nam, Thang + 1, 1) - 1
    Set DB = CurrentDb
    Set qryNX = DB.QueryDefs("qryNhapXuat")
    qryNX.Parameters("TuNgay") = dStart
    qryNX.Parameters("DenNgay") = dEnd
    Set rnx = qryNX.OpenRecordset
    Set rTon = DB.OpenRecordset("tblTonKho", dbOpenTable)
    rTon.Index = "RecKey"
    Set rTonCu = DB.OpenRecordset("Select * From tblTonKho Where Left(Reckey,6) = '" & KhoaMoi & "'")
    If rTonCu.RecordCount > 0 Then
        GoSub TinhLaiTon
        GoSub TinhTrongKy
    Else
        GoSub ChuyenTonCu
        GoSub TinhTrongKy
    End If
    rTon.Close: rTonCu.Close:  rnx.Close
    Set rTon = Nothing: Set rTonCu = Nothing: Set rnx = Nothing
    Exit Function
'Tinh lai ton cua thang da tinh
TinhLaiTon:
    Set rTonCu = DB.OpenRecordset("Select * From tblTonKho Where Left(RecKey,6) = '" & KhoaMoi & "'")
    If rTonCu.RecordCount > 0 Then rTonCu.MoveFirst
    Do Until rTonCu.EOF
        MaKho = rTonCu!MaKho: MaVT = rTonCu!MaVT: Rec = KhoaMoi & "-" & MaKho & "-" & MaVT
        TonDau = rTonCu!TonDau: TienDau = rTonCu!TienDau
        rTon.Seek "=", Rec
        If Not rTon.NoMatch Then
            rTon.Edit
            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!DGBQ = 0
            rTon.Update
        End If
        rTonCu.MoveNext
    Loop
    Return
        
'Chuyen Ton thang truoc sang thang moi
ChuyenTonCu:
    Set rTonCu = DB.OpenRecordset("Select * From tblTonKho Where Left(RecKey, 6) = '" & 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!DGBQ = 0
        rTon.Update
        rTonCu.MoveNext
    Loop
    Return
    
'Tinh Nhap Xuat trong ky
TinhTrongKy:
    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
    
    Return
'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 Functiondotrung > 08-04-20, 09:23 PM
https://www.upsieutoc.com/image/tonkho.PAILMOongke0711 > 09-04-20, 04:31 PM
![[Hình: mmZ5viW.png]](https://i.imgur.com/mmZ5viW.png)
Xuân Thanh > 09-04-20, 04:43 PM
(09-04-20, 04:31 PM)ongke0711 Đã viết: Anh Xuân Thanh cho hỏi: theo cái file demo của anh, khi chạy thì bảng tồn kho có cái mã DA4x6 của 2 kho khác nhau thì giá BQGQ cũng khác nhau luôn? Nó có đúng qui chuẩn kế toán không?
Xuân Thanh > 09-04-20, 05:11 PM
(09-04-20, 04:31 PM)ongke0711 Đã viết: Môt câu hỏi nữa là trong thực tế việc tính lại đơn giá BQGQ cho toàn bộ mã hàng chỉ thực hiện ở cuối tháng khi chốt sổ đúng không anh Thanh?
Còn trong tháng mỗi khi có nghiệp vụ Xuất thì có tính liền lúc đó không?
Nếu có tính BQGQ ngay thời điểm Xuất thì cuối tháng có cần cập nhật lại không?
Lúc trước em có test trên CSDL lớn của anh ledangvan thì dùng code VBA tính lại giá BQGQ cho nhiều tháng nó chậm kinh khủng, chuyển qua dùng Query kết hợp thì cũng đỡ hơn chút thôi. Bây giờ mới nghĩ ra là chưa thử cách dùng mảng xem có cải thiện tốc độ không.
dotrung > 17-08-21, 06:11 AM
Xuân Thanh > 18-08-21, 11:12 AM
Public Function TinhTonKho(TuNgay As Date, DenNgay As Date)
    Dim DB As DAO.Database, rnx As DAO.Recordset, rTonCu As DAO.Recordset, rTonNgay As DAO.Recordset
    Dim KhoaCu As String,  KhoaMoi As String
    Dim qryNX As QueryDef
    Dim TonDau As Double, TienDau As Double, MaKho As String, MaVT As String
    
    Set DB = CurrentDb
    Set qryNX = DB.QueryDefs("qryNhapXuat")    
    Set rTonNgay = DB.OpenRecordset("tblTonKhoNgay", dbOpenTable)
    If rTonNgay.Recordcount > 0 Then DB.Excute "Delete * From tblTonKhoNgay"
    rTonNgay.Index = "RecKey"
    
    GoSub LayTonDau
    
    If Day(TuNgay) > 1 Then
        qryNX.Parameters("TuNgay") = DateSerial(Year(TuNgay), Month(TuNgay),1)
        qryNX.Parameters("DenNgay") = TuNgay - 1
        Set rnx = qryNX.OpenRecordset
        GoSub CongThemTonDau            
    End If
    GoSub TinhTrongKy
    rTonNgay.Close: rTonCu.Close:  rnx.Close
    Set rTonNgay = Nothing: Set rTonCu = Nothing: Set rnx = Nothing
    Exit Function
'Lay Ton Dau Ky cua Thang TuNgay
LayTonDau:
    KhoaCu = Year(TuNgay) & Month(TuNgay)
    Set rTonCu = DB.OpenRecordset("Select * From tblTonKho Where Left(RecKey,6) = '" & KhoaCu & "'")
    If rTonCu.RecordCount > 0 Then rTonCu.MoveFirst
    Do Until rTonCu.EOF
        MaKho = rTonCu!MaKho: MaVT = rTonCu!MaVT: KhoaMoi = MaKho & "-" & MaVT
        TonDau = rTonCu!TonDau: TienDau = rTonCu!TienDau
        rTonNgay.Seek "=", KhoaMoi
        If rTonNgay.NoMatch Then
            rTonNgay.AddNew
            rTonNgay!RecKey = KhoaMoi: rTonNgay!MaKho = MaKho: rTonNgay!MaVT = MaVT
            rTonNgay!TonDau = TonDau: rTonNgay!TienDau = TienDau: rTonNgay!TongNhap = 0: rTonNgay!TienNhap = 0
            rTonNgay!TongXuat = 0: rTonNgay!TienXuat = 0: rTonNgay!TonCuoi = 0: rTonNgay!TienCuoi = 0
            rTonNgay.Update
        End If
        rTonCu.MoveNext
    Loop
    Return
      
'Cong them Ton Dau Ky khi TuNgay > 1
CongThemTonDau:
    
    If rnx.RecordCount > 0 Then rnx.MoveFirst
    Do Until rnx.EOF
        rTonNgay.Seek "=", rnx!MaKho & "-" & rnx!MaVT
        If rTonNgay.NoMatch Then            
            rTonNgay.AddNew
            rTonNgay.RecKey = rnx!MaKho & "-" & rnx!MaVT: rTonNgay!MaKho = rnx!MaKho: rTonNgay!MaVT = rnx!MaVT
            rTonNgay!TonDau = 0: rTonNgay!TienDau = 0: rTonNgay!TongNhap = 0: rTonNgay!TienNhap = 0
            rTonNgay!TongXuat = 0: rTonNgay!TienXuat = 0: rTonNgay!TonCuoi = 0: rTonNgay!TienCuoi = 0
            rTonNgay.Update
            rTonNgay.Bookmark = rTonNgay.LastModified
       End If
            rTonNgay.Edit
            If rnx!LoaiCT = "PN" Then
                rTonNgay!TonDau = rTonNgay!TonDau + rnx!SoLuong
                rTonNgay!TienDau = rTonNgay!TienDau + rnx!ThanhTien
            ElseIf rnx!LoaiCT = "PX" Then               
                rTonNgay!TonDau = rTonNgay!TonDau - rnx!SoLuong
                rTonNgay!TienDau = rTonNgay!TienDau - rnx!ThanhTien
            End If
            rTonNgay.Update            
        
        rnx.MoveNext
    Loop
    Return
  
'Tinh Nhap Xuat trong ky
TinhTrongKy:
    ryNX.Parameters("TuNgay") = TuNgay
    qryNX.Parameters("DenNgay") = DenNgay
    Set rnx = qryNX.OpenRecordset    
    If rnx.RecordCount > 0 Then rnx.MoveFirst
    Do Until rnx.EOF
        rTonNgay.Seek "=", rnx!MaKho & "-" & rnx!MaVT
        If rTonNgay.NoMatch Then
            rTonNgay.AddNew
            rTonNgay!RecKey = rnx!MaKho & "-" & rnx!MaVT
            rTonNgay!MaKho = rnx!MaKho
            rTonNgay!MaVT = rnx!MaVT
            rTonNgay!TonDau = 0: rTonNgay!TienDau = 0: rTonNgay!TongNhap = 0: rTonNgay!TienNhap = 0
            rTonNgay!TongXuat = 0: rTonNgay!TienXuat = 0: rTonNgay!TonCuoi = 0: rTonNgay!TienCuoi = 0
            rTonNgay.Update
            rTonNgay.Bookmark = rTonNgay.LastModified
        End If
        rTonNgay.Edit
        If rnx!LoaiCT = "PN" Then
            rTonNgay!TongNhap = rTonNgay!TongNhap + rnx!SoLuong
            rTonNgay!TienNhap = rTonNgay!TienNhap + rnx!ThanhTien
        ElseIf rnx!LoaiCT = "PX" Then
            rTonNgay!TongXuat = rTonNgay!TongXuat + rnx!SoLuong
            rTonNgay!TienXuat = rTonNgay!TienXuat + rnx!ThanhTien
        End If
        
        GoSub TinhTonCuoi
        rTonNgay.Update
        rnx.MoveNext
    Loop
  
    Return
'Tinh Ton Cuoi Ky
TinhTonCuoi:
    rTonNgay!TonCuoi = rTonNgay!TonDau + rTonNgay!TongNhap - rTonNgay!TongXuat
    rTonNgay!TienCuoi = rTonNgay!TienDau + rTonNgay!TienNhap - rTonNgay!TienXuat
    
    Return
  
End Functiondotrung > 18-08-21, 07:13 PM