เราก็ได้เรียนรู้ความรู้พื้นฐานหลายๆ เรื่องไปแล้ว คราวนี้ขอพักเปลี่ยนหัวข้อมาดูเรื่องที่จะช่วยให้รายงานเรามีลูกเล่นเจ๋งๆ เพิ่มขึ้นด้วยการดึงค่าจาก Slicer มาคำนวณใน Report กันบ้างครับ (พอดีมีคน inbox มาถามด้วยล่ะ 55)
สารบัญ
ไฟล์ประกอบ
ใช้ไฟล์เดิมจากตอนก่อนหน้าได้เลยนะครับ หรือจะใช้อันนี้ก็ได้
ก่อนอื่น ลองสร้าง Table หรือ Matrix ขึ้นมาก่อน ลากสรุปผลยอดขายของแต่ละ ProductCategory ประมาณนี้
ตัวอย่างการดึงค่าจาก Slicer มาใช้คำนวณใน Visual
- การปรับตัวเลข TotalRevenue เป็นหน่วยต่างๆ เช่น เลขปกติ หารพัน หารล้าน
- การปรับสกุลเงิน เช่น BHT USD JPY
ปรับตัวเลขที่เป็นตัวหาร
เคสนี้เป็นตัวอย่างที่ Simple ที่สุด เพราะว่าเราจะสร้าง Slicer ที่มีเลข 1 , 1000, 1000000 แค่ 3 ตัว แล้วพอเลือกตัวไหน เราก็จะเอาตัวเลขนั้นมาใช้เป็นตัวหารเลย
จะมี Slicer ได้ ก็ต้องมีคอลัมน์ก่อน แต่คอลัมน์นี้จะต้องไม่มา Filter ผลลัพธ์ของตารางของเราด้วย ดังนั้นเราจะสร้าง Table ที่แยกออกไปต่างหาก และไม่ต้องผูก Relationship กับตารางอื่นเลย
ให้ไปกด Enter Data แล้วใส่ประมาณนี้ลงไป
แล้วเราก็จะได้ตารางแยกออกมาเดี่ยวๆ ซึ่งเราไม่ต้องไปผูก Relationship กับใครนะ
จากนั้นเราลาก Field หัวหาร มาเป็น Slicer แบบ List
จากนั้นลองสร้าง Measure เพื่อดึงค่าจาก Field ตัวหารดู ซึ่งฟังก์ชันที่เรารู้จัก และพอใช้ได้ก็คือ VALUES หรือ DISTINCT ก็ได้
Measureดึงตัวหาร = VALUES('Tableตัวหาร'[ตัวหาร])
มันสามารถดึงค่ามาได้ดีเลย ทีนี้ถ้าเกิดเราสร้าง Measure ใหม่ ให้ TotalRevenue หารด้วย Measure ดึงตัวหาร เราก็จะเปลี่ยนหน่วยได้
TotalRevenueเปลี่ยนหน่วย = [TotalRevenue]/[Measureดึงตัวหาร]
อย่างไรก็ตาม วิธีที่เราเพิ่งทำไปมันมีจุดอ่อนอยู่ ก็คือ หากคนใช้ Report ดันแกล้งเลือกตัวหารมากกว่า 1 ตัว หรือแม้แต่การ clear การเลือก item ใน slicer ออกไปเลย (จะแปลว่าเลือกทุกตัว) ก็จะทำให้ เจ้า Visual ของเราพังทันที!
เมื่อกด See Details ก็จะพบว่า มัน Error เพราะว่า Measure ดึงตัวหารมันต้องการค่าเดียว แต่เราดันส่งให้มันหลายค่านั่นเอง…
ทางแก้ไขในการดึงค่าจาก Slicer ทำได้หลายแบบ เช่น
ใช้ IF + COUNTROWS
TotalRevenueเปลี่ยนหน่วย =
VAR divider =
IF (
COUNTROWS ( VALUES ( 'Tableตัวหาร'[ตัวหาร] ) ) = 1,
VALUES ( 'Tableตัวหาร'[ตัวหาร] ),
1
)
RETURN
[TotalRevenue] / divider
concept คือเช็คจำนวนแถวของ Tableตัวหาร'[ตัวหาร] ซะใช่ 1 แถวรึเปล่า? (ถ้าเลือก Slicer ค่าเดียว มันจะ Filter ตาราง Tableตัวหาร ให้เหลือแค่ 1 Row ซึ่งถ้า COUNTROWS ได้ 1 ก็จะให้ผลลัพธ์เป็น TRUE นั่นเอง
พอเป็น TRUE เราก็ค่อยให้เอาค่าจากคอลัมน์ Tableตัวหาร'[ตัวหาร] แต่พอไม่ใช่ TRUE เราก็ให้เป็นเลข 1 ไปก่อน ค่าที่ได้จะได้ไม่ Error
แต่ถ้าเราไม่อยากเขียนเทียบกับ 1 ให้ยุ่งยาก ก็สามารถใช้อีกฟังก์ชันนึงนั่นก็คือ HASONEVALUE ได้ ถ้าคอลัมน์นั้นมีแค่ค่าเดียว ก็จะได้ผลลัพธ์เป็น TRUE เช่นกัน ตามตัวอย่างข้างล่าง
ใช้ IF + HASONEVALUE
TotalRevenueเปลี่ยนหน่วย =
VAR divider =
IF (
HASONEVALUE ( 'Tableตัวหาร'[ตัวหาร] ),
VALUES ( 'Tableตัวหาร'[ตัวหาร] ),
1
)
RETURN
[TotalRevenue] / divider
หรือถ้าขี้เกียจไปกว่านั้นอีก ก็มีฟังก์ชันอีกตัวที่ทำให้สูตรเขียนง่ายขึ้นไปอีก นั่นก็คือ
SELECTEDVALUE
SELECTEDVALUE(<columnName>[, <alternateResult>])
SELECTEDVALUE มีความสามารถในการเช็คว่า <columnName> ที่ระบุ มีค่าเดียวรึเปล่า? ถ้ามีค่าเดียวก็จะให้ผลเป็นค่านั้นเลย แต่ถ้าไม่ได้มีค่าเดียวจะให้ผลเป็น <alternateResult> แทน เช่น
TotalRevenueเปลี่ยนหน่วย =
VAR divider =
SELECTEDVALUE ( 'Tableตัวหาร'[ตัวหาร], 1 )
RETURN
[TotalRevenue] / divider
และเพื่อให้อ่านผลได้เนียนขึ้น เราน่าจะต้องใส่หน่วยลงไปด้วย เช่น
TotalRevenueเปลี่ยนหน่วย =
VAR divider =
SELECTEDVALUE ( 'Tableตัวหาร'[ตัวหาร], 1 )
VAR numResult = [TotalRevenue] / divider
VAR textResult =
FORMAT ( numResult, "#,##0.00" )
RETURN
SWITCH (
divider,
1, numResult,
1000, textResult & " K",
1000000, textResult & " M"
)
การปรับสกุลเงิน
ให้เราเตรียม Table สกุลเงินที่ต้องการจะเลือกเอาไว้ พร้อมกับตัวเลขอัตราแลกเปลี่ยนเมื่อเทียบกับเงินบาท ( Assume ว่าค่าตัวเลขปัจจุบันที่เราคำนวณอยู่ปกติเป็นสกุลบาทนะ)
ในบทความนี้ผมจะเอาอัตราแปลกเปลี่ยนมาจากในเว็บ SCB ละกัน test แล้วเร็วดี
https://www.scb.co.th/th/personal-banking/foreign-exchange-rates.html
สั่ง Get Data from Web ซะ
ที่นี้ Rate ของ JPY มันจะประหลาดตรงที่ว่ามันคิดต่อ 100 เยน ดังนั้นต้องระวังไว้ด้วย
ผมได้ทำ Query ให้แล้ว แต่ขอไม่อธิบายละเอียด หลักๆ คือเลือกเอาบางคอลัมน์ แล้ว Split เอาตัวย่อกับ Rate ออกมาใช้ เพื่อนๆ สามารถเอา Code นี้ใส่ไว้ใน Advanced Editor ได้เลย
let
Source = Web.Page(Web.Contents("https://www.scb.co.th/th/personal-banking/foreign-exchange-rates.html")),
Data2 = Source{2}[Data],
#"Changed Type" = Table.TransformColumnTypes(Data2,{{"FOREIGN CURRENCIES", type text}, {"BANK SELLS D/D & T/T", type text}, {"BANK SELLS NOTES", type text}, {"BANK BUYS TT", type text}, {"BANK BUYS EXPORT SIGHT BILL", type text}, {"BANK BUYS T/CHQS. & CHQS.", type text}, {"BANK BUYS NOTES", type text}}),
#"Removed Other Columns" = Table.SelectColumns(#"Changed Type",{"FOREIGN CURRENCIES", "BANK SELLS NOTES"}),
#"Removed Top Rows" = Table.Skip(#"Removed Other Columns",2),
#"Split Column by Delimiter" = Table.SplitColumn(#"Removed Top Rows", "FOREIGN CURRENCIES", Splitter.SplitTextByEachDelimiter({"#(lf)"}, QuoteStyle.Csv, false), {"FOREIGN CURRENCIES.1", "FOREIGN CURRENCIES.2"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"FOREIGN CURRENCIES.1", type text}, {"FOREIGN CURRENCIES.2", type text}}),
#"Trimmed Text" = Table.TransformColumns(#"Changed Type1",{{"FOREIGN CURRENCIES.1", Text.Trim, type text}, {"FOREIGN CURRENCIES.2", Text.Trim, type text}}),
#"Renamed Columns" = Table.RenameColumns(#"Trimmed Text",{{"FOREIGN CURRENCIES.1", "FXshort"}, {"FOREIGN CURRENCIES.2", "FXdesc"}, {"BANK SELLS NOTES", "Rate"}}),
#"Changed Type2" = Table.TransformColumnTypes(#"Renamed Columns",{{"Rate", type number}}),
#"Replaced Errors" = Table.ReplaceErrorValues(#"Changed Type2", {{"Rate", null}})
in
#"Replaced Errors"
จากนั้นตั้งชื่อ Query ว่า FXRateTable แล้ว Close & Apply ซะ
จากนั้นเราจะได้ FXRateTable ออกมาหน้าตาประมาณนี้
และใน Data Model ก็ไม่ได้ต้องไปผูก Relationship เช่นเคย
จากนั้นเราสร้าง Visual ที่มี Slicer เป็น FXshort ให้กดเลือกสกุลเงินที่ต้องการ (ผมปรับรูปแบบ Orientation ให้เป็น Horizontal เพื่อความสวยงาม)
จากนั้นสร้าง Measure ชื่อว่า FXRate ด้วยสูตรดังนี้ เพื่อใช้เป็นตัวดึงค่าจาก Slicer นั่นเอง
FXRate = SELECTEDVALUE(FXRateTable[Rate],1)
และสร้าง Measure ที่จะแสดง TotalRevenue แบบสกุลเงินอื่นได้ ชื่อว่า TotalRevenueFX
TotalRevenueFX =
VAR currentrate=[FXRate]
RETURN[TotalRevenue]/currentrate
ทีนี้เราต้องแก้เรื่อง JPY เล็กน้อย เพราะ Rate ที่ให้มามันเป็นการคิดต่อ 100 YEN ไม่ใช่ 1 YEN
ดังนั้นให้กลับไปแก้ Measure FX Rate ให้เป็นแบบนี้
FXRate =
IF (
SELECTEDVALUE ( FXRateTable[FXshort] ) = "JPY",
SELECTEDVALUE ( FXRateTable[Rate] ) / 100,
SELECTEDVALUE ( FXRateTable[Rate], 1 )
)
แปลว่าให้เช็คก่อนว่าเลือกมาเป็น JPY รึเปล่า? ถ้าใช่ให้เอา Rate ที่ได้ไปหาร 100 (เพื่อให้เป็น Rate ต่อ 1 YEN) นอกนั้นก็เช็คว่า Rate ที่ได้มีค่าเดียวรึเปล่า? ถ้ามีหลายค่าให้ทำ FXRate ให้เป็น 1 ซะ เพราะแปลว่าไม่ได้เลือกสกุลไหนเลย (หรือเลือกมาหลายอัน) นั่นเอง
จากนี้ จะเอาคำว่า Yen มาต่อท้ายตัวเลข คล้ายๆ กับที่เราทำ K กับ M ตอนแปลงหน่วยก็ย่อมได้ แต่ผมขี้เกียจทำแล้วล่ะ เพื่อนๆ ลองไปประยุกต์ทำกันเองนะ แล้วมาบอกด้วยล่ะว่าทำได้รึเปล่า อิอิ
และนี่ก็คือวิธีดึงค่าจาก Slicerทั้งหมดที่ผมอยากจะแนะนำให้รู้จัก หวังว่าเพื่อนๆ น่าจะพอเห็นภาพและสามารถนำไปประยุกต์ใช้กับงานของตัวเองได้นะครับ
สารบัญ Series Power BI
- POWER BI ตอนที่ 01: POWER BI คืออะไร?
- POWER BI ตอนที่ 02: พื้นฐาน EXCEL ที่สำคัญก่อนจะเรียนรู้ POWER BI
- POWER BI ตอนที่ 03: ภาพรวมการใช้งาน POWER BI DESKTOP
- POWER BI ตอนที่ 04: สร้าง REPORT แรก ใน POWER BI
- POWER BI ตอนที่ 05: วิธีการ DRILL เพื่อเจาะลึกข้อมูลใน REPORT
- POWER BI ตอนที่ 06: การปรับแต่งสีใน VISUAL ด้วย CONDITIONAL FORMAT
- POWER BI ตอนที่ 07: เริ่ม GET DATA ตั้งแต่ไฟล์ยังว่างเปล่า
- POWER BI ตอนที่ 08: สร้าง DATA MODEL ที่เหมาะสม
- POWER BI ตอนที่ 09: สร้าง DATE TABLE ด้วย DAX
- POWER BI ตอนที่ 10: เรียนรู้ DAX เบื้องต้น
- POWER BI ตอนที่ 11: เรียนรู้ DAX Table Function – FILTER
- POWER BI ตอนที่ 12: DISTINCT, VALUES, ALL และผองเพื่อน
- POWER BI ตอนที่ 13: CALCULATE ฟังก์ชันที่ทรงพลังที่สุดใน DAX
- Power BI ตอนที่ 14: Context Transition และ พลังแฝงใน Measure
- Power BI ตอนที่ 15: วิธีดึงค่าจาก Slicer มาคำนวณใน Report
- Power BI ตอนที่ 16 : เดินทางข้ามเวลาไปกับ Time Intelligence DAX Function
- Power BI ตอนที่ 17 : วิธีทำรายงานเทียบเป้าหมาย Target vs Actual
- Power BI ตอนที่ 18 : วิธีการกระจายเป้า Allocate Target ด้วย DAX
- Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension
- ส่วนเสริม
- การคำนวณต้นทุนแบบ FIFO ด้วย DAX
- แสดงข้อมูลสรุปแบบ Top N + Others (ฉบับเทพเอ็กเซล)
- การวิเคราะห์ Event ที่มีช่วงเวลาเริ่มต้นกับสิ้นสุดคนละวัน
- เปรียบเทียบ MAX vs LASTDATE ในภาษา DAX
ใครสนใจอยากเรียนเป็นคลิปวีดีโอ ผมมี