提示使用者選擇列是JMP腳本中非常常見的任務。在編寫腳本時,需要考慮一些因素,以幫助您確定最佳方法。
首先,想想你希望視窗的外觀如何。除了選擇列之外,視窗是否應該允許使用者指定其他選項?最重要的是,你希望視窗如何運作?
模態視窗與非模態視窗
模態視窗會導致腳本暫停並等待使用者互動。用戶與視窗互動並將其關閉後,腳本的剩餘部分才會繼續執行。例如,「首選項」視窗(「檔案」>「首選項」)就是一個模態視窗。在「首選項」視窗關閉之前,JMP 不會執行任何其他操作。
使用非模態窗口,窗口會保持開啟狀態,腳本無需等待任何使用者互動即可完成運行。例如,Fit Model 平台啟動視窗(分析 > Fit Model)。請注意,您可以保持視窗開啟並在 JMP 中執行其他任務。甚至還有一個複選框,用於在分析創建完成後保持對話框打開。這就是非模態視窗的範例。您可以選擇使用保持開啟的非模態窗口,以便使用者可以選擇不同的列和角色。
那麼,如何決定使用模態視窗還是非模態視窗呢?主要考慮因素是您是否希望 JMP 等待用戶輸入。如果腳本的其餘部分依賴使用者的選擇,那麼您應該使用模態視窗。由於建立模態視窗有兩種常用方法,讓我們來探討一下這些選項。
列對話框()
ColumnDialog() 是一個內建函數,可用於快速產生模態對話框,提示使用者從目前資料表中選擇列。腳本編寫者只需選擇對話方塊中顯示的方塊類型,但對佈局幾乎沒有控制權。以下範例腳本提示使用者選擇兩列 X 軸列和兩列 Y 軸列。
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Fitness.jmp" );
dlg = Column Dialog(
yList = Col List( "Y",
Min Col( 2 ),
Max Col( 2 ),
Data Type( "Numeric" )
),
effectList = Col List( "Effects",
Min Col( 2 ),
Max Col( 3 ),
Data Type( "Numeric" )
)
);
向使用者顯示的視窗如下所示:

請注意,腳本作者只提供了兩個「列清單」顯示框的選項。左側目前資料表中的列清單是內建功能的一部分。
使用者做出選擇並點選確定後,結果會顯示使用者選擇的列表,例如:
dlg = {yList = {:Age, :Oxy}, effectList = {:RunPulse, :RstPulse}, Button(1)};
列表中的各個表達式不會被求值。因此,要使用選定的列,您可以透過幾種方式卸載列列表以供分析使用。例如,您可以將dlg清單變數設為下標,並將列清單指派給一個新變量,或者您可以使用相同的名稱:
yList = dlg["yList"];
effectList = dlg["effectList"];
另一種卸載列清單的方法是使用 `Eval List()` 函數來評估 `dlg` 清單變數中的項目。在評估清單中的其他項之前,會先移除 `dlg` 清單中的最後一項,因為`Button(1)`不需要任何評估。
Eval List( Remove( dlg, -1 ) )
現在,如果您執行顯示符號 ();您將看到所有已定義的變量,並且列選擇儲存在 yList 和 effectList 變數中。
// Here
dlg = {yList = {:Age, :Oxy}, effectList = {:RunPulse, :RstPulse}, Button( 1 )};
dt = Data Table( "Fitness" );
effectList = {:RunPulse, :RstPulse};
yList = {:Age, :Oxy};
// 4 Here
無論你選擇哪一種方法來卸載這些值,都可以在分析中使用 yList 和 effectList 變數:
fm = dt << Fit Model(
Y( Eval( yList ) ),
Effects( Eval( effectList ) ),
Personality( "Standard Least Squares" ),
Emphasis( "Effect Leverage" ),
Run
);
那麼,使用 ColumnDialog() 時需要考慮哪些主要因素呢?
- 當前資料表中的列選擇器始終存在。雖然這在需要使用者選擇列時很方便,但也限制了此類模態視窗的使用。
- 您需要編寫的腳本程式碼量相當少。您可能會發現內建功能完全能夠滿足您的需求。但是,自訂功能有限。例如,只有三個建構子可以控制視窗中顯示框的排列方式:HList()、VList() 和 Line Up Box()。
- ColumnDialog() 函數傳回的值是固定的。作為腳本編寫者,您應該知道 ColumnDialog() 函數始終會傳回一個需要提取的值清單。缺點是需要額外的步驟來卸載這些值,並且在檢索使用者選擇的方式上靈活性較低。
有關 Column Dialog() 可用建構函式的完整列表,請查看腳本指南中「顯示樹」章節的「Column Dialogs 建構子」部分。
新視窗()
`New Window()` 是一個內建函數,可用於產生模態或非模態窗口,其用途廣泛,例如提示使用者選擇列,或向使用者顯示重要資訊。由於提供了數量眾多且種類繁多的顯示框,您可以使用 `New Window()` 建立高度自訂的模態視窗。
隨著自訂選項的增加,需要編寫的程式碼量也隨之增加。以下範例展示了一個與上面所示的「列對話框」類似的視窗。請注意,某些顯示框的名稱相似。例如,「垂直列錶框」、「水平列錶框」、「面板框」和「列列錶框」用於控制視窗的佈局。其餘顯示框則是視窗中可見的元素,例如按鈕和列清單。
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Fitness.jmp" );
nw = New Window( "Launch Dialog",
<
<MODAL>
V List Box( Align( "right" ),
<STRONG>H List Box</STRONG>(
<STRONG>Panel Box</STRONG>( "Select Columns", clb = Filter Col Selector( dt, all ) ),
<STRONG>Panel Box</STRONG>( "Cast Selected Columns into Fit Model Roles",
<STRONG>Lineup Box</STRONG>( N Col( 2 ), Spacing( 5 ), Button Box( "Y", clbY << Append( clb << Get Selected ) ), clbY = Col List Box( "Numeric", MinItems( 2 ), MaxItems( 2 ), nlines( 3 ) ), Button Box( "Effects", clbEffects << Append( clb << Get Selected ) ), clbEffects = Col List Box( "Numeric", MinItems( 2 ), MaxItems( 3 ), nlines( 4 ) ), Button Box( "Remove", clbY << Remove Selected; clbEffects << Remove Selected; ) ) ) ),
<STRONG>H List Box</STRONG>( Button Box( "OK", yVars = clby << Get Items( "Column Reference" ); eVars = clbEffects << Get Items( "Column Reference" ); ), Button Box( "Cancel" ) ) ) );
</MODAL>
向使用者顯示的視窗如下所示:

在這個範例視窗的腳本編寫方式中,選定的列被賦值給「確定」按鈕中的 JSL 變數。您可能會想,也可以在「Y」按鈕和「效果」按鈕的腳本中賦值列,作為替代方案。這確實可行。但是,由於使用者可以將列拖放到列列錶框中,這些按鈕可能永遠不會被點擊。因此,按鈕腳本將永遠不會執行。如需其他方法,請參閱「文件編寫指南」中「顯示樹」章節的「從視窗擷取值」部分。
執行展示 ( yVars, eVars );將在日誌中列出這些值(查看 > 日誌):
yVars = {:Age, :Oxy};
eVars = {:RunPulse, :RstPulse};
這些變數無需卸載即可在 Fit 模型啟動中使用。
fm = dt << Fit Model(
Y( Eval( yVars ) ),
Effects( Eval( eVars ) ),
Personality( "Standard Least Squares" ),
Emphasis( "Effect Leverage" ),
Run
);
不要被大量的腳本程式碼嚇到。讓我們來看看這個模態新視窗 (New Window()) 中可用的一些自訂選項。以下項目與上圖的數字相對應。
- New Window() 函數可讓您為腳本項目提供一個有意義的視窗標題。在本例中,我們使用了簡單的標題「啟動對話方塊」。
- 分組上方顯示的文字可以自訂。這樣,您可以為使用者提供分組的簡短說明或描述。
- 可以透過 `Col List Box()` 函數的可選參數來指定顯示的行數,該函數用於顯示選定的列。這樣,您可以控制顯示框中顯示的列數。您也可以為了美觀而添加額外的空間,如上圖所示。
- 列列表可以來自任何已開啟的資料表,而不僅僅是目前開啟的表。請記住,`New Window()` 函數可用於各種對話訊息傳遞。因此,顯示列列表是可選的。
- “確定”按鈕可以自訂功能。此外,「取消」按鈕是可選的。
New Window() 函數提供了比這裡示範的更多的建構函數,例如滑桿、單選按鈕、圖片、圖表等等!有關 New Window() 函數可用建構函式的列表,請查看文件編寫指南中「顯示樹」章節的「為 New Windows 建立顯示框」部分。
總而言之,`ColumnDialog()` 提供了一種快速簡單的視窗建立方式,但自訂功能有限。另一方面,模態的 `NewWindow()` 提供了極大的自訂彈性,但在創建時需要更多的思考和腳本編寫。顯然,這兩種方法各有優勢,我猜您最終都會發現它們的用武之地。幸運的是,您的工具箱裡完全可以容納它們!