| 扬声器 |
抄本 |
| 温迪·默弗雷 |
大家好,感谢您今天的演讲。我们很高兴能和大家探讨不同经验水平的脚本作者经常遇到的场景。 |
| |
我们的目的是解释发生了什么,以便您掌握避免这些错误所需的工具和知识。那就让我们开始吧。 |
| |
或许是因为默认情况下不打开,所以很容易忘记检查日志中的消息。但日志中包含了有关最近脚本执行的有用信息。让我们在 JMP 中仔细看看这个示例。 |
| |
这里我们可以看到,该脚本只是打开一个数据表并尝试选择一行。运行此脚本时, |
| |
对于致命错误,也就是脚本因错误而停止的情况,我们会收到一个交互式错误消息。弹出窗口是 JMP 15 的新功能,您可以在首选项中关闭此功能。 |
| |
当我们关闭该消息时,我们可以检查日志,我们会从窗口中看到相同的消息,但我们也会看到行号 |
| |
找到脚本文件的名称,帮助我们找到问题所在。现在,不要仅仅依赖这些弹出窗口,因为日志中还会出现其他重要消息。 |
| |
并且它们不一定会导致弹出窗口。那么我们来看另一个例子。 |
| |
在此脚本中,作者尝试打开一个表,创建一个分析,并将一条消息打印到日志中。 |
| |
当我们运行这个脚本时,我们立即注意到我们的分析没有生成。 |
| |
因此,我们再次检查日志 |
| |
我们看到数据表中没有找到某一列,但脚本继续运行并将我们的消息打印到日志中。 |
| |
所以这里最重要的一点是,一定要检查日志,尤其是当发生的情况不符合你的预期时。这可能只是列名拼写错误而已。 |
| |
当前数据表的概念通常被描述为活动表。但是,是什么让该表成为活动表或当前数据表?它又为何与你的脚本息息相关? |
| |
当打开、创建或以其他方式对表进行操作时,它会成为当前数据表。但是,还有一些其他方式可以使表在运行时成为当前表,而这些方式可能是脚本作者意想不到的。 |
| |
JMP 在后台处理的任务。例如,JMP 可能需要计算公式或更新窗口。 |
| |
这些后台进程可能会导致运行时激活的表与您预期的表不同。这可能会导致脚本失败,或者更糟的是,您甚至没有意识到 JMP 使用了错误的表。 |
| |
因此,我们在这里提供了一些 |
| |
使用特定于数据表的引用来编写脚本的最佳实践。这样,无论运行时处于活动状态的表是什么,都可以确保使用正确的表。 |
| |
在此示例中,我们演示了如何向特定数据表发送双变量调用,以确保该表中的数据用于您的分析。 |
| |
您还可以将新列用作发送到特定数据表的消息,这将确保您的新列在所需的表中创建,并且不会转到当前的任何内容。 |
| |
您还可以使用可选的数据表引用。这里我们仅演示如何使用它来引用列,稍后我们将更详细地讨论如何引用列。 |
| |
您还可以在函数中使用可选的数据表引用;对于每一行和汇总是两个可用的地方。 |
| |
我们还建议您避免使用数据表……在生产脚本中使用当前数据表函数分配数据表引用。在本例中,我们将连接两个数据表,并希望分配对该表的引用。 |
| |
这是通过连接创建的。现在,连接返回对新创建表的引用。因此,我们不想将其赋值给当前数据表,而是希望在创建连接时赋值。 |
| |
所以在这里,我们只需在调用连接时进行分配,当我们运行这个 |
| |
我们可以看到,我们的新 DT 变量确实引用了所需表,并且它不受当前表的影响。 |
| |
使用 JSL 变量识别列是一项常见任务,使用哪种方法取决于您的预期用途。 |
| |
列函数返回对列的引用,该引用是整个单元。它接受多种参数,例如,列名可以是字符串或字符串变量, |
| |
索引或表示索引的数字变量。它可以被下标引用特定行上的列值。 |
| |
可以使用列函数的一些地方是平台调用、向列发送消息或为列分配变量引用。 |
| |
as column 函数返回对当前行值的引用 |
| |
指定列的。它接受与列函数相同的所有参数,但需要注意的是,在 JMP 中,除非另有管理,否则当前行始终为零。 |
| |
因此,使用 as column 函数的绝佳场合是公式、for each row 和 select where,因为它们的设计使其能够在计算每一行时控制行。让我们看一个例子来解释一下我们的意思。 |
| |
这里我们打开一个示例数据表。我们已将一个 JSL 变量赋值给一列的名称,并尝试在 select where 语句中使用 column 函数。 |
| |
现在,当我们运行这个脚本时,我们发现没有选择任何行。这是为什么呢?因为 select where 会计算每一行的值, |
| |
使用不带下标的 column 函数将不会选择任何行。我们记得,column 函数返回的是整个列的引用,因此整列数据永远不会等于 14。 |
| |
因此解决方案是使用带有行下标的列函数(并且这个行下标只是表示当前行,无论在 select where 评估时它是什么),或者您可以使用 as column 函数来选择行。 |
| |
在公式中使用 JSL 变量可能会出现一些问题,原因如下。JSL 变量的生命周期仅限于当前 JMP 会话,并且随着变量值的变化,公式的结果也会随之变化。 |
| |
除非您查看公式编辑器中的公式,否则您可能不会意识到自己有问题。 |
| |
让我们看一下示例。在这里,我只需打开一个数据表,并创建一个要求和的列的列表。 |
| |
我正在创建新的公式列,并在 sum 函数中使用了我的 JSL 变量。运行一下。我们可以看到新列已创建并填充了数据。不过,我们先来看看公式编辑器。我们从未说过 sum 函数中使用了 JSL 变量。 |
| |
当我们忽略这一点并对其中一个相关列进行更改时,我们还注意到我们的列公式并没有自动更新。 |
| |
因此,让我们保存并关闭 JMP,保存此表并关闭 JMP。 |
| |
我们将重新开始。 |
| |
现在请记住,该 JSL 变量的生命周期仅限于前一个 JMP 会话。那么,让我们打开表格,看看会发生什么。 |
| |
我们注意到变量...列公式仍然没有再次求值。查看时,我们仍然可以看到 JSL 变量,但现在它下方出现了一条红线。将鼠标悬停在红线上,我们可以看到名为“未解决”的错误。 |
| |
如果我们尝试重新计算公式,就会收到错误消息,而忽略这些错误会导致所有数据都变为缺失值。那么该如何解决这个问题呢? |
| |
在公式中使用变量时,您需要执行一些操作来指示 JMP 在计算公式之前用其值替换该变量。您可以使用替换函数来实现这一点,但今天我们将演示表达式函数。所以,让我们先结束这个表格。 |
| |
我们将打开表格的新副本并重新建立列表。 |
| |
现在让我们看看如何解决这个问题。 |
| |
因此,eval 表达式函数告诉 JMP 评估并替换其中的任何变量...在其参数中,这些变量被包装在 EXPR 函数中。 |
| |
然后它将返回未求值的表达式。因此,在这段代码中,JMP 将替换表达式 SAT 分数,并将其替换为我们的列表。 |
| |
让我们运行一下这部分代码,看看会发生什么。我们看到 sum 函数现在得到的是我们要求和的列的列表,而不是变量本身。 |
| |
但它实际上并没有为我们创建列。它只是返回了这个表达式。为了求值,我们在 eval 表达式函数周围添加了一个 eval 函数。 |
| |
这将导致 JMP 在替换完成后对整个新列表达式进行求值。所以本质上,邮件里说的是,运行……运行 eval 表达式返回的结果,也就是这个。 |
| |
因此,让我们运行它,我们可以看到我们的列现在已经创建,并且我们拥有我们期望的数据。 |
| |
我们的公式不再有变量,而是有列的列表。 |
| |
当我们对从属列中的数据进行更改时,我们的公式会自动更新。 |
| |
所以现在我要把这个交给贾斯汀来谈谈另外几个需要避免的错误。 |
| 贾斯汀·奇尔顿 |
好的,我们看到人们常犯的另一个错误是设置列属性时语法可能有点棘手。在我们深入讨论细节之前, |
| |
让我们从列属性的角度来讨论一下什么是列。本质上,列就是 |
| |
此属性信息的存储库。它不进行任何语法检查以确保 |
| |
你传入的内容是正确的,这使得它能够存储任何你想要的内容。这意味着,这是因为属性的使用者期望某些内容采用特定的格式,无论是 JMP 平台、使用列属性,还是 JSL 应用程序。 |
| |
让我们看一个简单的例子。 |
| |
这里,我们将打开一个名为“列属性”的表,仅用于测试。我们有一列名为“NPN1”,还有一列名为“测试”。此列包含规格限制和访问属性,但我们希望 |
| |
添加要测试的规格限值属性。这样我们就得到了我们认为 |
| |
是设置规格限值列属性的正确语法。我们运行这个程序,没有报错,但是当我们 |
| |
查看该列,该列有规格限制。 |
| |
你可以,但你可以看出它不正确。当我们要求根据规格限值进行过程能力分析时, |
| |
运行该程序后,NPN1 确实返回了结果,但测试列却没有返回结果。这是因为测试列的规格限值属性中存储的内容不正确。 |
| |
因此,如果您已经知道如何使用设置属性规范限制,那么可以这样做: |
| |
你可以直接将属性消息发送到 NPN1 列,我们知道这一列是正确的。所以,只要运行这一行,就能得到正确的语法。 |
| |
这实际上表明,这应该以列表形式呈现,而不是单独的参数。换句话说,如果您不熟悉 get 属性,您可以转到您知道正确的列并复制列属性。 |
| |
然后,您可以将其粘贴到脚本中,然后会看到您添加了列属性以及几个设置属性。因此,添加列属性只是批量处理多个设置属性的一种方式。我们可以删除它,也可以删除额外的访问权限。 |
| |
属性。移除之后,我们可以使用这个 set 属性,通过发送运算符将其发送到测试列。现在,当我们运行这个程序时, |
| |
我们......它......它已经覆盖了我们的规格限制,但我们可以通过使用我们的规格限制运行相同的分布来确认这一点。 |
| |
所以,您可以看到,我们对两列都进行了过程能力分析。这只是获取规格限值的一个例子,但同样的方法也适用于任何您需要应用并获取 JSL 语法的列属性。 |
| |
我们要讨论的下一个错误是操纵调度命令。那么什么是调度命令呢? |
| |
当您执行红色三角形菜单的保存到脚本窗口或保存到剪贴板时,它就会出现在您保存的脚本中。 |
| |
当你添加参考线之类的内容,或者更改其他内容(例如关闭轮廓框)时,它就会出现。这个命令是 JMP 内部开发的,用于重新创建图表。 |
| |
你的定制功能。而且它并没有计划让用户 |
| |
使用动态变量进行自定义。这意味着调度命令中的某些参数不接受 JSL 变量。我们来看一个可能发生这种情况的例子。这里有一个脚本。我们有一个 |
| |
表格和一个稍后会用到的字符串变量。这基本上就是“保存到脚本”窗口返回的内容。所以当我们运行这个程序时, |
| |
我们可以看到,我们的调度命令设置了测量轴的最小最大和增量 |
| |
此处设置为从 0 到 1.4。现在我们可以看到调度命令依赖于 |
| |
这里是轮廓框标题,但这个轮廓框标题实际上是基于我们的 y 输入的。假设我们希望这是来自用户的动态输入,我们只需要这个变量。我们可以用这个变量来表示 Y。 |
| |
但是我们还需要使用此处该列的名称。因此,当我们运行此程序时,您实际上会看到我们没有获得正确的轴设置 0.4 到 1.2,这不对……这意味着我们发送的内容未被处理。 |
| |
有几种方法可以解决这个问题。第一种方法是使用 Wendy 几分钟前谈到的 eval 表达式解决方案。所以在这里你可以看到我们有相同的 eval 表达式。我们实际上想包装上一个示例中尝试过的串联操作。 |
| |
这里。 |
| |
eval 表达式会计算整个表达式的值。所以当我们运行 eval EXPR 时, |
| |
它只是用我们连接的字符串替换了整个内容,然后,记住当我们进行评估时, |
| |
它运行那个表达式。所以这里我们有0到1.4。这是一种方法。 |
| |
但有时还是会有点棘手。你该如何真正操作这些调度命令呢?因为你仍然在使用调度命令,你必须了解它们的工作原理。所以最常见的方法是完全删除这个调度命令。 |
| |
所以,使用我们所说的显示框下标。在这里,我将使用已移除的调度命令运行它,这样我们就得到了原始的轴设置。 |
| |
然后我们要做的就是,在我们不知道怎么写之前,只能通过观察来理解。所以我们要找到这个图标,也就是轮廓框,右键点击 |
| |
编辑并显示树形结构。这显示了轮廓框内的显示框树形结构,在这个轮廓框中,您可以看到这个轴框就是我们想要更改的轴框。轮廓框内是轴框一。 |
| |
然后我们就可以开始编写脚本了。我们使用这个报表函数来获取平台的报表层 OBJ1。 |
| |
然后,我们根据列名下标来获取我们知道的轮廓框标题。 |
| |
然后,我们希望...我们希望尽可能具体,这样如果 JMP 的未来版本发生变化,我们就不太可能遇到问题。 |
| |
因此,在其中,我们需要轴框 1,这就是我们获取该轴框的方式,然后我们可以从调度命令中获取相同的信息,并将它们转换为我们发送到轴框的消息。 |
| |
然后您可以在这里看到,现在我们的轴设置是从零到 1.4。 |
| |
另一种更强大的方法是使用 XPath。它的作用相同,但可能稍微复杂一些,但也为 JMP 的未来版本提供了更大的灵活性,因为您可以使用框的底层数据。 |
| |
我们要讨论的最后一个错误是只使用全局命名空间。 |
| |
你可能不知道,当你创建一个符号而没有指定它的位置时,它会进入全局命名空间。所以,当你只是为个人用途模拟一些东西时,这非常适合快速脚本。 |
| |
但对于您发送给同事的脚本或您发布的脚本或在社区上发布的插件来说,这可能不是一个好主意。 |
| |
关于 JMP 中作用域和名称查找的工作原理,我们再详细说一下。请从这张图的底部开始。局部作用域可以是任意数量的作用域,其中包含函数和局部框。 |
| |
因此,如果它没有找到符号,或者你没有指定它进入本地,取决于你是在写还是读, |
| |
然后是此处作用域,它本质上每个文件都有一个。然后是全局作用域,它本质上是 JMP 会话的一个作用域。然后在右边,是命名空间作用域,你必须明确地找到它才能 |
| |
访问。我们来看一个例子。这会删除我所有的符号,由于我没有指定它们应该放在哪里,所以它们会被放入全局变量中。所以 x 是 5。但如果其他人也有一个脚本,比如,嗯,我也 |
| |
有一个 |
| |
我想要使用的变量 x。我不打算指定它放在哪里。所以我把它设置为 10。 |
| |
但是当你回到你的脚本时,也许这是你设置的一些变量,然后你在按钮上有一些回调...按钮 |
| |
依赖于该变量的操作,然后您去使用它,但变量已经发生了变化,这可能不是您想要的。 |
| |
那么,我们有什么方法可以解决这个问题呢?最简单的方法是使用名称默认为 here(1)。这意味着,除非你明确指定,否则任何内容都不会进入全局范围。让我们来看看 |
| |
此时 |
| |
例如。我们所做的就是将这个名称 default 添加到这里(1)。它可以放在……通常放在脚本的顶部,但实际上可以放在任何地方。 |
| |
我要清理我的符号,并将这个变量 x 设置为 5。这样我们这里就有一些其他的经文了 |
| |
意思是“我想访问你的 x”。但实际上,这个 x 永远无法访问这个命名空间中的 x。所以 |
| |
让我们复制部分脚本并让 X 等于 50。 |
| |
这样,右边文字中的 X 是 50,但这对左边文字中的 X 没有影响。所以,这是一种轻松区分符号与其他文字和应用程序的好方法。 |
| |
另一个选项是使用自定义命名空间。这有点高级,但功能非常强大。所以我又来了……清除我的 |
| |
符号,然后创建一个新的命名空间,在命名空间中设置一个变量 x 并显示它。所以它的值为 5。 |
| |
你还有另一个剧本。也许这是你的剧本之一,你知道 |
| |
myNS 确实存在。所以你可以尝试访问它,而且你完全可以做到,因为你知道它的名字。但这样一来,不法分子在你不知情的情况下更改你的符号的可能性就小得多。所以 |
| |
我可以改变这个符号,它仍然是 10,但如果我只是做 X,它实际上不会对命名空间中 X 的结果产生任何影响。 |
| |
我要把它交还给温迪,她将向我们讲述一些被忽视的资源。 |
| 温迪·默弗雷 |
谢谢你,Justin。有很多资源可以帮助你了解更多关于 JSL 的知识,其中很多都是免费的。这里我们为你链接了一些比较常见的 JSL 学习资源。 |
| |
我们还提供技术支持,您可以随时联系,此外还有几本关于该主题的书籍。当然,我们始终鼓励您查看我们的培训资源以及其中为您准备的计划。 |
| |
请务必查看与 JMP 社区本次演示相关的论文,因为我们之前在论文中已经提到过一些错误,但今天没时间一一讨论。感谢您的观看。 |