TL;DR
Power Query tìm kiếm một khóa, không tìm thấy gì, và báo lỗi thay vì trả về null. Chín trong mười trường hợp, thủ phạm là sự không khớp kiểu dữ liệu — một cột là text, cột kia là number hoặc date. Chuyển đổi cả hai phía về cùng kiểu dữ liệu trước bước merge hoặc lookup và lỗi sẽ biến mất.
Lỗi Này Xuất Hiện Ở Đâu
Lỗi có thể xuất hiện ở nhiều nơi, không chỉ một chỗ:
- Lookup thủ công dùng Table.SelectRows hoặc Record.Field trong M code
- Drill vào cột nested table sau bước Merge Queries
- Pattern lookup theo chỉ số hàng:
lookupTable{[ID = someValue]} - Hàm M tùy chỉnh tham chiếu đến một hàng cụ thể theo khóa
Nguyên Nhân Gốc Rễ
Cú pháp M tableName{[ColumnName = value]} kỳ vọng tìm đúng một hàng khớp. Không tìm thấy? Báo lỗi. Tìm thấy hai hàng? Cũng báo lỗi. Không có cơ chế dự phòng nào được tích hợp sẵn.
Điều khiến vấn đề này phức tạp: quá trình lookup phân biệt kiểu dữ liệu. Chuỗi "123" và số 123 trông giống hệt nhau trong ô tính nhưng hoàn toàn khác nhau với Power Query — sự không khớp này âm thầm phá vỡ kết quả so khớp. Các nguyên nhân phổ biến khác:
- Dữ liệu nguồn được cập nhật và một khóa hợp lệ trước đó bị xóa hoặc đổi tên
- Khoảng trắng đầu hoặc cuối ẩn trong một cột (thường gặp khi import CSV)
- Ngày tháng lưu dạng text (
"2024-01-15") thay vì kiểudatethực sự - Gõ nhầm tên cột trong M code — tên cột phân biệt chữ hoa chữ thường
Cách Sửa 1: Đồng Nhất Kiểu Dữ Liệu Hai Phía
Mở Advanced Editor và tìm dòng lookup. Ép buộc cả hai phía về cùng kiểu trước khi so sánh:
// Trước — lỗi khi ID là number trong bảng này, text trong bảng kia
let
result = lookupTable{[ID = sourceID]}[Value]
in
result
// Sau — chuyển tất cả về text trước
let
safeID = Text.From(sourceID),
safeTable = Table.TransformColumnTypes(lookupTable, {{"ID", type text}}),
result = safeTable{[ID = safeID]}[Value]
in
result
Nếu khóa luôn là số (như mã đơn hàng hoặc mã nhân viên), hãy chuyển về number thay thế:
let
numID = Number.From(sourceID),
numTable = Table.TransformColumnTypes(lookupTable, {{"ID", type number}}),
result = numTable{[ID = numID]}[Value]
in
result
Cách Sửa 2: Dùng try…otherwise Để Xử Lý Khóa Không Tồn Tại
Không phải hàng nguồn nào cũng có kết quả khớp — điều đó bình thường với dữ liệu thực tế. Thay vì để query bị crash, hãy bọc lookup trong try:
let
safeLookup = try lookupTable{[ID = sourceID]}[Value] otherwise null
in
safeLookup
Khóa không tìm thấy → trả về null, không báo lỗi. Tương tự như bọc công thức Excel trong IFERROR. Sau khi load dữ liệu, lọc các hàng null để xem chính xác những khóa nào không có kết quả khớp.
Cách Sửa 3: Cắt Khoảng Trắng Trước Khi So Sánh
Dữ liệu export CSV và copy-paste nổi tiếng với các khoảng trắng vô hình. "ABC " và "ABC" không phải cùng một khóa. Hãy loại bỏ khoảng trắng cả hai phía:
let
cleanSource = Table.TransformColumns(sourceTable, {{"ID", Text.Trim}}),
cleanLookup = Table.TransformColumns(lookupTable, {{"ID", Text.Trim}}),
merged = Table.NestedJoin(
cleanSource, "ID",
cleanLookup, "ID",
"LookupResult", JoinKind.LeftOuter
)
in
merged
Cách Sửa 4: Kiểm Tra Sự Tồn Tại Của Khóa Trước Khi Lookup
Trong hàm tùy chỉnh nhận tham số khóa, hãy kiểm tra sự tồn tại trước thay vì mặc định có:
(inputID as text) =>
let
matches = Table.SelectRows(lookupTable, each [ID] = inputID),
result = if Table.RowCount(matches) > 0
then matches{0}[Value]
else "KEY NOT FOUND"
in
result
Table.SelectRows trả về bảng rỗng khi không có kết quả khớp — không báo lỗi. Cú pháp chỉ số hàng {[ID = ...]} không cung cấp sự an toàn đó, vì vậy pattern này mạnh mẽ hơn cho các query hướng người dùng.
Cách Sửa 5: Kiểm Tra Kiểu Join Trong Giao Diện
Dùng hộp thoại Merge Queries và lỗi chỉ xuất hiện khi bạn mở rộng cột đã merge? Kiểu join có thể sai:
- Nhấp vào bước merge trong Applied Steps
- Xem cài đặt Join Kind — Inner Join âm thầm loại bỏ các hàng không có kết quả khớp, làm hỏng các bước tiếp theo vốn giả định tất cả hàng đều có mặt
- Chuyển sang Left Outer Join để giữ tất cả hàng nguồn (các hàng không khớp sẽ có null ở cột lookup)
- Lọc bỏ các giá trị null sau đó nếu bạn cần loại trừ chúng
Các Bước Kiểm Tra Sau Khi Sửa
Thực hiện các bước này sau khi áp dụng bất kỳ cách sửa nào:
- Nhấn Refresh Preview trong Power Query Editor — thanh lỗi màu đỏ phải biến mất
- Kiểm tra biểu tượng kiểu dữ liệu bên cạnh các cột khóa — cả hai phải hiển thị ABC (text) hoặc 123 (number), không được lẫn lộn
- Thêm bước chẩn đoán nhanh:
= Table.RowCount(lookupTable)để xác nhận bảng đã load dữ liệu (zero hàng là lỗi thường gặp) - Close & Load, sau đó so sánh số hàng đầu ra với số lượng bạn mong đợi
- Đã dùng
try...otherwise null? Thêm bộ lọc trên cột kết quả để tách các hàng null — đó là những khóa không khớp cần được điều tra
Danh Sách Kiểm Tra Nhanh
- [ ] Cùng kiểu dữ liệu ở cả hai phía của phép so sánh khóa?
- [ ] Có khoảng trắng đầu hoặc cuối ẩn trong các giá trị khóa không?
- [ ] Dữ liệu nguồn có thay đổi sau khi query được tạo ban đầu không?
- [ ] Bảng lookup có đang load zero hàng không?
- [ ] Đang dùng Inner Join trong khi thực ra cần Left Outer không?
- [ ] Tên cột khóa viết đúng chính tả và chữ hoa/thường trong M code chưa?

