UDF tính tồn kho (theo số lượng) tại một thời điểm bất kỳ

  • Thread starter Thread starter BNTT
  • Ngày gửi Ngày gửi
Liên hệ QC

BNTT

Bùi Nguyễn Triệu Tường
Thành viên danh dự
Tham gia
3/7/07
Bài viết
4,946
Được thích
23,208
Nghề nghiệp
Dạy đàn piano
Tôi có một đề tài thú vị đây.
Để tính tồn kho tại một thời điểm bất kỳ, chúng ta đã biết là dễ dàng dùng hàm SUMPRODUCT. Tuy nhiên, cho tôi hỏi, có thể tạo một cái UDF được không?

Ví dụ, có 1 Database Hàng hóa, gồm có các cột như sau:
1. Ngày tháng năm (nhập hoặc xuất)
2. Mã hàng hóa
3. Số lượng Nhập
4. Số lượng Xuất

Xin nhờ các bác làm giúp một cái UDF (có thể chạy trong Excel và cả trong VBA) theo dạng sau:
TONKHO(DATABASE,NGAY,MAHANG)
Diễn giải: Dùng để kiểm tra số lượng hàng tồn kho của (MAHANG) tại thời điểm (NGAY) trong bảng (DATABASE)
 
Lần chỉnh sửa cuối:
Trong dữ liệu có những chứng từ CƠ BẢN sau đây ảnh có ảnh hưởng tới việc tính NXT về số lượng:

1/ Dư đầu kỳ:
- Chứng từ "Dư đầu kỳ"
2/ Phát sinh tăng:
- Chứng từ "Phiếu nhập hàng"
- Chứng từ "Phiếu nhập hàng Khách hàng trả lại"
- Chứng từ "Phiếu điều chuyển" (Kho chuyển đến)
- Chứng từ "Lắp ráp/tháo dỡ" (Tăng "thành phẩm" hay "vật tư")
- Chứng từ "Phiếu điều chỉnh - kiểm kê" (chênh lệch thực tế so với sổ sách là > 0)
3/ Phát sinh giảm
- Chứng từ "Phiếu xuất hàng" (bán buôn, bán lẻ, sản xuất,...)
- Chứng từ "Phiếu xuất hàng trả lại NCC"
- Chứng từ "Phiếu điều chuyển" (Kho chuyển đi)
- Chứng từ "Lắp ráp/tháo dỡ" (Giảm "thành phẩm" hay "vật tư")
- Chứng từ "Phiếu điều chỉnh - kiểm kê" (chênh lệch thực tế so với sổ sách là < 0)

Khi tính số dư tại 1 thời điểm thì người ta thường hay có mục đích sau:
- Hiển thị danh sách hàng hóa vật tư với số dư tồn kho trong 1 kho hàng tại một thời điểm (gọi chung là ngày báo cáo).
- Tính giá trị tồn kho của 1 mặt hàng trong 1 kho tại 1 thời điểm (gọi chung là ngày báo cáo).

Kỳ ở đây được hiểu là tháng của ngày báo cáo
ví dụ: Thời điểm báo cáo là 07/12/2007 thì Kỳ = 12

Số dư (tại thời điểm) = Dư đầu kỳ(thời điểm) + PS tăng (thời điểm) - PS giảm (thời điểm)

Nếu các bạn thiết kế các chứng từ độc lập (dạng Master/Detail) trong hệ thống CSDL thì với cách hiểu nói trên, chỉ cần khéo léo 1 tý là các bạn có thể viết đúng 1 câu SQL có sự kết hợp của Union All và hàm Sum() để tính số dư thời điểm và báo cáo Nhập-Xuất-Tồn một cách cực kỳ nhanh.
 
Upvote 0
BNTT đã viết:

Nếu theo cách 1, thì e rằng khó, vì mình muốn dùng cho bất kỳ một Database nào, nên có thể các cột sẽ không sắp sẵn như ý mình muôn.
Còn theo cách 2, nghe cũng có lý. Thừa cái thằng Database.
Vậy theo cách này đi, ta sẽ thiết kế một cái hàm TonKho như vầy"
TONKHO(NGAY,MAHANG,SLNHAP,SLXUAT)
Riêng cột ngày, đương nhiên phải sort rồi, từ xưa tới nay.

Làm gì có UDF nào mà "
muốn dùng cho bất kỳ một Database nào" , các data có ai đặt thống nhất đâu.
TONKHO(NGAY,MAHANG,SLNHAP,SLXUAT)
Thiếu mất ngay_array, mahang_array. Mà chỉ cần lấy cột thứ mấy của 1 data set trước, phải lấy từ đầu ->NGAY.
Tôi đề xuất tạo sẵn 1 Range Data. Các cột thay đổi thì đổi IMa...
Chẳng lẽ:
TONKHO(NGAY,MAHANG,Col(Mahang), Col(Ngay), Col(SLNhap),
Col(SLXuat))
Nó thế nào...
Vậy dùng tạm cái này
PHP:
[quote]Option Explicit
Dim Ngay As Range, MaHH As Range, SLNhap As Range, SLXuat As Range, nname As String
Dim eRow As Long, iDate As Long, iMaHH As Long, i As Long, Tmp As Double
Private Const iNgay = 1 'cot ngay trong data
Private Const iMa = 2
Private Const iNhap = 3
Private Const iXuat = 4
Public Function TKCK(Ngay_Value As Range, MaHH_Value As Range) As Double
'Ngay phai nhap theo dang dd/mm/yy, chua test het
Application.Volatile (False) 'Okebab
'Kiem tra name Data
nname = "Data"
If RangeNameExists(nname) = False Then
    MsgBox "Chua co range Data"
    Exit Function
End If
eRow = Range("Data").Rows.Count
Set Ngay = WorksheetFunction.Index(Range("Data"), 0, iNgay)
Set MaHH = WorksheetFunction.Index(Range("Data"), 0, iMa)
iDate = WorksheetFunction.CountIf(Ngay, ">=" & CLng(Ngay_Value))
iMaHH = WorksheetFunction.CountIf(MaHH, MaHH_Value)
'HangCuoi = sht.UsedRange.Rows.Count + sht.UsedRange.Row
If iDate = 0 Or iMaHH = 0 Then
    MsgBox "Truy xuat khong dung"
    Exit Function
End If
eRow = WorksheetFunction.CountIf(Ngay, "<=" & CLng(Ngay_Value))
Set MaHH = WorksheetFunction.Index(Range("Data"), 0, iMa)
Set SLNhap = WorksheetFunction.Index(Range("Data"), 0, iNhap)
Set SLXuat = WorksheetFunction.Index(Range("Data"), 0, iXuat)
For i = 1 To eRow
    If UCase(MaHH(i)) = UCase(MaHH_Value) Then
        Tmp = Tmp + SLNhap(i) - SLXuat(i)
    End If
Next
TKCK = Tmp
Tmp = 0
Set Ngay = Nothing
Set MaHH = Nothing
Set SLNhap = Nothing
Set SLXuat = Nothing

End Function
Public Function RangeNameExists(nname) As Boolean
    Dim n As Name
    RangeNameExists = False
    For Each n In ActiveWorkbook.Names
        If UCase(n.Name) = UCase(nname) Then
            RangeNameExists = True
            Exit Function
        End If
    Next n
End Function

[/quote]
 
Lần chỉnh sửa cuối:
Upvote 0
Smart Indenter Version 3.5

Các bác nên dùng cái này:
http://www.giaiphapexcel.com/forum/showthread.php?t=3921

để canh chỉnh code trước khi post bài cho mọi người dễ đọc.

Code của anh ThuNghi sau khi dùng Smart Indenter Version 3.5

PHP:
Option Explicit
Dim Ngay As Range, MaHH As Range, SLNhap As Range, SLXuat As Range, nname As String
Dim eRow As Long, iDate As Long, iMaHH As Long, i As Long, Tmp As Double
Private Const iNgay = 1    'cot ngay trong data
Private Const iMa = 2
Private Const iNhap = 3
Private Const iXuat = 4

Public Function TKCK(Ngay_Value As Range, MaHH_Value As Range) As Double
'Ngay phai nhap theo dang dd/mm/yy, chua test het
    Application.Volatile (False)    'Okebab
'Kiem tra name Data
    nname = "Data"
    If RangeNameExists(nname) = False Then
        MsgBox "Chua co range Data"
        Exit Function
    End If
    eRow = Range("Data").Rows.Count
    Set Ngay = WorksheetFunction.Index(Range("Data"), 0, iNgay)
    Set MaHH = WorksheetFunction.Index(Range("Data"), 0, iMa)
    iDate = WorksheetFunction.CountIf(Ngay, ">=" & CLng(Ngay_Value))
    iMaHH = WorksheetFunction.CountIf(MaHH, MaHH_Value)
    'HangCuoi = sht.UsedRange.Rows.Count + sht.UsedRange.Row
    If iDate = 0 Or iMaHH = 0 Then
        MsgBox "Truy xuat khong dung"
        Exit Function
    End If
    eRow = WorksheetFunction.CountIf(Ngay, "<=" & CLng(Ngay_Value))
    Set MaHH = WorksheetFunction.Index(Range("Data"), 0, iMa)
    Set SLNhap = WorksheetFunction.Index(Range("Data"), 0, iNhap)
    Set SLXuat = WorksheetFunction.Index(Range("Data"), 0, iXuat)
    For i = 1 To eRow
        If UCase(MaHH(i)) = UCase(MaHH_Value) Then
            Tmp = Tmp + SLNhap(i) - SLXuat(i)
        End If
    Next
    TKCK = Tmp
    Tmp = 0
    Set Ngay = Nothing
    Set MaHH = Nothing
    Set SLNhap = Nothing
    Set SLXuat = Nothing
End Function

Public Function RangeNameExists(nname) As Boolean
    Dim n As Name
    RangeNameExists = False
    For Each n In ActiveWorkbook.Names
        If UCase(n.Name) = UCase(nname) Then
            RangeNameExists = True
            Exit Function
        End If
    Next n
End Function


FB.
 
Upvote 0
Nghiên cứu tới lui, vẫn thấy phải có tham số DATABASE thôi MrOKBap à.
Để cho nó hiểu rằng mình truy xuất từ cái bảng nào. Bảng này có thể sẽ được chỉ định bằng địa chỉ tuyệt đối hoặc bằng cách đặt tên.
Sau đó, chỉ cho nó sử dụng tham số SLNHAP và SLXUAT là 2 cái cột nào trong bảng đó.

Hình như trong những bài trên, vấn đề nêu ra chưa được hiểu rõ lắm, có thể do tôi diễn đạt chưa kỹ.

Xin được diễn giải lại:

Database là một bảng bất kỳ (bất kỳ ở đây có nghĩa là có thể nằm trong bất kỳ một file nào đó hoặc một sheet nào đó), định dạng của Database có thể sẽ mỗi cái mỗi khác. Miễn là:
- Cột Ngày Tháng là cột đầu tiên trong Database (giống như hàm Vlookup tìm kiếm dựa vào cột đầu tiên) và đã được sort rồi.
- Trong Database này có ít nhất 3 cột nữa: Mã Hàng Hóa, Số Lượng Nhập và Số Lượng Xuất.

Giả sử sau khi nhận được cái Database này, ta sẽ đặt tên:
- khối cell chứa dữ liệu cần truy xuất là DATABASE
- khối cell chứa tên hàng là MAHANG
- khối cell (cột) chứa ngày tháng là NGAY
- khối cell (cột) chứa số lượng nhập là SLNHAP
- khối cell (cột) chứa số lương xuât là SLXUAT

Vậy bây giờ yêu cầu là làm được 1 cái hàm TONKHO, với cú pháp:
TONKHO(DATABASE,NGAY,MAHANG,SLNHAP,SLXUAT)​
Khi chạy, yêu cầu là:
Lấy cái MAHANG, đi dò trong DATABASE, tính ra số lượng tồn kho tính tới thời điểm NGAY (vẫn giả sử tồn kho đầu kỳ = 0)
2 tham số SLNHAP và SLXUAT là vị trí khối cell trong DATABASE chứa số lượng nhập và số lượng xuất.

Xin gửi kèm theo đây một cái Database đã được đặt tên sẵn cho các khối cell cần phải đặt, trong đó, các cột ngày tháng, mã hàng, số lượng nhập và số lương xuất không nằm liên tục nhau.

Dựa vào file Book2.xls này, ý đồ của tôi là có được một cái hàm để khi ta gõ (ở bất kỳ cell nào ngoài cái Database hoặc sử dụng trong VBA):
= TONKHO(DATABASE,"9/10/2007","G_3030",SLNHAP,SLXUAT)​
Thì sẽ cho ra số lượng tồn kho của mặt hàng G_3030 tại thời điểm ngày 9/10/2007.

---------------------
Xin nói rõ thêm, ở đây chúng ta có thể sử dụng những hàm như SUMIF, SUMPRODUCT để đạt được yêu cầu trên.
Nhưng ý định khi mở topic này là không dùng những hàm có sẵn của Excel, mà tự chế ra một hàm khác, trong VBA, để có thể sử dụng trong cả Excel lẫn VBA, nên mong các bác không đưa ra các giải đáp mà sử dụng hàm có sẵn.
 

File đính kèm

Upvote 0
Bác ThuNghi ơi, áp dụng cái của bác vào cái Database trong Book2 không được. Nó cứ báo là "Truy xuất không đúng" miết thôi.

Nhân đây cũng xin phép cho tôi nói điều này, không phải là tôi chỉ nêu vấn đề ra rồi ngồi đó chờ mọi người giải quyết dùm thôi đâu. Tôi cũng đang mày mò làm, tuy nhiên chưa đưa lên đây được vì nó chẳng ra làm sao cả, chạy không được, thiếu lên thiếu xuống, báo lỗi liên tục... điên cái đầu từ sáng giờ, hic.
 
Upvote 0
BNTT đã viết:
Nghiên cứu tới lui, vẫn thấy phải có tham số DATABASE thôi MrOKBap à.
Để cho nó hiểu rằng mình truy xuất từ cái bảng nào. Bảng này có thể sẽ được chỉ định bằng địa chỉ tuyệt đối hoặc bằng cách đặt tên.
Sau đó, chỉ cho nó sử dụng tham số SLNHAP và SLXUAT là 2 cái cột nào trong bảng đó.

Hình như trong những bài trên, vấn đề nêu ra chưa được hiểu rõ lắm, có thể do tôi diễn đạt chưa kỹ.

Xin được diễn giải lại:

Database là một bảng bất kỳ (bất kỳ ở đây có nghĩa là có thể nằm trong bất kỳ một file nào đó hoặc một sheet nào đó), định dạng của Database có thể sẽ mỗi cái mỗi khác. Miễn là:
- Cột Ngày Tháng là cột đầu tiên trong Database (giống như hàm Vlookup tìm kiếm dựa vào cột đầu tiên) và đã được sort rồi.
- Trong Database này có ít nhất 3 cột nữa: Mã Hàng Hóa, Số Lượng Nhập và Số Lượng Xuất.

Giả sử sau khi nhận được cái Database này, ta sẽ đặt tên:
- khối cell chứa dữ liệu cần truy xuất là DATABASE
- khối cell chứa tên hàng là MAHANG
- khối cell (cột) chứa ngày tháng là NGAY
- khối cell (cột) chứa số lượng nhập là SLNHAP
- khối cell (cột) chứa số lương xuât là SLXUAT

Vậy bây giờ yêu cầu là làm được 1 cái hàm TONKHO, với cú pháp:
TONKHO(DATABASE,NGAY,MAHANG,SLNHAP,SLXUAT)​
Khi chạy, yêu cầu là:
Lấy cái MAHANG, đi dò trong DATABASE, tính ra số lượng tồn kho tính tới thời điểm NGAY (vẫn giả sử tồn kho đầu kỳ = 0)
2 tham số SLNHAP và SLXUAT là vị trí khối cell trong DATABASE chứa số lượng nhập và số lượng xuất.

Xin gửi kèm theo đây một cái Database đã được đặt tên sẵn cho các khối cell cần phải đặt, trong đó, các cột ngày tháng, mã hàng, số lượng nhập và số lương xuất không nằm liên tục nhau.

Dựa vào file Book2.xls này, ý đồ của tôi là có được một cái hàm để khi ta gõ (ở bất kỳ cell nào ngoài cái Database hoặc sử dụng trong VBA):
= TONKHO(DATABASE,"9/10/2007","G_3030",SLNHAP,SLXUAT)​
Thì sẽ cho ra số lượng tồn kho của mặt hàng G_3030 tại thời điểm ngày 9/10/2007.

---------------------
Xin nói rõ thêm, ở đây chúng ta có thể sử dụng những hàm như SUMIF, SUMPRODUCT để đạt được yêu cầu trên.
Nhưng ý định khi mở topic này là không dùng những hàm có sẵn của Excel, mà tự chế ra một hàm khác, trong VBA, để có thể sử dụng trong cả Excel lẫn VBA, nên mong các bác không đưa ra các giải đáp mà sử dụng hàm có sẵn.

Phức tạp nhỉ, đây là UF của em.

Khi chọn xong Database thì nhập cố cột ngày, mã . . . vào,
tức là trong Database thì nó là cột thứ mấy

PHP:
Function TonKho(MaHang As String, Ngay As Date, DTBS As Range, CotNgay As Byte, CotMa As Byte, CotNhap As Byte, CotXuat As Byte) As Long
    Application.Volatile (False)
    Dim i As Integer
    If Len(MaHang) = 0 Then Exit Function
    If DTBS.Rows.Count < 1 Then Exit Function
    If DTBS.Columns.Count < 4 Then Exit Function
    For i = 1 To DTBS.Rows.Count
        If DTBS(i, CotNgay) > Ngay Then Exit For
        If DTBS(i, CotMa) = MaHang Then TonKho = TonKho + DTBS(i, CotNhap) - DTBS(i, CotXuat)
    Next
    Set DTBS = Nothing
End Function


Thân!
 

File đính kèm

Upvote 0
Ô! Đúng là MrOKBap! Tài thật! Xin cảm ơn rất nhiều.
Sao ông Tía có thể làm ngắn thế nhỉ ?

Tuy nhiên, Bap ơi, có vấn đề đây.

Giả sử mình gõ (vào trong cái Book2.xla đã post lên) như sau:
=TonKho("G_3030","30/9/2007",DATA,1,10,12,13)
Đáp số sẽ là 846 (m2)

Nhưng nếu dùng SUMIF để kiểm tra lại thì nó phải bằng 846.2 (m2) cơ!
Bap làm mất của mình 0,2 m2 rồi... Hihi

Tại Bap dùng Tonkho... As Long đấy, sửa lại As Double thì mới có được 0,2 m2 này.

Cho mình hỏi thêm. Có cách nào, thay vì nhập số thứ tự của những cột tương ứng, thì mình nhập thẳng tên (Name) của nó không?

Thứ hai nữa, giải thích dùm mình cái này: Application.Volatile (False), hổng hiểu nơi...

Cảm ơn nhiều.
 
Upvote 0
BNTT đã viết:
Ô! Đúng là MrOKBap! Tài thật! Xin cảm ơn rất nhiều.
Sao ông Tía có thể làm ngắn thế nhỉ ?

Tuy nhiên, Bap ơi, có vấn đề đây.

Giả sử mình gõ (vào trong cái Book2.xla đã post lên) như sau:
=TonKho("G_3030","30/9/2007",DATA,1,10,12,13)
Đáp số sẽ là 846 (m2)

Nhưng nếu dùng SUMIF để kiểm tra lại thì nó phải bằng 846.2 (m2) cơ!
Bap làm mất của mình 0,2 m2 rồi... Hihi

Tại Bap dùng Tonkho... As Long đấy, sửa lại As Double thì mới có được 0,2 m2 này.

Cho mình hỏi thêm. Có cách nào, thay vì nhập số thứ tự của những cột tương ứng, thì mình nhập thẳng tên (Name) của nó không?

Thứ hai nữa, giải thích dùm mình cái này: Application.Volatile (False), hổng hiểu nơi...

Cảm ơn nhiều.
  1. Ngay em khai báo là date, còn của bác thì vẫn thể hiện là chuỗi, nếu muốn như bác thì thêm cái Val hoặc Cdbl nữa là xong (chuyển text sang số)
  2. Uh, không nghĩ là có thập phân
  3. Nếu dùng Name như bác thì lại là TH2 rồi (không khai báo Database)
  4. Bác đọc qua xíu nhé (Lười quá đấy)
Volatile Method

See AlsoApplies ToExampleSpecifics
Marks a user-defined function as volatile. A volatile function must be recalculated whenever calculation occurs in any cells on the worksheet. A nonvolatile function is recalculated only when the input variables change. This method has no effect if it's not inside a user-defined function used to calculate a worksheet cell.
expression.Volatile(Volatile)
expression Required. An expression that returns an Application object.
Volatile Optional Variant. True to mark the function as volatile. False to mark the function as nonvolatile. The default value is True
Example

This example marks the user-defined function "My_Func" as volatile. The function will be recalculated whenever calculation occurs in any cells on the worksheet on which this function appears.
Function My_Func() Application.Volatile ' ' Remainder of the function ">End Function


Thân!
 
Upvote 0
BNTT đã viết:


Cho mình hỏi thêm. Có cách nào, thay vì nhập số thứ tự của những cột tương ứng, thì mình nhập thẳng tên (Name) của nó không?

Cảm ơn nhiều.

Bác xem nhé :
PHP:
Function TonKho1(MaHang As String, Ngay As Date, _
                MangNgay As Range, MangMa As Range, MangNhap As Range, MangXuat As Range) As Long
    Application.Volatile (False)
    Dim i As Integer
    If Len(MaHang) = 0 Then Exit Function
    If MangNgay.Columns.Count > 1 Then Exit Function
    If MangMa.Columns.Count > 1 Then Exit Function
    If MangNhap.Columns.Count > 1 Then Exit Function
    If MangXuat.Columns.Count > 1 Then Exit Function
    If Not (MangNgay.Rows.Count = MangMa.Rows.Count And MangNgay.Rows.Count = MangNhap.Rows.Count _
            And MangNgay.Rows.Count = MangXuat.Rows.Count) Then Exit Function
    For i = 1 To MangNgay.Rows.Count
        If MangNgay(i) <= Ngay Then
            If MangMa(i) = MaHang Then TonKho1 = TonKho1 + MangNhap(i) - MangXuat(i)
        Else: Exit For: End If
    Next
    Set MangNgay = Nothing
    Set MangMa = Nothing
    Set MangNhap = Nothing
    Set MangXuat = Nothing
End Function
 

File đính kèm

Upvote 0
Tính tồn cho kho nào vậy? :)

Với lại ko hiểu MangNhap, MangXuat là gì?

Hình như các bạn đang tính NXT từ 1 sổ Nhật ký kho hàng tổng hợp (1 danh sách có hàng hóa, số lượng nhập, số lượng xuất) hay sao ấy chứ ko phải từ danh sách các chứng từ. Mình tưởng danh sách mỗi loại chứng từ nó phải nằm riêng rẽ các Sheets khác nhau chứ nhỉ? (Chứng từ nhập hàng để ở 1 nơi, chứng từ xuất hàng ở 1 nơi, v.v....). Thế các bạn cho chung vào 1 Sheet hết cả à?

Theo mình nghĩ, thông tin chứng từ cần thể hiện trên 2 sheets như sau:
Ví dụ Chứng từ "Phiếu nhập hàng"

Sheet1: Chứa nội dung chính của chứng từ

Mã chứng từ, Số chứng từ, Ngày chứng từ, Mã NCC, Mã Kho hàng, v.v....
1, PN001,'01/01/2007',1,1,...
2, PN002,'01/01/2007',1,1,...
....
n,.....

Sheet2: Chứa nội dung dòng hàng của chứng từ
STT, Mã chứng từ (Link với Mã CT ở trên), Mã hàng, Số lượng, Đơn giá, Thuế GTGT,....
1, 1, HH0001, 10, 12.000, VAT5,...
2, 1, HH0002, 5, 11.000, VAT5,...
3, 1, HH0003, 7, 13.000, VAT5,...
-----------------------------------
1, 2, HH0001, 10, 12.000, VAT5,...
2, 2, HH0002, 5, 11.000, VAT5,...
----------------------------------
.....
----------------------------------
1, n, HH001,....
 
Lần chỉnh sửa cuối:
Upvote 0
hai2hai đã viết:
Tính tồn cho kho nào vậy? :)

Với lại ko hiểu MangNhap, MangXuat là gì?

Hình như các bạn đang tính NXT từ 1 sổ Nhật ký kho hàng tổng hợp (1 danh sách có hàng hóa, số lượng nhập, số lượng xuất) hay sao ấy chứ ko phải từ danh sách các chứng từ. Mình tưởng danh sách mỗi loại chứng từ nó phải nằm riêng rẽ các Sheets khác nhau chứ nhỉ? (Chứng từ nhập hàng để ở 1 nơi, chứng từ xuất hàng ở 1 nơi, v.v....). Thế các bạn cho chung vào 1 Sheet hết cả à?
Bác Hai2hai thân, bài này không đề cập đến một kho cụ thể nào cả.
Nếu muốn làm hàm tính tồn kho theo ý của bác, thì em đã đưa topic này qua bõ Kế toán rồi.

Em chỉ muốn nêu vấn đề này ra, trước là làm một cái hàm tính tồn kho cho một một bảng tính bất kỳ (bất kỳ ở đây có nghĩa là có thể nằm trong bất kỳ một file nào đó hoặc một sheet nào đó), định dạng của nó có thể sẽ mỗi cái mỗi khác. Miễn là:
- Cột Ngày Tháng là cột đầu tiên và đã được sort rồi.
- Và có ít nhất 3 cột nữa: Mã Hàng Hóa, Số Lượng Nhập và Số Lượng Xuất.

Em nghĩ, hàm này sẽ có nhiều ứng dụng cho những bạn cần tìm số lượng tồn kho, cho một cửa hàng bán lẻ chẳng hạn, hay một cái kho be bé... Không nhất thiết phải làm kế toán, làm sổ sách chứng từ... Tuy nhiên vẫn có thể áp dụng cho kế toán, khi đó có thể sửa đổi đôi chút.

Thứ hai là, chủ yếu của em khi mở topic này, là chia sẻ khả năng viết hàm tự tạo. Thông qua hàm Tonkho này, với những trao đổi trên đây, có thể vận dụng để sáng tác ra nhiều loại hàm khác...

Thân.
 
Upvote 0
Cảm ơn Ông Tía nhiều.
Nhưng nè, cái Tonkho1 cũng phải set nó là Double chứ hả? Thấy Bap đã sửa cái Tonkho thành Double rồi mà Tonkho1 thì vẫn là Long.
Trong ví dụ của Bap, thì KIENG, là tấm kính, nên không có sổ lẻ, chứ gạch thì lẻ tới 4 số đấy Bap ơi.

Còn cái vụ Volatile, hì hì, hỏng phải lười đâu, nhưng khả năng tiếng Anh của mình thì chỉ có hạn thôi... Mình đã lùng trong Help và đã đọc qua rồi, nhưng không hiểu lắm. Nếu Bap rảnh, dịch sơ sơ dùm chút đi.


Nếu không có bác nào có giải pháp khác, em xin tạm đưa ra cú pháp hàm này nhé. Tác giả xin ghi là Mr OkBap.
PHP:
Function TonKho(MaHang As String, Ngay As Date, _
                MangNgay As Range, MangMa As Range, MangNhap As Range, MangXuat As Range) As Double
    Application.Volatile (False)
    Dim i As Integer
    If Len(MaHang) = 0 Then Exit Function
    If MangNgay.Columns.Count > 1 Then Exit Function
    If MangMa.Columns.Count > 1 Then Exit Function
    If MangNhap.Columns.Count > 1 Then Exit Function
    If MangXuat.Columns.Count > 1 Then Exit Function
    If Not (MangNgay.Rows.Count = MangMa.Rows.Count And MangNgay.Rows.Count = MangNhap.Rows.Count _
            And MangNgay.Rows.Count = MangXuat.Rows.Count) Then Exit Function
    For i = 1 To MangNgay.Rows.Count
        If MangNgay(i) <= Ngay Then
            If MangMa(i) = MaHang Then TonKho = TonKho + MangNhap(i) - MangXuat(i)
        Else: Exit For: End If
    Next
    Set MangNgay = Nothing
    Set MangMa = Nothing
    Set MangNhap = Nothing
    Set MangXuat = Nothing
End Function
Trong đó:
  • MaHang: Mã hàng cần kiểm tồn kho
  • Ngay: Ngày cần kiểm số lượng tồn kỳ (kể từ ngày đầu tiên nhập mặt hàng nay)
  • MangNgay: Cột chứa danh sách Ngày Tháng Năm
  • MangMa: Cột chứa danh sách Mã Hàng Hóa
  • MangNhap: Cột chứa Số Lượng Nhập
  • MangXuat: Cột chứa Số Lượng Xuất

Nhân tiện, cũng xin đưa sang bài UDF tính công nợ tại một thời điểm bất kỳ một hàm tương tự.
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom