Tình số tồn đầu kỳ trong Power bi bằng DAX (4 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Tôi tuân thủ nội quy khi đăng bài

duongapt2024

Thành viên mới
Tham gia
5/6/24
Bài viết
8
Được thích
0
Dear Anh Chị,
Em cần trợ giúp về DAX trong Power bi như sau.
Em cám ơn
Nhaphang=if( (openstock -sudung)<Safety stock,safety stock,0)
OPENSTOCK=
nếu tháng=1 thì openstock=tondaunam
ngược lại openstock=closingtock của tháng trước
Closingtock=openstock+nhaphang-sudung
 
A circular dependency was detected
nó báo lỗi này nè huynh
Dax không có đệ quy, làm tham chiếu vòng vậy trong Dax xử lý rất mệt. Bài này tốt nhất là dùng VBA hoặc các ngôn ngữ lập trình có hỗ trợ đệ quy.
Nếu vấn muốn dùng Dax thì tính thủ công từng tháng 1: tính tồn đầu kỳ, nhập hàng, sử dụng=> tính được Closingstock T1=tồn đầu kỳ T2, tính nhập hàng T2, sử dụng T2=> tính được Closingstock T2, tính tương tự như vậy, khá là thủ công. Tốt nhất nên dùng cái nào có đệ quy mà xử lý! Hoặc bạn có thể xử lý nó bằng Power Query( viết tắt PQ), PQ sử dụng List.Accumulate có xử lý được nhé! Còn làm bằng Dax thì rất mệt đó!
 
Dax không có đệ quy, làm tham chiếu vòng vậy trong Dax xử lý rất mệt. Bài này tốt nhất là dùng VBA hoặc các ngôn ngữ lập trình có hỗ trợ đệ quy.
Nếu vấn muốn dùng Dax thì tính thủ công từng tháng 1: tính tồn đầu kỳ, nhập hàng, sử dụng=> tính được Closingstock T1=tồn đầu kỳ T2, tính nhập hàng T2, sử dụng T2=> tính được Closingstock T2, tính tương tự như vậy, khá là thủ công. Tốt nhất nên dùng cái nào có đệ quy mà xử lý! Hoặc bạn có thể xử lý nó bằng Power Query( viết tắt PQ), PQ sử dụng List.Accumulate có xử lý được nhé! Còn làm bằng Dax thì rất mệt đó!
Thanks Huynh. Khổ cái cái nào cũng gà hết
 
Chào bạn,
Mình rất vui được hỗ trợ bạn về vấn đề DAX trong Power BI. Để có thể giải quyết vấn đề một cách hiệu quả nhất, mình xin phép được phân tích và đưa ra giải pháp từng phần một nhé.
Phân tích vấn đề:
Từ các công thức bạn cung cấp, mình hiểu rằng bạn đang cố gắng xây dựng một mô hình quản lý tồn kho đơn giản trong Power BI, với các yếu tố chính sau:
  • Nhaphang: Số lượng hàng hóa nhập vào trong tháng.
  • Openstock: Số lượng hàng tồn kho đầu kỳ của tháng.
  • Safety stock: Số lượng hàng tồn kho tối thiểu cần duy trì.
  • Closingtock: Số lượng hàng tồn kho cuối kỳ của tháng.
  • Sudung: Số lượng hàng hóa đã sử dụng trong tháng.
Các công thức của bạn đã thể hiện một logic khá rõ ràng:
  • Nhaphang: Nếu số lượng hàng tồn kho sau khi trừ đi số lượng đã sử dụng nhỏ hơn số lượng hàng tồn kho tối thiểu, thì số lượng nhập hàng sẽ bằng số lượng cần để đạt đến mức hàng tồn kho tối thiểu, ngược lại sẽ bằng 0.
  • Openstock: Số lượng hàng tồn kho đầu kỳ sẽ bằng tồn đơ đầu năm nếu là tháng 1, còn lại sẽ bằng số lượng hàng tồn kho cuối kỳ của tháng trước.
  • Closingtock: Số lượng hàng tồn kho cuối kỳ sẽ bằng tổng số lượng hàng tồn kho đầu kỳ, cộng với số lượng nhập hàng và trừ đi số lượng đã sử dụng.
Giải pháp DAX:
Để triển khai các công thức này trong Power BI, chúng ta sẽ tạo các cột tính toán (calculated columns) và các thước đo (measures).
1. Tạo bảng dữ liệu:
Trước tiên, bạn cần tạo một bảng dữ liệu trong Power BI chứa các cột sau:
  • Tháng: Tháng trong năm.
  • Tondaunam: Tồn kho đầu năm.
  • Nhaphang: Số lượng nhập hàng (sẽ được tính toán bằng DAX).
  • Sudung: Số lượng đã sử dụng.
  • Safetystock: Số lượng hàng tồn kho tối thiểu.
  • Openstock: Số lượng hàng tồn kho đầu kỳ (sẽ được tính toán bằng DAX).
  • Closingtock: Số lượng hàng tồn kho cuối kỳ (sẽ được tính toán bằng DAX).
2. Tạo cột tính toán và thước đo:
  • Cột tính toán Openstock:
    Code snippet
    Openstock =
    VAR ThangTruoc = [Thang] - 1
    RETURN
    IF([Thang] = 1, [Tondaunam],
    CALCULATE([Closingtock], FILTER(ALL('TableName'), 'TableName'[Thang] = ThangTruoc)))

    Công thức này kiểm tra xem nếu tháng hiện tại là tháng 1 thì lấy giá trị từ cột Tondaunam, ngược lại sẽ tính toán giá trị Closingtock của tháng trước.
  • Cột tính toán Nhaphang:
    Code snippet
    Nhaphang =
    VAR TonKhoSauKhiSuDung = [Openstock] - [Sudung]
    RETURN
    IF(TonKhoSauKhiSuDung < [Safetystock], [Safetystock] - TonKhoSauKhiSuDung, 0)

    Công thức này tính toán số lượng nhập hàng dựa trên logic đã nêu ở trên.
  • Cột tính toán Closingtock:
    Code snippet
    Closingtock = [Openstock] + [Nhaphang] - [Sudung]
Lưu ý:
  • TableName: Bạn cần thay thế 'TableName' bằng tên thực tế của bảng dữ liệu của bạn.
  • Thang: Tên cột đại diện cho tháng trong bảng dữ liệu của bạn.
  • Tùy chỉnh: Bạn có thể tùy chỉnh các công thức này để phù hợp hơn với cấu trúc dữ liệu và yêu cầu cụ thể của bạn.
3. Sử dụng các thước đo:
Bạn có thể tạo các thước đo để tính toán các chỉ số khác như tổng nhập hàng trong năm, tổng sử dụng trong năm, ... bằng cách sử dụng hàm SUM hoặc các hàm khác của DAX.
Ví dụ:
Code snippet
TongNhaphangNam = SUM('TableName'[Nhaphang])

Những điểm cần lưu ý:
  • Trật tự tính toán: Đảm bảo rằng các cột tính toán được tính toán đúng thứ tự.
  • Hiệu suất: Nếu bạn có một lượng lớn dữ liệu, hãy tối ưu hóa các công thức DAX để cải thiện hiệu suất.
  • Kiểm tra kết quả: Luôn kiểm tra kỹ lưỡng các kết quả tính toán để đảm bảo chúng chính xác.
Hỗ trợ thêm:
Nếu bạn gặp bất kỳ khó khăn nào trong quá trình triển khai, hãy cung cấp thêm thông tin chi tiết về cấu trúc dữ liệu của bạn, các lỗi mà bạn gặp phải, và các câu hỏi cụ thể của bạn.
Mình sẽ cố gắng hỗ trợ bạn hết mình để bạn có thể xây dựng được một mô hình quản lý tồn kho hiệu quả trong Power BI.
Ngoài ra, bạn có thể tham khảo thêm các tài liệu sau:
Chúc bạn thành công!
Bạn thử chạy closingstock xem có ra kết quả không, bạn phải giải quyết vấn đề tham chiếu vòng ở công thức closing stock mới ra kết quả được.
Nếu bạn viết ra được kết quả này thì đúng:
1729665594495.png
 
Lần chỉnh sửa cuối:
Bạn thử chạy closingstock xem có ra kết quả không, bạn phải giải quyết vấn đề tham chiếu vòng ở công thức closing stock mới ra kết quả được.
Nếu bạn viết ra được kết quả này thì đúng:
View attachment 304977
1729689219604.pngvẫn bị lổi vòng tròn huyn hơi
Bài đã được tự động gộp:

Bạn thử chạy closingstock xem có ra kết quả không, bạn phải giải quyết vấn đề tham chiếu vòng ở công thức closing stock mới ra kết quả được.
Nếu bạn viết ra được kết quả này thì đúng:
View attachment 304977
 
Lần chỉnh sửa cuối:
Ủa bạn, tôi có làm bằng Dax đâu tôi làm bằng PQ mà, nếu bạn xài Pq hoặc R hoặc python thì tôi viết cho bạn. Còn Dax là tôi chịu, do bạn vẫn muốn viết Dax nên tôi không phản hồi thêm đó!
Trời vậy mà e cứ tưởng dax,vậy cho e xin PQ với
 
Trời vậy mà e cứ tưởng dax,vậy cho e xin PQ với
Đây bạn, lý ra bạn phải nói sớm hơn chứ!:
JavaScript:
let
    Source = Excel.Workbook(File.Contents("C:\Users\Admin\Downloads\bom.xlsx"), null, true),
    _Tbl = Table.Sort(Source{[Item="Table1",Kind="Table"]}[Data], {{"thang", Order.Ascending}}),
    CalcStock = List.Accumulate(
        Table.ToRecords(_Tbl),
        {}, 
        (state, current) =>
            let
                prevClosingStock = if List.IsEmpty(state) then current[ton_dau_ky] else List.Last(state)[ClosingStock],
                NhapHang = if (prevClosingStock - current[nhucau_sudung]) < current[safety_sotck] then current[safety_sotck] else 0,
                ClosingStock = prevClosingStock + NhapHang - current[nhucau_sudung],
                newRecord = Record.AddField(Record.AddField(Record.AddField(current, "OpenStock", prevClosingStock), "NhapHang", NhapHang), "ClosingStock", ClosingStock)
            in
                state & {newRecord}
    ),
    CType = Table.TransformColumnTypes(
        Table.FromRecords(CalcStock),
        {{"nam", Int64.Type}, {"thang", Int64.Type}, {"alldaykey", type date}, {"Plant", Int64.Type}, {"material_Raw", Int64.Type}, {"Description RMs", type text}, {"UoM2", type text}, {"Bom", type number}, {"safety_sotck", Int64.Type}, {"nhucau_sudung", Int64.Type}, {"ton_dau_ky", Int64.Type}, {"OpenStock", Int64.Type}, {"NhapHang", Int64.Type}, {"ClosingStock", Int64.Type}}
    )
in
    CType
Dữ liệu của bạn tháng 8 không đúng, bị âm tồn.
 

File đính kèm

Đây bạn, lý ra bạn phải nói sớm hơn chứ!:
JavaScript:
let
    Source = Excel.Workbook(File.Contents("C:\Users\Admin\Downloads\bom.xlsx"), null, true),
    _Tbl = Table.Sort(Source{[Item="Table1",Kind="Table"]}[Data], {{"thang", Order.Ascending}}),
    CalcStock = List.Accumulate(
        Table.ToRecords(_Tbl),
        {},
        (state, current) =>
            let
                prevClosingStock = if List.IsEmpty(state) then current[ton_dau_ky] else List.Last(state)[ClosingStock],
                NhapHang = if (prevClosingStock - current[nhucau_sudung]) < current[safety_sotck] then current[safety_sotck] else 0,
                ClosingStock = prevClosingStock + NhapHang - current[nhucau_sudung],
                newRecord = Record.AddField(Record.AddField(Record.AddField(current, "OpenStock", prevClosingStock), "NhapHang", NhapHang), "ClosingStock", ClosingStock)
            in
                state & {newRecord}
    ),
    CType = Table.TransformColumnTypes(
        Table.FromRecords(CalcStock),
        {{"nam", Int64.Type}, {"thang", Int64.Type}, {"alldaykey", type date}, {"Plant", Int64.Type}, {"material_Raw", Int64.Type}, {"Description RMs", type text}, {"UoM2", type text}, {"Bom", type number}, {"safety_sotck", Int64.Type}, {"nhucau_sudung", Int64.Type}, {"ton_dau_ky", Int64.Type}, {"OpenStock", Int64.Type}, {"NhapHang", Int64.Type}, {"ClosingStock", Int64.Type}}
    )
in
    CType
Dữ liệu của bạn tháng 8 không đúng, bị âm tồn.
Nhaphang=if( (openstock -sudung)<Safety stock, roundup((safety stock-(openstock -sudung))/moq,0)*moq,0)=>khong co am, luc noa cung >=Safety stock
vì không biết viết sao nên rut gọn cho đơn giản,
 
Nhaphang=if( (openstock -sudung)<Safety stock, roundup((safety stock-(openstock -sudung))/moq,0)*moq,0)=>khong co am, luc noa cung >=Safety stock
vì không biết viết sao nên rut gọn cho đơn giản,
Ý tôi nói nó âm vì logic quản lý hàng tồn của bạn nó có vấn đề đó.
Thứ nhất: thuật ngữ cần phải rõ ràng, openstock-sudung, cái này bạn phải viết đúng là openstock- nhu cầu sử dụng chứ không ai tham chiếu việc nhập hàng vào cái đã sử dụng rồi, thế thì có ý nghĩa gì, phải tham chiếu trên dự báo nhu cầu cần sử dụng là bao nhiêu chứ!
Thứ 2: Bạn không thể sử dụng roundup((safety stock-(openstock -sudung))/moq,0)*moq,0), đơn giản vì sao, nếu bạn làm như vậy sẽ dẫn đến tình trạng nhập hàng quá mức, dẫn tới tồn kho quá cao không cần thiết, lãng phí tài nguyên, vì bạn đang làm tròn lượng hàng cần lên tới Moq, tôi ví dụ Moq là 100, tồn tiêu chuẩn - tồn hiện tại sau sử dụng là 10, tức là bạn chỉ cần nhập 10 mà bạn nhập lên tận moq là 100 thế là lãng phí có thể dẫn đến dư thừa tồn kho và làm hạn sử dụng xấu đi.
 
Lần chỉnh sửa cuối:
Ý tôi nói nó âm vì logic quản lý hàng tồn của bạn nó có vấn đề đó.
Thứ nhất: thuật ngữ cần phải rõ ràng, openstock-sudung, cái này bạn phải viết đúng là openstock- nhu cầu sử dụng chứ không ai tham chiếu việc nhập hàng vào cái đã sử dụng rồi, thế thì có ý nghĩa gì, phải tham chiếu trên dự báo nhu cầu cần sử dụng là bao nhiêu chứ!
Thứ 2: Bạn không thể sử dụng roundup((safety stock-(openstock -sudung))/moq,0)*moq,0), đơn giản vì sao, nếu bạn làm như vậy sẽ dẫn đến tình trạng nhập hàng quá mức, dẫn tới tồn kho quá cao không cần thiết, lãng phí tài nguyên, vì bạn đang làm tròn lượng hàng cần lên tới Moq, tôi ví dụ Moq là 100, tồn tiêu chuẩn - tồn hiện tại sau sử dụng là 10, tức là bạn chỉ cần nhập 10 mà bạn nhập lên tận moq là 100 thế là lãng phí có thể dẫn đến dư thừa tồn kho và làm hạn sử dụng xấu đi.
Ha hả.huynh nói đúng.
Bên em còn dùng actual là thực tế sử dụng nữa.
Còn roundup vì ko bao giờ để dưới safety_sotck. Còn moq thì đơn vị giao nguyen cont hàng không giao lẻ.
Cũng có packsize nữa nhưng hiếm khi giao hàng theo kiểu này lắm. Nguyen liẹu mua từ nước ngoài ko ak
 
Web KT

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

Back
Top Bottom