Csv.Document แปลงข้อมูลรูปแบบ CSV (Comma-Separated Values) ให้เป็นตารางข้อมูล (table) ใน Power Query โดยรองรับการกำหนดตัวแบ่งข้อมูล (delimiter), รหัสภาษา (encoding) และโครงสร้างคอลัมน์ (column structure) แบบต่างๆ ได้ตามความต้องการ function นี้สามารถแยกวิเคราะห์ทั้งข้อมูลแบบ binary content ที่ได้จาก File.Contents และข้อความแบบ text string ที่ได้จาก Web.Contents พร้อมจัดการข้อความที่ครอบด้วย quote ตามมาตรฐานสากล CSV standard เหมาะสมสำหรับการนำเข้าไฟล์ CSV จากระบบไฟล์ในเครื่อง (local), ที่อยู่เว็บไซต์ (URL) หรือการตอบกลับจาก API (API response) ที่มีตัวแบ่งข้อมูลแบบกำหนดเอง (custom delimiter), เนื้อหาภาษาต่างประเทศ หรือโครงสร้างพิเศษที่ต้องการการควบคุมเฉพาะ คืนค่าออกมาเป็นตารางที่ทุกคอลัมน์มีประเภทข้อมูลเป็นข้อความ (text type) ควรใช้ร่วมกับ Table.PromoteHeaders เพื่อยกแถวแรกขึ้นเป็นหัวตาราง และ Table.TransformColumnTypes เพื่อแปลงประเภทข้อมูลให้เหมาะสมกับการใช้งาน
=Csv.Document(source as any, optional columns as any, optional delimiter as any, optional extraValues as nullable number, optional encoding as nullable number) as table
=Csv.Document(source as any, optional columns as any, optional delimiter as any, optional extraValues as nullable number, optional encoding as nullable number) as table
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| source | any | Yes | ข้อมูลต้นทาง CSV สามารถเป็น binary content (จาก File.Contents), text string หรือ stream ก็ได้ | |
| columns | any | Optional | null | กำหนดโครงสร้าง column ได้ 4 รูปแบบ: null (auto-detect), number (จำนวน column), list of text (ชื่อ column), table type (กำหนดชื่อและ type พร้อมกัน) หรือ record (options ขั้นสูง) |
| delimiter | any | Optional | "," | ตัวแบ่ง column สามารถเป็น single character เช่น “,” “;” “|”, list of characters, หรือ “” เพื่อแบ่งด้วย whitespace |
| extraValues | nullable number | Optional | null | กำหนดวิธีจัดการ row ที่มี column มากกว่าหรือน้อยกว่าที่คาดหวัง ใช้ค่าจาก ExtraValues.Type (Ignore, Error, List) |
| encoding | nullable number | Optional | 65001 | รหัส text encoding ที่ใช้อ่านไฟล์ เช่น 65001 (UTF-8), 874 (Thai Windows), 1252 (Western European), 932 (Japanese Shift-JIS) |
ใช้ร่วมกับ File.Contents เพื่ออ่านไฟล์ CSV จาก local path แล้ว parse เป็น table พร้อมยก row แรกเป็น header
ใช้ร่วมกับ Web.Contents เพื่อดาวน์โหลด CSV จาก URL หรือ API endpoint แล้ว parse ให้เป็น table
จัดการไฟล์ที่ใช้ semicolon (ไฟล์จากยุโรป), tab (TSV), pipe หรืออักขระอื่นแทน comma
ระบุ encoding ที่เหมาะสมเพื่ออ่านภาษาไทย จีน ญี่ปุ่น หรือภาษาอื่นๆ ได้ถูกต้องโดยไม่เกิด mojibake
กำหนดชื่อ column เองผ่าน list of text เมื่อ CSV ไม่มี header row หรือ header ไม่ถูกต้อง
let // สร้าง CSV text จาก list of text (แต่ละ item = 1 row) CsvText = Text.Combine( { "OrderID,Product,Amount", "1,Laptop,25000", "2,Mouse,350", "3,Keyboard,890…=let
// สร้าง CSV text จาก list of text (แต่ละ item = 1 row)
CsvText = Text.Combine(
{
"OrderID,Product,Amount",
"1,Laptop,25000",
"2,Mouse,350",
"3,Keyboard,890"
},
"#(cr)#(lf)" // Line break (carriage return + line feed)
),
// Parse CSV ด้วยค่า default (comma delimiter, auto-detect 3 columns)
ParsedTable = Csv.Document(CsvText),
// ยก row แรก (OrderID,Product,Amount) ขึ้นเป็นชื่อ column
WithHeaders = Table.PromoteHeaders(ParsedTable, [PromoteAllScalars=true]),
// แปลง column type จาก text เป็น number
TypedTable = Table.TransformColumnTypes(
WithHeaders,
{
{"OrderID", Int64.Type},
{"Amount", Int64.Type}
}
)
in
TypedTable
// Result: Table with 3 rows
// [OrderID = 1, Product = "Laptop", Amount = 25000]
// [OrderID = 2, Product = "Mouse", Amount = 350]
// [OrderID = 3, Product = "Keyboard", Amount = 890]
Table with 3 rows and 3 columns (OrderID: Int64, Product: text, Amount: Int64)
let // Case 1: Semicolon CSV (ไฟล์จากยุโรปที่ใช้ comma เป็นทศนิยม) EuropeanCsv = Text.Combine( { "Name;Country;Score", "Alice;USA;95", "Bob;UK;87", "Carol;Franc…=let
// Case 1: Semicolon CSV (ไฟล์จากยุโรปที่ใช้ comma เป็นทศนิยม)
EuropeanCsv = Text.Combine(
{
"Name;Country;Score",
"Alice;USA;95",
"Bob;UK;87",
"Carol;France;92"
},
"#(cr)#(lf)"
),
// ระบุ delimiter เป็น semicolon (argument ที่ 3)
ParsedEU = Csv.Document(EuropeanCsv, null, ";"),
WithHeadersEU = Table.PromoteHeaders(ParsedEU),
TypedEU = Table.TransformColumnTypes(WithHeadersEU, {{"Score", Int64.Type}}),
// Case 2: Tab-delimited (TSV file)
TsvData = Text.Combine(
{
"Product#(tab)Price#(tab)InStock",
"Coffee#(tab)120#(tab)Yes",
"Tea#(tab)80#(tab)No"
},
"#(cr)#(lf)"
),
// ใช้ #(tab) เป็น delimiter
ParsedTSV = Csv.Document(TsvData, null, "#(tab)"),
WithHeadersTSV = Table.PromoteHeaders(ParsedTSV),
Result = [
European = TypedEU,
TSV = WithHeadersTSV
]
in
Result
// Result: Record with 2 tables
// [European]: 3 rows × 3 columns (Name, Country, Score)
// [TSV]: 2 rows × 3 columns (Product, Price, InStock)
Record containing 2 tables with different delimiters successfully parsed
let // Case 1: CSV ไม่มี header row (กำหนดชื่อ column เอง) CsvWithoutHeader = Text.Combine( { "001|Electronics|15000", "002|Clothing|3500", "003|Food|1200" }, "…=let
// Case 1: CSV ไม่มี header row (กำหนดชื่อ column เอง)
CsvWithoutHeader = Text.Combine(
{
"001|Electronics|15000",
"002|Clothing|3500",
"003|Food|1200"
},
"#(cr)#(lf)"
),
// ส่ง list of text เป็น argument ที่ 2 (แทน null)
ColumnNames = {"ProductCode", "Category", "Revenue"},
ParsedNoHeader = Csv.Document(
CsvWithoutHeader,
ColumnNames,
"|"
),
TypedNoHeader = Table.TransformColumnTypes(
ParsedNoHeader,
{{"Revenue", Int64.Type}}
),
// Case 2: CSV ภาษาไทย (Windows-874 encoding)
ThaiCsv = "รหัส,ชื่อสินค้า,ราคา#(cr)#(lf)P001,กาแฟ,120#(cr)#(lf)P002,ชา,80",
// ใช้ record format เพื่อระบุ Delimiter และ Encoding พร้อมกัน
ParsedThai = Csv.Document(
ThaiCsv,
[Delimiter=",", Encoding=874]
),
WithHeadersThai = Table.PromoteHeaders(ParsedThai),
TypedThai = Table.TransformColumnTypes(
WithHeadersThai,
{{"ราคา", Int64.Type}}
),
Result = [
Products = TypedNoHeader,
ThaiProducts = TypedThai
]
in
Result
// Result: Record with 2 tables
// [Products]: 3 rows with custom column names (ProductCode, Category, Revenue)
// [ThaiProducts]: 2 rows with Thai text correctly displayed
Record containing 2 tables: one with custom column names, one with Thai encoding correctly handled
let // Case 1: CSV ที่มี quoted text ซับซ้อน (มี delimiter และ line break ข้างใน) ComplexCsv = Text.Combine( { "ID,Name,Description", "1,Product A,""Premium qua…=let
// Case 1: CSV ที่มี quoted text ซับซ้อน (มี delimiter และ line break ข้างใน)
ComplexCsv = Text.Combine(
{
"ID,Name,Description",
"1,Product A,""Premium quality"" with",
"multiple lines and, commas",
"2,Product B,Standard item",
"3,Product C,""Features: comma, semicolon; and pipe|"""
},
"#(cr)#(lf)"
),
// ใช้ record format กับ QuoteStyle และ CsvStyle options
ParsedComplex = Csv.Document(
ComplexCsv,
[
Delimiter=",",
Columns=3,
QuoteStyle=QuoteStyle.Csv, // ตีความ quote ตามมาตรฐาน CSV
CsvStyle=CsvStyle.QuoteAfterDelimiter, // Quote มีนัยสำคัญหลัง delimiter
Encoding=65001
]
),
WithHeadersComplex = Table.PromoteHeaders(ParsedComplex),
// Case 2: CSV ที่ row บางตัวมี column ไม่สม่ำเสมอ
UnevenCsv = Text.Combine(
{
"A,B,C",
"1,2,3,4,5", // 5 columns (เกิน)
"6,7", // 2 columns (ขาด)
"8,9,10" // 3 columns (ถูกต้อง)
},
"#(cr)#(lf)"
),
// ใช้ ExtraValues.Ignore เพื่อจัดการ column ที่ไม่สม่ำเสมอ
ParsedUneven = Csv.Document(
UnevenCsv,
[
Columns=3,
ExtraValues=ExtraValues.Ignore // ละเว้นค่าที่เกิน, เติม null ให้ค่าที่ขาด
]
),
WithHeadersUneven = Table.PromoteHeaders(ParsedUneven),
Result = [
ComplexQuotes = WithHeadersComplex,
UnevenColumns = WithHeadersUneven
]
in
Result
// Result: Record with 2 tables
// [ComplexQuotes]: Table with quoted text containing delimiters and line breaks
// [UnevenColumns]: Table with 3 rows × 3 columns (extra values ignored, missing filled with null)
Record with 2 tables: complex quoted text handled correctly, uneven columns normalized to 3 columns
Csv.Document ใช้สำหรับแยกวิเคราะห์ข้อมูล CSV (ข้อความธรรมดาที่แบ่งด้วยตัวแบ่งข้อมูล delimiter) ให้กลายเป็นตารางข้อมูล (table) โดยสามารถตรวจจับโครงสร้างโดยอัตโนมัติ (auto-detect) Excel.Workbook ใช้สำหรับอ่านไฟล์ Excel ที่เป็นรูปแบบ binary format เช่น .xlsx หรือ .xls ซึ่งมีข้อมูลแผ่นงาน (worksheet), การจัดรูปแบบ (formatting) และสูตรคำนวณ (formula) อยู่ด้วย Json.Document ใช้สำหรับแยกวิเคราะห์ข้อความรูปแบบ JSON ให้กลายเป็น record หรือ list ตามโครงสร้างของ JSON ส่วน Table.FromRows ใช้สำหรับสร้างตารางข้อมูลจาก list of lists ที่มีโครงสร้างชัดเจนอยู่แล้วในหน่วยความจำ เช่น {{1,”A”},{2,”B”}} โดยไม่ต้องแยกวิเคราะห์ข้อความอีก ดังนั้นการเลือกใช้ควรพิจารณาจากรูปแบบข้อมูลต้นทาง: ข้อความ CSV → Csv.Document, ไฟล์ Excel → Excel.Workbook, ข้อความ JSON → Json.Document, รายการของรายการ → Table.FromRows เพื่อให้การประมวลผลมีประสิทธิภาพสูงสุด
สำหรับการอ่านไฟล์จากเครื่องคอมพิวเตอร์ (local file) ให้ใช้ File.Contents ร่วมกับ Csv.Document ตัวอย่างโค้ด: let Source = File.Contents(“C:\\Data\\sales.csv”), Parsed = Csv.Document(Source) in Parsed โดย File.Contents จะอ่านไฟล์เป็น binary content แล้ว Csv.Document จะแยกวิเคราะห์เป็นตารางข้อมูล สำหรับการดาวน์โหลดไฟล์จากที่อยู่เว็บไซต์ (URL) ให้ใช้ Web.Contents ตัวอย่างโค้ด: let Source = Web.Contents(“https://example.com/data.csv”), Parsed = Csv.Document(Source) in Parsed โดย Web.Contents จะดาวน์โหลดเนื้อหาเป็น binary content เช่นเดียวกัน สำหรับการรับข้อมูลจาก API ที่ส่งกลับมาเป็นข้อความ CSV ให้ใช้ Web.Contents และอาจต้องใช้ Text.FromBinary ก่อนแปลงเป็นข้อความ (ถ้าจำเป็น) ทั้ง File.Contents และ Web.Contents จะคืนค่าออกมาเป็น binary content ซึ่ง Csv.Document สามารถแยกวิเคราะห์ให้กลายเป็นตารางข้อมูลได้ทันที จากนั้นควรตามด้วย Table.PromoteHeaders เพื่อยกแถวแรกขึ้นเป็นหัวตารางและ Table.TransformColumnTypes เพื่อแปลงประเภทข้อมูลให้ถูกต้องตามปกติ
เกิดจาก text encoding ไม่ตรงกับไฟล์ต้นทาง… เคยเจอปัญหานี้บ่อยมากครับ 😭
.
CSV ภาษาไทยมักใช้ UTF-8 (encoding 65001, ค่า default) หรือ Windows-874 (legacy Thai encoding ใน Windows เก่า)
.
วิธีแก้คือระบุ encoding ด้วย record format:
– Csv.Document(source, [Encoding=874]) สำหรับไฟล์ที่ save จาก Excel ภาษาไทยเวอร์ชันเก่า
– Csv.Document(source, [Encoding=65001]) สำหรับ UTF-8
.
ถ้าไม่แน่ใจให้ลองทั้ง 2 ค่า หรือเปิดไฟล์ด้วย Notepad++ เพื่อตรวจสอบ encoding ที่ถูกต้อง
.
💡 **Tip:** สำหรับภาษาอื่น: 932 (Japanese Shift-JIS), 936 (Simplified Chinese GBK), 1252 (Western European)
ระบุ delimiter ผ่าน argument ที่ 3 หรือใช้ record format สำหรับ semicolon (ไฟล์จากยุโรป): Csv.Document(source, null, “;”) สำหรับ tab character (TSV): Csv.Document(source, null, “#(tab)”) สำหรับ pipe: Csv.Document(source, null, “|”) หรือใช้ record format: Csv.Document(source, [Delimiter=”;”]) สามารถใช้ delimiter อื่นๆ ได้ เช่น colon “:”, space ” “, หรืออักขระใดก็ได้ที่เป็น single character ถ้าต้องการ split ด้วย whitespace ให้ใช้ “” (empty string) ถ้าต้องการ multi-character delimiter ให้ส่งเป็น list of characters แทน
ใช้ ExtraValues option ควบคุมพฤติกรรม มี 3 แบบ:
.
1. **ExtraValues.Ignore** (ละเว้นค่าที่เกิน, เติม null ให้ค่าที่ขาด, ใช้บ่อยที่สุด 😎)
เหมาะกับข้อมูลที่ต้องการโครงสร้างสม่ำเสมอ
.
2. **ExtraValues.Error** (แจ้ง error ถ้า column ไม่สม่ำเสมอ)
เหมาะกับข้อมูลที่ต้องการความแม่นยำสูง
.
3. **ExtraValues.List** (เก็บค่าที่เกินใน nested list)
เหมาะกับข้อมูลที่ต้องการเก็บทุกค่า
.
ตัวอย่าง: Csv.Document(source, [Columns=3, ExtraValues=ExtraValues.Ignore]) จะบังคับให้ table มี 3 column เสมอโดยตัดค่าที่เกินและเติม null ให้ค่าที่ขาด
.
💡 **Tip:** ส่วนตัวผมแนะนำ ExtraValues.Ignore สำหรับงานส่วนใหญ่ครับ เพราะข้อมูลจริงมักมีความไม่สมบูรณ์แบบอยู่แล้ว
Table.PromoteHeaders ไม่จำเป็นถ้า CSV ไม่มี header row หรือต้องการกำหนดชื่อ column เอง
.
โดยส่ง list of column names เป็น argument ที่ 2: Csv.Document(source, {“ID”,”Name”,”Amount”}, “,”) จะได้ table ที่มีชื่อ column กำหนดไว้แล้ว
.
ส่วน Table.TransformColumnTypes จำเป็นเพราะ Csv.Document คืน table ที่ทุก column เป็น text type ทำให้ไม่สามารถคำนวณหรือเปรียบเทียบตัวเลขได้ถูกต้อง
.
ตัวอย่าง: “10” > “9” เป็น false เพราะเปรียบเทียบเป็น text 😭
.
ต้องแปลงเป็น type ที่เหมาะสม: Table.TransformColumnTypes(table, {{“Amount”,Int64.Type}, {“Date”,type date}}) เพื่อให้ filter, sort และคำนวณได้ถูกต้อง
.
💡 **Tip:** ส่วนตัวผมเคยเจอ bug จาก text type นี้บ่อยมากครับ เลยเป็นนิสัยที่จะ transform type ทุกครั้งเลย 😅
Csv.Document จัดการ quoted text ตามมาตรฐาน CSV โดย default ถ้าข้อความครอบด้วย double quote ตัว delimiter และ line break ภายในจะถือเป็น literal text ไม่ใช่ตัวแบ่ง column หรือ row สามารถควบคุมพฤติกรรมด้วย QuoteStyle option: QuoteStyle.Csv (default, quote มีนัยสำคัญเสมอ) หรือ QuoteStyle.None (ถือว่า quote เป็น text ธรรมดา, line break ทุกตัวแบ่ง row) และ CsvStyle option: CsvStyle.QuoteAfterDelimiter (quote มีนัยสำคัญเฉพาะหลัง delimiter) หรือ CsvStyle.QuoteAlways (quote มีนัยสำคัญตลอด) ตัวอย่าง: Csv.Document(source, [QuoteStyle=QuoteStyle.Csv, CsvStyle=CsvStyle.QuoteAfterDelimiter]) เหมาะกับ CSV standard
ตรวจสอบสาเหตุที่พบบ่อย:
.
1. **Delimiter ผิด** → ลองระบุอย่างชัดเจน [Delimiter=”;”]/[Delimiter=”#(tab)”]
2. **Encoding ไม่ตรง** → ทดสอบ [Encoding=874]/[Encoding=1252]/[Encoding=65001]
3. **Quoted text ซับซ้อน** → ปรับ [QuoteStyle=QuoteStyle.Csv, CsvStyle=CsvStyle.QuoteAfterDelimiter]
4. **Column ไม่สม่ำเสมอ** → ใช้ [ExtraValues=ExtraValues.Ignore]
5. **ไฟล์ไม่ใช่ CSV จริง** → เปิดด้วย Notepad++ ตรวจสอบ delimiter และ line ending
.
ถ้ายังแก้ไม่ได้ ลองใช้ Lines.FromBinary แล้ว parse แต่ละ line ด้วย Text.Split เอง
.
หรือถ้าเป็นไฟล์ .xlsx ที่ save as CSV ให้ใช้ Excel.Workbook อ่านจากไฟล์ต้นฉบับแทน
.
💡 **Tip:** ส่วนตัวผมเคยเจอปัญหา encoding บ่อยที่สุดครับ เลยแนะนำให้เช็ค encoding ก่อนเป็นอันดับแรก 😅
Csv.Document เป็น function สำคัญใน Power Query ที่ใช้แปลงไฟล์ CSV ให้กลายเป็น table พร้อมใช้งานได้ทันที ครับ
function นี้รองรับทั้งการรับข้อมูลแบบ binary content จาก File.Contents (ไฟล์ในเครื่อง) และข้อความแบบ text string จาก Web.Contents (ดาวน์โหลดจากเว็บ) หรือแม้แต่ API response ที่ส่งมาเป็น CSV format ก็ใช้ได้
.
ที่เจ๋งคือ Csv.Document มีความยืดหยุ่นสูงมาก ครับ 😎
คุณสามารถควบคุมตัวแบ่งข้อมูล (delimiter), การเข้ารหัสภาษา (encoding), โครงสร้างคอลัมน์ (column structure) และวิธีจัดการข้อความที่ครอบด้วย quote ได้หมด
ทำให้นำเข้าข้อมูลจากแหล่งต่างๆ ได้อย่างแม่นยำ ไม่ว่าจะเป็นไฟล์ในเครื่อง, URL, หรือ API response
.
Csv.Document มักถูกใช้เป็นจุดเริ่มต้นในการ transform ข้อมูลภายใน Power Query โดยมักจะใช้ร่วมกับ Table.PromoteHeaders เพื่อยกแถวแรกขึ้นเป็นชื่อคอลัมน์ และใช้ร่วมกับ Table.TransformColumnTypes เพื่อแปลงประเภทข้อมูลจากข้อความ (text) เป็นประเภทที่เหมาะสมอย่างเช่น ตัวเลข (number), วันที่ (date) หรือค่าตรรกะ (logical) ตามความต้องการนะครับ
Csv.Document ทำงานโดยการแยกวิเคราะห์ (parse) ข้อมูล CSV ด้วยการแยกแถว (row) ตามเครื่องหมายขึ้นบรรทัดใหม่ (line break) และแยกคอลัมน์ (column) ตามตัวแบ่งข้อมูลที่กำหนด
.
โดยค่าเริ่มต้น (default) จะใช้เครื่องหมายจุลภาค (comma) ซึ่งเป็นมาตรฐานของไฟล์ CSV ครับ
.
function นี้มีความสามารถพิเศษในการตรวจจับจำนวนคอลัมน์โดยอัตโนมัติ หรือคุณสามารถกำหนดจำนวนคอลัมน์, ระบุชื่อคอลัมน์, หรือแม้กระทั่งกำหนดทั้งชื่อคอลัมน์และประเภทข้อมูล (data type) พร้อมกันผ่านการระบุแบบ table type specification ได้ตามความต้องการ
.
สำหรับกรณีที่มีข้อความที่ถูกครอบด้วย double quote ระบบจะตีความตัวแบ่งข้อมูล (delimiter) และการขึ้นบรรทัดใหม่ (line break) ที่อยู่ภายใน quote เหล่านั้นว่าเป็นข้อความปกติ (literal text) ไม่ใช่ตัวแบ่งคอลัมน์หรือตัวแบ่งแถว ซึ่งเป็นไปตามมาตรฐาน CSV ครับ 😎
.
นอกจากนี้ function ยังรองรับการกำหนดรหัสภาษา (text encoding) เพื่อให้สามารถอ่านไฟล์ที่มีภาษาต่างๆ ได้อย่างถูกต้อง ไม่ว่าจะเป็น UTF-8 (รหัส 65001), Windows-874 (ภาษาไทย), หรือ Windows-1252 (ภาษายุโรปตะวันตก)
การระบุรหัสภาษาที่ถูกต้องจะช่วยป้องกันปัญหาการแสดงผลอักขระผิดพลาด (mojibake) ที่มักเกิดขึ้นบ่อยครั้งเมื่อรหัสภาษาไม่ตรงกันระหว่างไฟล์ต้นทางกับการตั้งค่าที่ใช้อ่านไฟล์ นะครับ
.
สำหรับกรณีที่ข้อมูลมีจำนวนคอลัมน์ที่ไม่สม่ำเสมอกันในแต่ละแถว (บางแถวมีคอลัมน์มากกว่าหรือน้อยกว่าที่กำหนดไว้) สามารถใช้ตัวเลือกพิเศษที่เรียกว่า ExtraValues option เพื่อควบคุมพฤติกรรมการจัดการได้ครับ
.
เช่น ExtraValues.Ignore จะละเว้นค่าที่เกินและเติมค่า null ให้กับคอลัมน์ที่ขาด, ExtraValues.Error จะแจ้งข้อผิดพลาดทันทีเมื่อพบความไม่สม่ำเสมอ, หรือ ExtraValues.List จะเก็บค่าที่เกินมาไว้ในรูปแบบของ list ซ้อนเพื่อไม่ให้ข้อมูลสูญหาย
.
นอกจากนี้ยังสามารถใช้รูปแบบ record format เพื่อระบุตัวเลือกขั้นสูงได้หลายตัวพร้อมกันในคำสั่งเดียว 💡
เช่น QuoteStyle เพื่อควบคุมว่าเครื่องหมาย quote จะถูกตีความอย่างไรในการแยกข้อมูล (QuoteStyle.Csv สำหรับมาตรฐาน CSV หรือ QuoteStyle.None สำหรับถือว่าเป็นอักขระธรรมดา) และ CsvStyle เพื่อกำหนดว่าเครื่องหมาย quote จะมีนัยสำคัญในสถานการณ์ใด (CsvStyle.QuoteAfterDelimiter หมายความว่ามีนัยสำคัญเฉพาะเมื่ออยู่หลังตัวแบ่งข้อมูล หรือ CsvStyle.QuoteAlways หมายความว่ามีนัยสำคัญเสมอทุกกรณี)
.
การใช้รูปแบบ record format จะทำให้โค้ดอ่านเข้าใจได้ง่ายกว่าการส่ง argument แยกกันหลายตัว และยังช่วยให้สามารถปรับแต่งพฤติกรรมการแยกวิเคราะห์ (parsing behavior) ได้อย่างละเอียดและครอบคลุมมากขึ้นครับ
.
เนื่องจาก Csv.Document จะคืนค่าออกมาเป็น table ที่ทุกคอลัมน์มีประเภทข้อมูลเป็นข้อความ (text type) ทั้งหมด จึงควรใช้ Table.TransformColumnTypes ตามหลังเพื่อแปลงคอลัมน์เป็นประเภทที่เหมาะสมกับข้อมูลจริง
เช่น Int64.Type สำหรับตัวเลขจำนวนเต็ม, type date สำหรับวันที่, type logical สำหรับค่าความจริง เพื่อให้สามารถกรองข้อมูล (filter), เรียงลำดับ (sort) และคำนวณผลลัพธ์ได้อย่างถูกต้องตามที่ต้องการนะครับ
Csv.Document เหมาะสมอย่างยิ่งสำหรับการนำเข้าไฟล์ CSV จากระบบไฟล์ในเครื่อง (local file system) โดยใช้ร่วมกับ File.Contents หรือการดาวน์โหลดข้อมูลจาก URL โดยใช้ร่วมกับ Web.Contents โดยเฉพาะเมื่อต้องการควบคุมตัวแบ่งข้อมูล (delimiter), รหัสภาษา (encoding) หรือโครงสร้างคอลัมน์ (column structure) ด้วยตัวเองอย่างละเอียด
.
ใช้ได้ดีกับไฟล์ที่มีตัวแบ่งข้อมูลแบบกำหนดเอง (custom delimiter) เช่น เครื่องหมาย semicolon ซึ่งพบบ่อยในไฟล์จากประเทศในยุโรป, อักขระ tab สำหรับไฟล์รูปแบบ TSV, เครื่องหมาย pipe หรืออักขระอื่นๆ ที่ไม่ใช่ comma ทั่วไป
.
ใช้ได้ดีกับไฟล์ที่มีเนื้อหาเป็นภาษาพิเศษ เช่น ภาษาไทย ภาษาจีน ภาษาญี่ปุ่น โดยต้องระบุรหัสภาษา (encoding) ที่ถูกต้องเพื่อให้แสดงผลได้ถูกต้อง ไม่งั้นจะเจออักขระพิเศษแบบ mojibake แน่นอน 😅
.
ใช้ได้ดีกับข้อมูลที่ไม่มีแถวหัวตาราง (header row) โดยสามารถกำหนดชื่อคอลัมน์ขึ้นมาใช้เองได้
.
ใช้ได้ดีกับข้อมูลที่มีข้อความซับซ้อนที่ถูกครอบด้วย quote (มีตัวแบ่งข้อมูลหรือการขึ้นบรรทัดใหม่อยู่ภายในข้อความ) และยังใช้ได้ดีกับข้อมูลที่มีจำนวนคอลัมน์ไม่สม่ำเสมอในแต่ละแถวโดยสามารถใช้ ExtraValues option เพื่อจัดการได้
.
นอกจากนี้ยังใช้ได้ดีกับการรับข้อมูลจาก API ที่ตอบกลับมาในรูปแบบ CSV format โดยสามารถแยกวิเคราะห์ข้อความ (text string) ให้กลายเป็น table ได้ทันทีครับ 😎
ในทางตรงกันข้าม สถานการณ์ที่ไม่เหมาะสมสำหรับการใช้ Csv.Document คือเมื่อต้องการอ่านไฟล์ Excel ที่เป็นรูปแบบ binary format เช่น .xlsx หรือ .xls ซึ่งควรใช้ Excel.Workbook แทนเพราะจะได้ข้อมูลที่สมบูรณ์พร้อมทั้งการจัดรูปแบบและสูตรคำนวณ
.
หรือเมื่อต้องการแยกวิเคราะห์ข้อมูลรูปแบบ JSON ซึ่งควรใช้ Json.Document แทนเพื่อให้ได้โครงสร้างข้อมูลที่ถูกต้อง
.
หรือเมื่อข้อมูลมีโครงสร้างเป็น list of lists อยู่แล้วในหน่วยความจำ (in-memory) ซึ่งควรใช้ Table.FromRows แทนเพราะจะเร็วกว่าและไม่ต้องแยกวิเคราะห์ข้อความอีกครั้ง
.
การเลือกใช้ function ให้เหมาะสมกับรูปแบบข้อมูลต้นทางจะช่วยให้การประมวลผลข้อมูลมีประสิทธิภาพและถูกต้องที่สุดครับ 💡