<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />幾年前,我正在構建一個腳本來自動生成用於屬性式測量系統分析的採樣計劃。 一切都很順利,直到我遇到了一個大問題:如果在運行時選擇了部件數量,如何讓腳本彈出一個窗口來生成正在使用的部件的主“通過/失敗”列表? 現在,您可能已經在考慮一種簡單的方法來做到這一點。 然而,我仍然為我想出的方法感到自豪,我將在這篇博文中分享這一點。
JSL 腳本索引的編程部分中隱藏著 2 個看似無害的條目:Eval 和 Parse。 這些函數允許狡猾的腳本編寫者執行字符串,就好像它是一段代碼一樣。 能夠做到這一點具有驚人的意義。 這樣做也可以解決我之前的問題。
讓我們通過構建一個簡單的腳本來深入研究:
//第1節:
//獲取某一部分的通過/失敗標準
//初始化一些變量
我= 1 ;
列表零件= {} ;
//構建模態窗口以獲取條件
新窗戶( “獲取通過/失敗列表” ,
<<莫代爾,
H 列錶框(
V 列錶框(
陣容盒( 2 ,
文本框(字符(我)) ,列表零件[我] =文本編輯框( “經過” ) ,
按鈕盒( “好的” ,列表零件[我] =列表零件[我] <<獲取文本; ) ,按鈕盒( “取消” )
)
)
)
) ;
//查看列表
展示(列表零件[我]) ;
確保顯示日誌,然後運行此腳本。 腳本本身會顯示一個窗口,並僅針對一個部分詢問該部分是“通過”還是“失敗”。當按下 OK 按鈕時,窗口中的任何文本都會傳遞到 i th listParts 列表中的位置,並且 listParts 顯示在日誌上。 將結果存儲在僅包含 1 項的列表中目前看來有點愚蠢,但當我們有多個零件要存儲通過/失敗標準時,這是有意義的。 請參閱下面的示例,了解腳本的 3 個部分:
//第2節:
//重複上述腳本,但獲取 3 個部分的標準
我= 1 ;
列表零件= {} ;
新窗戶( “獲取通過/失敗列表” ,
<<莫代爾,
H 列錶框(
V 列錶框(
陣容盒( 2 ,
文本框(字符( 1 )) ,列表零件[ 1 ] =文本編輯框( “經過” ) ,
文本框(字符( 2 )) ,列表零件[ 2 ] =文本編輯框( “經過” ) ,
文本框(字符( 3 )) ,列表零件[ 3 ] =文本編輯框( “經過” ) ,
按鈕盒( “好的” ,為了(我= 1 ,我<= 3 ,我++,列表零件[我] =列表零件[我] <<獲取文本; )) ,按鈕盒( “取消” )
)
)
)
) ;
展示(列表零件) ;
但是,我們還沒有解決這個問題。 我們如何使該腳本基於某些任意數量的部分顯示動態數量的文本框,這些部分直到腳本開始運行後才知道,並且每次運行腳本時都可能不同? 前面提到的神童 Eval 和 Parse 來拯救我們了。 看一下下面的代碼:
//第3節:
//確定零件數量
新窗戶( “有多少部分?” ,
<<莫代爾,
鼻=數字編輯框( 10 ) ,
按鈕盒( “好的” ,零件數=鼻<<得到; )
) ;
展示(零件數) ;
列表零件= {} ;
//為模式窗口構建腳本的第一部分
//“is \!”的轉義字符序列
A = ”
新窗口(\!"獲取通過/失敗列表\!",
<<莫代爾,
H 列錶框(
V 列錶框(
陣容盒( 2,
” ;
//for 循環創建第二部分,它會構建盡可能多的輸入框
// ||是連接的快捷方式
乙= ”” ;
為了(我= 1 ,我<=零件數,我++,
b1 =字符( “文本框(字符(” ||字符(我) || ")), 列表部分[" ||字符(我) || "] = 文本編輯框(\!"通過\!")," ) ;
乙=乙|| b1 ;
) ;
//構建模態窗口腳本的最後一部分
C = ”
按鈕框(\!"確定\!", for (i = 1, i <=numParts, i++, listParts = 零件清單<< 獲取文本;)),按鈕框(\!"取消\!")
)
)
)
)
” ;
//合併部分腳本並執行
d = A ||乙|| C ;
評估(解析( d )) ;
//看看創建了什麼
展示( d ) ;
展示(列表零件) ;
首先,有一個部分詢問用戶有多少個零件,這些零件存儲在 numParts 中。 接下來,該腳本創建三個獨立的字符串,它們看起來很像 JSL,只不過它們都是紫色的。 第一個字符串只是之前腳本的精確副本(使用一些特殊代碼使引號字符不會結束字符串),一直到插入文本框的部分。 第二部分是一個 for 循環,用於構建一個字符串,其中包含先前輸入的多個部分 (numParts) 重複的文本框。 第三部分是之前腳本的最後部分。
創建該字符串後,我們將它們組合起來( d = A ||乙|| C ; ),然後使用評估(解析( d )) ;命令來評估當 JMP 解析字符串 d(我們動態創建的具有可調整數量的文本框的字符串)時會發生什麼,就好像字符串 d 是 JSL 腳本,而不僅僅是一個字符串一樣。 查看日誌以查看顯示大量文本框的超長命令,以及生成的通過/失敗列表(如果您只接受默認值,則如下所示):
d = ”
新窗口(\!"獲取通過/失敗列表\!",
<<莫代爾,
H 列錶框(
V 列錶框(
陣容盒( 2,
文本框(char(1))、listParts[1] = 文本編輯框(\!"通過\!")、文本框(char(2))、listParts[2] = 文本編輯框(\!"通過\") !"),文本框(char(3)),listParts[3] = 文本編輯框(\!"通過\!"),文本框(char(4)),listParts[4] = 文本編輯框(\ !"通過\!")、文本框(char(5))、listParts[5] = 文本編輯框(\!"通過\!")、文本框(char(6))、listParts[6] = 文本編輯框(\!"通過\!"),文本框(char(7)), listParts[7] = 文本編輯框(\!"通過\!"),文本框(char(8)), listParts[ 8] = 文本編輯框(\!"通過\!"),文本框(char(9)), listParts[9] = 文本編輯框(\!"通過\!"),文本框(char(10) ), listParts[10] = 文本編輯框(\!"通過\!"),
按鈕框(\!"確定\!", for (i = 1, i <=numParts, i++, listParts = 零件清單<< 獲取文本;)),按鈕框(\!"取消\!")
)
)
)
)
”;
listParts = {"通過", "通過", "通過", "通過", "通過", "通過", "通過", "通過", "通過", "通過"};
花點時間思考一下這裡的含義。 有了這些概念,您就可以創建能夠自行調整然後自行執行的代碼。 動態、自引用、遞歸和瘋狂的腳本可能只是一個開始。 如果有足夠的時間和耐心,您可能可以使用這個概念來創建天網。 轉念一想,也許這不是一個好主意……
看看非類型變量的令人愉快的奧秘! 使用 JSL 時很容易陷入類似的情況。 我也曾不小心犯過不應該工作的代碼,當 JMP 的更高版本或不同的操作條件導致我的草率最終失敗時,這真是一個需要解開的結。
我願意承認細節,但我不記得任何內容(也許我在壓抑?),JSL 俱樂部的第一條規則是你不要談論 JSL 俱樂部發生的事情。
我只想說,你的後續行動讓我捧腹大笑。
除了艾琳所說的之外,我還可以將其追溯到我自己的一些愚蠢之處,因為在這個例子中我沒有一直正確使用名稱。 我認為正在發生的事情是,當創建窗口時,會創建一堆文本框。 文本框是對象,這意味著應該可以向它們發送 << Get Text() 消息。 愚蠢(運氣?)的地方是每個文本框都被分配了名稱 ListParts,所以如果我真的很幸運什麼時候我向 ListParts[x] 發送 Get Text () 消息,我實際上得到了一些文本。 回想起來,我應該將 listParts[x] 文本框命名為其他名稱(即,在下面的示例中,用 tb[1] 替換 ListParts[1])。
Text Box(char(1)), listParts[1] = Text Edit Box("Pass"),
我認為這是一個罕見的例子,當腳本執行作者想要的事情時,儘管實際上是不正確的,這有點令人興奮!
這裡的問題是 <
您無法向不是對象的事物發送消息,列表也不是與數據表相同意義上的對象。 我最近修復了一個客戶插件中長期存在的錯誤,因為我意識到我曾嘗試這樣做
list<<INSERT item=""></INSERT>
代替
insert item(list, item)
我認為我們很多人感到困惑的是關聯數組是可以接受 << 消息的對象,因此您會看到具有相同名稱的命令的不同語法,例如:
map=associative array(:Name, :Weight);
map<<INSERT item=""></INSERT>
回到手頭的問題,我不太確定為什麼該示例首先使用 listparts[i]<回复:Eval ()、Parse () 和遞歸,元編程的一次冒險
很好的例子,謝謝@傑德坎貝爾。我有一個似乎無法解決的問題。我收到錯誤:在訪問或評估 'List' 時發送期望可編寫腳本的對象,{/*###*/"Pass", "Fail"}
我認為這是這個發送命令引起的問題。僅當我選擇超過 1 個數字時才會出現錯誤。有什麼想法嗎?
listParts = listParts << Get Text;