<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;