🐬Spotfire 為什麼突然沒有 BIN 值與圖表不顯示?工程師用「縮排、欄位來源、過濾條件」三招快速定位(含 IronPython 範例)

 在 Tibco Spotfire 裡做良率(Yield)或 BIN 分佈分析時,最常見也最讓人抓狂的狀況之一,就是:

  • 表格(TablePlot)突然看不到 BIN 欄位

  • 圖表(Chart)突然空白

  • 你明明知道資料有回來,但畫面就是不出來

  • 腳本還可能報 unexpected indent、或是印出一堆 debug 訊息卻看不出問題在哪

這篇文章用「軟體工程師的除錯方式」,用簡單白話把問題拆成 3 類,並用可套用在任何 Spotfire 專案的方式,教你快速定位「BIN 不見」的真正原因。


一、Spotfire 的 BIN 不見,其實通常不是「沒資料」,而是「你拿錯地方的欄位」

很多人直覺以為:

圖表不顯示 = 資料表沒資料


但在 Spotfire 的腳本世界裡,另一個超常見真相是:

資料表其實有資料、有 BIN 欄位
只是你從「視覺物件的參照」去拿欄位,而不是從「真正的資料表」去拿欄位 
結果判斷條件永遠成立不了 → BIN 就永遠加不回去


什麼是「視覺物件的參照」?

Spotfire 的 TablePlot / Chart 會有一種像「指向資料的指標」的東西(概念上類似捷徑),它可能還停留在舊的 view、舊的欄位集合,或欄位字串格式跟你想像的不一樣。

工程師的做法是:

  • 用「資料表」做欄位判斷

  • 用「視覺物件參照」做欄位加入(AddColumn)


二、為什麼你「明明印得出 BIN 欄位清單」,最後卻又變成空?

你可能會遇到這種除錯輸出:

  • 你先印出:有 BIN1, BIN2, BIN3...

  • 但你最後算出來要顯示的 binColumns 卻是空的

這常見原因不是資料突然消失,而是你的判斷式像這樣:

  • 把欄位物件轉成字串 str(col) 去判斷是否 startswith("BIN")

  • str(col) 根本不是欄位名(可能是 ColumnRef(...) 這類描述字串)


三、第二個大地雷:過濾條件把資料「全部清光」但你沒發現

另一種超常見的 BIN 消失原因,是你後面加了某種過濾:

  • 只保留「Rate% > 0.01」

  • 只保留「選到的 BIN」

  • 只保留「某個欄位不是空」

如果你寫得太嚴格、或欄位名稱對不上、或格式是百分比字串(例如 "0.00%"),結果就是:

你以為你在刪除少數無效資料
實際上你把所有資料都刪了
→ 表格剩 0 筆 
→ 圖表自然空白


工程師會在每個關鍵步驟都印出 RowCount,像這樣:


四、最實用的工程師除錯流程(通用版)

下面的程式碼示範 Spotfire 腳本中「一步一步定位」的做法。

1)每一步都要印 RowCount(超重要)

# ✅ 通用除錯:每個重要處理後都看一下資料剩多少筆
def log_count(table_name):
t = Document.Data.Tables[table_name]
print("[COUNT]", table_name, "=", t.RowCount)

log_count("SourceTable")
log_count("IntermediateTable")
log_count("FinalTable")

只要你發現某一步後 RowCount 變成 0,就知道問題在哪一段。


2)用「真正資料表」判斷 BIN 欄位名稱

def get_bin_columns_from_table(table_name, prefix="BIN"):
t = Document.Data.Tables[table_name]
bins = []
for c in t.Columns:
name = c.Name
if name.startswith(prefix):
bins.append(name)
return bins

3)加入欄位到 TablePlot,要用視覺參照(Reference)

def apply_columns_to_tableplot(page_title, visual_title, column_names):
# 找到 TablePlot
page = next(p for p in Document.Pages if p.Title == page_title)
table_vis = next(v for v in page.Visuals if v.Title == visual_title).As[TablePlot]()

# 取得視覺資料參照
ref = table_vis.Data.DataTableReference

# 清除 + 加回欄位
table_vis.TableColumns.Clear()
for n in column_names:
table_vis.TableColumns.Add(ref.Columns.Item[n])

4)避免「過濾清光」:先算再刪,刪前印出會刪多少

def filter_rows_by_threshold(table_name, col_name, threshold):
t = Document.Data.Tables[table_name]
cur = DataValueCursor.CreateFormatted(t.Columns[col_name])

to_remove = IndexSet(t.RowCount, False)
for r in t.GetRows(cur):
raw = cur.CurrentValue
if raw is None:
to_remove.AddIndex(r.Index)
continue

s = str(raw).replace("%", "").replace(",", "").strip()
if s == "":
to_remove.AddIndex(r.Index)
continue

try:
v = float(s)
except:
to_remove.AddIndex(r.Index)
continue

if v <= threshold:
to_remove.AddIndex(r.Index)

print("[FILTER]", table_name, "remove =", to_remove.Count, "remain =", t.RowCount - to_remove.Count)
t.RemoveRows(RowSelection(to_remove))

五、unexpected indent 是什麼?為什麼 Spotfire/IronPython 特別容易中招?

很多 Spotfire 腳本的第一個錯誤不是邏輯,而是:

SyntaxError: unexpected indent


這幾乎都跟「縮排」有關,常見原因:

  1. Tab 跟空白混用(你以為對齊,IronPython 覺得不對)

  2. if / for / def 少了冒號 :

  3. 該在外層的 print() 卻縮排進去

工程師建議:

  • 全部統一用 4 個空白

  • 不用 Tab

  • 程式先貼到 VSCode / Notepad++ 做「Convert Tabs to Spaces」再貼回 Spotfire


六、真正能快速解決 BIN 不顯示的三個結論

✅ 結論 1:欄位判斷要用 DataTable(資料表),不是視覺參照

  • Document.Data.Tables["..."].Columns 做欄位判斷

  • TablePlot.Data.DataTableReference 做欄位加入

✅ 結論 2:不要用 str(column) 當欄位名

  • 一律用 column.Name

✅ 結論 3:任何會刪資料的過濾,都必須印 RowCount

  • 過濾前後都要印

  • 刪除前先計算「會刪幾筆、會剩幾筆」


七、常見 FAQ

Q1:為什麼我印得出 BIN 欄位,但表格就是不顯示?

因為你印的是「資料表的欄位」,但你加欄位用的是「視覺物件參照」,兩者欄位集合可能不同步或名稱格式不同。

Q2:為什麼一加上 Rate% 過濾,圖表就全空?

通常是欄位名不一致、格式是 % 字串、或你把 Null/空值都當作要刪除,最後刪到 0 筆。

Q3:Spotfire 腳本除錯最有效的方法是什麼?

RowCount。把每段處理後的資料筆數印出來,最能立刻定位是哪一步把資料弄沒。


結尾:用工程師方式除錯,Spotfire 問題會變得很可控

Spotfire 的腳本除錯其實跟一般程式一樣:
不是靠猜,而是靠「可觀測性」:RowCount、欄位名、每一步的輸出。

只要你掌握:

  • 正確使用 DataTable vs DataTableReference

  • 欄位名用 .Name 不用 str()

  • 過濾前後都印 RowCount

「BIN 不見」與「圖表空白」就會從玄學變成可快速定位的工程問題。

留言

這個網誌中的熱門文章

🔍Vue.js 專案錯誤排查:解決 numericFields is not defined 與合併儲存格邏輯最佳化

🖥️遠端桌面連線完整新手指南:Windows RDP、Chrome Remote Desktop、AnyDesk、TeamViewer 一次搞懂

🔎EF Core 連 Oracle 出現 ORA-00600 [kpp_concatq:2] 的完整排錯指南(含 EF Core ToString/CultureInfo 錯誤)