SCAN วนลูปผ่าน array โดยใช้ LAMBDA function คำนวณค่าสะสม (accumulator) และ return array ที่แสดงค่าสะสมในทุกขั้นตอนของการคำนวณ ต่างจาก REDUCE ที่ return เฉพาะค่าสุดท้าย SCAN เหมาะสำหรับ Running Total, Running Maximum/Minimum, การคำนวณดอกเบี้ยทบต้น หรือการแสดงผลลัพธ์แบบต่อเนื่องที่ต้องการเห็นทุกขั้นตอนของการเปลี่ยนแปลง ใช้งานได้ใน Excel 365 และ Excel 2024
=SCAN([initial_value], array, lambda)
=SCAN([initial_value], array, lambda)
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| initial_value | Any | Optional | 0 | ค่าเริ่มต้นของ accumulator ก่อนเริ่มวนลูป สำหรับตัวเลขใช้ 0 หรือ 1 (ขึ้นกับการคำนวณ) สำหรับข้อความใช้ “” (empty string) ถ้าไม่ระบุ Excel จะใช้ค่าเริ่มต้นตามชนิดข้อมูล |
| array | Array/Range | Yes | Array, range, หรือ Named Range ที่ต้องการวนลูป SCAN จะประมวลผลทีละ element จากบนลงล่าง (column) หรือซ้ายไปขวา (row) สามารถใช้ Table reference หรือ SEQUENCE, FILTER ได้ | |
| lambda | Function | Yes | LAMBDA function ที่รับ 2 parameters: (1) accumulator (acc/a) = ค่าสะสมจากรอบก่อนหน้า (2) value (val/v) = ค่าปัจจุบันของ element และต้อง return ค่า accumulator ใหม่สำหรับรอบถัดไป สามารถใช้ชื่อฟังก์ชันโดยตรง (MAX, MIN, SUM) แทน LAMBDA ได้ (Abbreviated Syntax) |
คำนวณยอดขายสะสมรายเดือน แสดง Year-to-Date (YTD) หรือ Month-to-Date (MTD) เพื่อติดตามประสิทธิภาพการขายเทียบกับเป้าหมาย
ติดตามราคาหุ้นสูงสุด/ต่ำสุดสะสม แสดงว่าราคาหุ้นทำ All-Time High หรือ All-Time Low ในช่วงเวลาใด
เติมค่าในเซลล์ว่างด้วยค่าจากเซลล์ก่อนหน้า เหมาะสำหรับข้อมูลที่มีช่องว่างและต้องการเติมด้วยค่าล่าสุด
แสดงยอดเงินหลังคำนวณดอกเบี้ยทบต้นในแต่ละงวด เห็นการเติบโตของเงินลงทุนตลอดระยะเวลา
นับจำนวนสะสมของข้อมูลที่ผ่านเงื่อนไข เช่น นับจำนวนวันที่อุณหภูมิสูงกว่า 30 องศา
SCAN(0, {10, 20, 30, 40, 50}, LAMBDA(acc, val, acc + val))=SCAN(0, {10, 20, 30, 40, 50}, LAMBDA(acc, val, acc + val))
{10, 30, 60, 100, 150}
SCAN(0, Sales[MonthlyRevenue], LAMBDA(acc, val, acc + val))=SCAN(0, Sales[MonthlyRevenue], LAMBDA(acc, val, acc + val))
Array ของ Running Total ตาม MonthlyRevenue
SCAN(0, {85, 92, 78, 95, 88, 97}, LAMBDA(acc, val, MAX(acc, val)))=SCAN(0, {85, 92, 78, 95, 88, 97}, LAMBDA(acc, val, MAX(acc, val)))
{85, 92, 92, 95, 95, 97}
SCAN(0, {3, 7, 2, 9, 5}, MAX)=SCAN(0, {3, 7, 2, 9, 5}, MAX)
{3, 7, 7, 9, 9}
SCAN(0, {10, "N/A", 25, "", 30, "Error"}, LAMBDA(acc, val, acc + ISNUMBER(val)))=SCAN(0, {10, "N/A", 25, "", 30, "Error"}, LAMBDA(acc, val, acc + ISNUMBER(val)))
{1, 1, 2, 2, 3, 3}
SCAN("", {"North", "", "", "South", "", "East"}, LAMBDA(acc, val, IF(val="", acc, val)))=SCAN("", {"North", "", "", "South", "", "East"}, LAMBDA(acc, val, IF(val="", acc, val)))
{"North", "North", "North", "South", "South", "East"}
SCAN("", {"T", "h", "e", "p", "E", "x", "c", "e", "l"}, LAMBDA(acc, val, acc & val))=SCAN("", {"T", "h", "e", "p", "E", "x", "c", "e", "l"}, LAMBDA(acc, val, acc & val))
{"T", "Th", "The", "Thep", "ThepE", "ThepEx", "ThepExc", "ThepExce", "ThepExcel"}
SCAN(100000, SEQUENCE(12), LAMBDA(principal, month, principal * (1 + 0.005)))=SCAN(100000, SEQUENCE(12), LAMBDA(principal, month, principal * (1 + 0.005)))
Array แสดงยอดเงินหลังดอกเบี้ย 0.5% ต่อเดือน เป็นเวลา 12 เดือน
SCAN(1, {1, 2, 3, 4, 5}, LAMBDA(acc, val, acc * val))=SCAN(1, {1, 2, 3, 4, 5}, LAMBDA(acc, val, acc * val))
{1, 2, 6, 24, 120}
SCAN return array ที่แสดงค่า accumulator ในทุกขั้นตอนของการคำนวณ (intermediate values) เช่น {1, 3, 6, 10, 15} ส่วน REDUCE return เฉพาะค่าสุดท้ายเพียงค่าเดียว เช่น 15 ใช้ SCAN เมื่อต้องการเห็น running results, แนวโน้ม, หรือการเปลี่ยนแปลงเทียบเวลา ใช้ REDUCE เมื่อต้องการแค่ผลลัพธ์สุดท้าย เช่น total sum, final count
Accumulator คือตัวแปรที่เก็บค่าสะสมจากการคำนวณรอบก่อนหน้า ในรอบแรก accumulator = initial_value หลังจากนั้นจะเป็นค่าที่ LAMBDA return ในรอบก่อนหน้า ชื่อไม่จำเป็นต้องเป็น ‘acc’ หรือ ‘a’ แต่นิยมใช้เพื่อความชัดเจน สามารถใช้ชื่ออื่นได้ เช่น ‘total’, ‘max_so_far’, ‘running_count’ ขึ้นกับบริบท
เพราะ COUNT นับจำนวน arguments ที่ได้รับ ซึ่ง SCAN ส่งให้เสมอ 2 ตัว (accumulator และ value) จึงได้ 2 ทุกรอบ ไม่ได้นับ element ใน array ให้ใช้ LAMBDA แทน เช่น =SCAN(0, data, LAMBDA(acc, val, acc + 1)) เพื่อนับทุก element หรือ =SCAN(0, data, LAMBDA(acc, val, acc + ISNUMBER(val))) เพื่อนับเฉพาะตัวเลข Abbreviated Syntax เหมาะกับ MAX, MIN, SUM, หรือฟังก์ชันที่คำนวณจาก 2 ค่า
ได้ แต่ไม่สามารถใส่สูตร SCAN ภายใน Table (Ctrl+T) ได้ เพราะ Dynamic Array Functions ไม่สามารถ spill ภายใน Table ให้ใส่สูตร SCAN ในเซลล์นอก Table แล้ว reference ข้อมูลจาก Table เช่น =SCAN(0, Sales[Revenue], LAMBDA(acc, val, acc + val)) หรือแปลง Table เป็น range ธรรมดาก่อน (Table Design → Convert to Range)
SCAN เป็น LAMBDA Helper Function ที่มีใน Excel for Microsoft 365 (Windows, Mac, Web) และ Excel 2024 เท่านั้น ไม่มีใน Excel 2021, Excel 2019 หรือเวอร์ชันเก่ากว่า ถ้าใช้เวอร์ชันเก่าต้องใช้วิธีอื่น เช่น Helper Column แทน หรืออัปเกรดเป็น Microsoft 365 subscription
ใช้ IF condition ใน LAMBDA ตรวจสอบว่าเป็นเดือนมกราคม (หรือจุดเริ่มต้นปี) หรือไม่ ถ้าใช่ให้ reset accumulator กลับไปเป็นค่าปัจจุบัน เช่น =SCAN(0, data, LAMBDA(acc, val, IF(MONTH(date_column)=1, val, acc+val))) โดยอาจต้องใช้ BYROW หรือ MAP เพื่อเข้าถึงคอลัมน์วันที่ประกอบด้วย หรือสร้าง array ที่รวม date กับ value ไว้ด้วยกันก่อนส่งให้ SCAN
ไม่ได้โดยตรง SCAN return array มิติเดียว (1D array) แต่สามารถใช้ HSTACK หรือ LET ร่วมกับหลาย SCAN เพื่อสร้าง array หลายคอลัมน์ เช่น =HSTACK(original_data, SCAN(0, original_data, LAMBDA(a,v,a+v)), SCAN(0, original_data, MAX)) จะได้ 3 คอลัมน์: ข้อมูลต้นฉบับ, Running Total, Running Maximum หรือใช้ MAP/BYROW ร่วมกับ SCAN สำหรับโครงสร้างที่ซับซ้อนกว่า
SCAN อาจช้ากว่า Helper Column ใน dataset ขนาดใหญ่มาก (>10,000 rows) เพราะเป็น array formula ที่คำนวณทั้งหมดในครั้งเดียว แต่ข้อดีคือสูตรเดียวแทนที่จะหลายเซลล์ และ auto-update เมื่อข้อมูลต้นทางเปลี่ยน ถ้าช้าเกินไปให้ใช้ Helper Column แทน หรือ optimize LAMBDA ให้ง่ายขึ้น (หลีกเลี่ยง nested SCAN หรือฟังก์ชันซับซ้อนภายใน LAMBDA)
SCAN เป็น LAMBDA Helper Function ที่วนลูปผ่านแต่ละ element ใน array และคำนวณค่าสะสม (accumulator) โดยใช้ LAMBDA function ที่กำหนด ความแตกต่างสำคัญคือ SCAN return array ที่แสดงผลลัพธ์สะสมในทุกขั้นตอน ไม่ใช่แค่ผลลัพธ์สุดท้าย ทำให้เห็นการเปลี่ยนแปลงของข้อมูลตลอดกระบวนการคำนวณ เหมาะสำหรับ Running Total, Running Maximum, การคำนวณดอกเบี้ยทบต้น หรือการแสดงผลลัพธ์แบบต่อเนื่อง
SCAN ต่างจาก REDUCE ตรงที่ REDUCE return เฉพาะค่าสุดท้ายเพียงค่าเดียว ในขณะที่ SCAN return ทุกค่าที่เกิดขึ้นระหว่างทาง เปรียบเสมือนการดูภาพเคลื่อนไหวทีละเฟรมแทนที่จะเห็นแค่เฟรมสุดท้าย ฟังก์ชันนี้มีประโยชน์มากสำหรับการวิเคราะห์ข้อมูลที่ต้องการเห็นแนวโน้มหรือการเปลี่ยนแปลงเทียบเวลา