????作者简介:博主是一位.Net开发者,同时也是RPA和低代码平台的践行者。
????个人主页:会敲键盘的肘子
????系列专栏:UiPath
????专栏简介:UiPath在传统的RPA(Robotic process automation)的基础上,增加了See(AI通过计算机视觉阅读用户的计算机屏幕)和Think(通过机器学习来发现平台能够为用户构建什么自动化流程)从而不断帮助用户自动化构建流程,而不仅仅是用户自主发现,自主构建。并且在构建的过程当中,做到了Low-code甚至是No-code的程度,让每一位员工都可以自主使用。
????座右铭:总有一天你所坚持的会反过来拥抱你。
????写在前面:
在本文中,您将学习何时以及如何使用状态机 State Machine工作流布局及其特定活动。了解状态机布局是使用机器人企业框架模板和自动化更复杂流程的关键步骤。为状态机中的状态命名对于维护和未来开发非常重要;在UiPath Studio中,每个状态中显示的转换顺序非常重要,因为它与评估它们的顺序相匹配。
????本文关键字:RPA、UiPath、Low-code、No-code、State Machine、.Net
1️⃣ 背景
♈ 什么是RPA
RPA(Robotic process automation) 代表机器人过程自动化。
它是一种软件程序,可在与计算机应用程序交互时模仿人类行为并实现重复的、基于规则的流程的自动化。
♉ 什么是UiPath
UiPath 是一种机器人流程自动化工具,用于自动化枯燥和重复的任务。它由罗马尼亚企业家 Daniel Dines 和 Marius Trica 于 2005 年创立。它还消除了自动化无聊任务的人工干预,并为所有活动提供了拖放功能,它是最简单的 RPA 工具。
♊ 为什么使用UiPath
UiPath在传统的RPA的基础上,增加了See(AI通过计算机视觉阅读用户的计算机屏幕)和Think(通过机器学习来发现平台能够为用户构建什么自动化流程)从而不断帮助用户自动化构建流程,而不仅仅是用户自主发现,自主构建。并且在构建的过程当中,做到了Low-code甚至是No-code的程度,让每一位员工都可以自主使用。
♋ 环境
-
UiPath Studio Community 2022.4.3
-
Windows 10
-
.Net
♌ 本文收获
-
解释什么是状态机。
-
区分
State Machine
与Sequence
和Flowchart
。 -
解释何时应使用状态机。
-
列出一个州内步骤的执行顺序。
-
根据给定的要求构建基于状态机的流程。
2️⃣ 概述
实践证明,从一开始就为您的工作流程选择正确的布局,不仅可以实现快速、轻松的开发,还可以为您提供更好的扩展和管理方法。
UiPath提供了三个布局形式,用于在开发工作流文件时将活动集成到工作结构中。
♈ Sequence(序列)
序列有一个从上到下流动的简单线性表示,最适合活动相互跟随的简单场景。
例如,当导航和键入一次单击/击键时,它们在UI自动化中非常有用。因为序列易于组装和理解,所以它们是大多数工作流的首选布局。
♉ Flowchart(流程图)
流程图为连接活动提供了更多的灵活性,并倾向于以简单的二维方式布置工作流。流程图最重要的方面是,与序列不同,它们呈现多个分支逻辑运算符。这些使您能够创建复杂的业务流程并以多种方式连接活动。
流程图通常用于包含多个决策点的工作流。
♊ State Machine(状态机)
有些过程更好地表示为相互连接的状态,这些状态在必要时反复执行。在每个状态中执行一组活动,然后评估一个条件以确定要转换到下一个状态。例如,旋转栅门是一个状态机,至少具有以下状态:空闲、允许访问、拒绝访问和关闭。
-
在空闲状态下,当机器等待访问卡时,大门被锁定。当一个人出示门禁卡时,机器会评估是否必须接受该卡。
-
如果卡被接受,旋转栅门将转换为“允许进入”状态,此时大门打开,允许一个人进入。在人员进入或经过一定时间后,机器将转换回空闲状态。
-
如果卡被拒绝,旋转栅门将转换为“拒绝访问”状态,在该状态下显示该信息,大门将保持锁定。经过一段时间后,机器将转换回空闲状态。
-
当输入正确的代码时,机器将转换到关闭状态。
在Studio中,状态机工作流布局允许您基于有限数量的状态和转换来设计事件驱动的流程。该布局应用于复杂和连续过程的高级项目组织。因此,状态机通常用于Main.xaml用于RPA框架,如企业级框架Robotic Enterprise Framework
。
3️⃣ 理解状态机
♈ 现实生活中的状态机
为了更好地理解与状态机相关的概念,我们将查看恒温器控制空调的表示。
在使用空调UI之前,请务必阅读说明:
- 使用ON/OFF按钮启动或停止空调。启动后,空调将进入空闲状态。
- 在“Desired Temp.”(所需温度)字段中写入所需温度,然后单击“SET”(设置)。请注意,工作范围在15度和30度之间,因此任何低于15度或高于30度的值都将分别转换为15和30度。
- 一旦设定了温度,空调将进入HEAT(加热)或COLD(冷)状态。当达到所需温度时,它将显示在“Current temperature”(当前温度)下,空调将返回IDLE(空闲)状态。
♉ 状态机工作流演练
让我们分析一下作为Studio自动化项目的空调示例是什么样子。
如图可以看出,有三个简单的状态(空闲状态、热状态和冷状态)、一个最终状态(关闭)以及基于设置条件在状态之间导航的几个转换。
-
当期望温度=当前温度时,从怠速状态到怠速状态。
-
当期望温度>当前温度时,怠速状态变为加热状态。
-
当期望温度<当前温度时,怠速状态变为冷态。
-
加热状态和冷态,一旦达到所需温度,则返回到怠速状态。
-
当用户单击“确定”且用户输入值为“关闭”或“无”时,“空闲状态”变为“关闭状态”。
♊ 具体实现
⭐ State
因为它直接链接到Start节点,所以“Idle State”是自动化启动后用户登录的位置。它看起来可能类似于“主菜单”。在这里,它总是进入状态(除非选择关闭机器)。
-
Entry块包含进入状态时要执行的活动。
-
Exit块包含退出状态时要执行的活动。
-
Transitions块允许您添加将在进入和退出时执行的活动。
“Transitions”部分根据用户输入显示所有下一个目的地。
⭐ Transitions
当您在状态机容器中将状态链接到另一个状态或最终状态时,将创建Transitions。
如观察到的,转换到“目的地”状态(例如热状态)的条件是“期望温度”变量值高于“当前温度”值。
????注意:打开时,空调处于过渡状态或状态,因为空调过程是连续的。
⭐ The Final State
当用户键入“OFF”时,状态机将转换到结束进程的状态。在Studio的“工作流”>“状态机”>“最终状态”下可以找到这种类型的状态。在我们的工作流中,它被命名为“关闭”,并在停止自动化过程之前记录消息“AC关闭”。
????注意:您只能创建一个初始状态,但也可能有多个最终状态。所有状态机必须包含初始状态和至少一个最终状态。
4️⃣ 使用状态机创建Process
到目前为止,您已经通过与空调UI交互观察到了状态机的概念。之后,您进一步分析了Studio中的实际工作流。
接下来,您将查看在Studio中创建状态机的端到端过程。
♈ 需求
我们将构建一个流程,首先要求用户输入初始账户余额,然后让他们付款,直到初始余额耗尽或决定结束该流程。
为了实现这一点,我们将构建一个具有五个状态的状态机:获取初始余额、获取付款值、进行付款(如果资金可用)、拒绝付款(如果经费不足)和结束过程的最终状态。
♉ 实现
我们将项目作为一个序列启动,然后从Activities面板中添加状态机。
⭐ Get Initial Balance
为了获得用户的初始余额,让我们添加第一个状态。通过将其链接到Start,它将成为流程的初始状态。
我们将其重命名为Get Initial Balance,并添加一个注释来记录此状态的作用:获取帐户的初始余额。
要配置状态,我们需要打开它。让我们双击它。我们注意到,一个简单的State有三个可编辑的部分。Entry部分保存了进入状态时将执行的活动。“Exit”部分保存退出状态时将执行的活动,“Transitions”部分描述此状态相对于其他状态的转换。
因此,我们希望在流程的初始状态中实现的是向用户请求初始余额。为此,我们将在输入区域中使用输入对话框活动,并提示用户插入数字。
然后,我们需要将活动的输出存储在名为“InputValue”的字符串变量中。我们将确保为我们计划在其他状态中使用的所有变量设置一个全局范围,在本例中为状态机。
现在我们需要确保用户提供的输入是有效的。在我们的例子中,输入应该是一个Double(最多16位数字)。要执行此检查,我们将使用If活动和Double。TryParse方法,如果转换成功,则返回布尔值True,如果转换失败,则返回False。
然后,我们将创建一个名为CurrentBalance的新变量,并将其范围设置为State Machine,将其类型设置为Double。注意,我们不能使用Double将转换结果传递给变量。Assign活动中的TryParse方法。
如果InputValue变量的值可以用前面提到的方法解析,那么我们使用Double将其值分配给CurrentBalance变量。解析方法。
如果无法解析InputValue,我们将通过在Else块中使用MessageBox活动通知用户输入无效。
我们还要创建一个新的布尔变量,用于存储有关用户输入有效性的数据。我们将其称为“IsValidInput”,将其范围设置为State Machine,将默认值设置为True。
然后,我们将使用MessageBox下的Assign活动将值False分配给“IsValidInput”。
从这一点来看,执行可以采取两个不同的方向:
如果输入无效,应提示用户关闭付款流程。这意味着流程将转换到其最终状态,因此流程的执行将停止。稍后我们将创建最终状态。
如果输入有效,系统将提示用户输入其付款金额。这意味着流程将转换到“获取付款值”状态。
⭐ Get payment value
最简单的方法是复制并粘贴Get初始Balance状态,然后将其重命名为Get payment value。
我们还将添加一个注释来记录此步骤的目的:获取当前迭代的付款值。
现在,让我们双击打开状态并将输入对话框重命名为Payment value。
此时,用户将输入他们想要支付的金额,因此我们需要将该输入存储在名为PaymentValue的新变量中。
我们将其类型设置为Double,并为其提供全局范围。
在复制的Assign活动中,我们现在需要用新创建的变量PaymentValue替换CurrentBalance变量。因此,我们刚才所做的工作有助于我们涵盖用户添加有效双精度值或无效双精度值的两种情况。
⭐ Final State
回到状态机视图,我们注意到我们的过程还没有最终状态。使用状态机时,必须有一个状态机。
让我们将“Final State”活动拖到工作流的底部。
我们将双击打开状态。你可以看到,最终状态的结构不同于简单状态的结构。唯一可用的块是Entry块,它保存了进入状态时执行的活动。顾名思义,这是流程可以处于的最后一个状态,因此我们无法定义从最终状态到任何其他状态的任何转换。
现在让我们回到我们的例子。当用户到达这一点时,我们希望通知他们流程已完成。
我们将通过在最终状态的入口块中使用MessageBox活动来实现这一点。所以,我们现在有一个初始状态,一个简单状态和一个最终状态。是时候添加第一个过渡了。
⭐ Valid Input
至此,用户将输入他们的初始余额。
接下来,他们将被提示输入他们的付款值。只有当我们在Get initial Balance状态和Get payment value状态之间创建转换时,才能触发该操作。
我们通过在Designer面板中简单地连接两者来实现这一点。
然后双击打开转换并将其重命名为有效输入。
流程从初始状态(获取初始余额)移动到付款值状态的条件是用户提供有效输入。因此,我们设置了一个条件,即只有当IsValidInput变量将值保持为True时,才会触发转换。
对于用户输入在初始状态(获取初始余额)期间无效的场景,我们将创建从获取初始余额状态到最终状态的转换,并设置在输入无效时触发转换的条件。
⭐ Input Not Valid
现在,我们已经添加了从初始状态(Get initial Balance)开始的所有转换。
退出此状态后,将提示用户添加付款金额,或者如果输入无效,将提示他们完成该过程。
但是,如果用户转换到添加其支付金额的状态,则有三种可能的转换到下一个状态:
如果他们添加了一个无效的付款输入,过程将停止,我们将转换到最终状态。
让我们添加此过渡。
如果他们添加了一个有效的付款输入,并且他们有足够的余额来支付金额,他们的付款将被支付。为此,我们需要创建一个新的状态和三个新的转换。
如果他们添加了有效的付款输入,但他们没有足够的余额来支付金额,他们的付款将被拒绝。为此,我们还将创建一个新状态和三个新转换。
⭐ Deny Payment
在拒绝支付的情况下,我们希望让用户知道,由于资金不足,无法执行交易。我们还想显示他们的当前余额,并询问他们是否想继续进行另一笔交易。
那么我们该怎么做呢?我们首先添加一个新状态,将其重命名为拒绝支付,并添加一个注释,说明该状态的目的:显示有关拒绝支付的消息。
然后,我们打开状态并在Entry字段中添加MessageBox活动,以通知用户“由于资金不足,无法处理付款”。
我们继续在消息框中键入一个表达式,将当前余额返回给用户。
最后,我们询问用户是否要继续。
然后,我们关闭表达式编辑器,并将Buttons属性设置为YesNo,以获取用户关于他们接下来要做什么的输入。
我们将此输入存储在名为ContinueAnswer的新字符串变量中。
让我们确保将新变量的范围更改为状态机。
如果用户有足够的余额来支付金额,我们需要从当前余额中减去支付值的状态。然后,我们将让用户知道交易已处理,显示当前余额的值,并询问他们是否要继续。
⭐ Make Payment
最简单的方法是复制“拒绝付款”状态,将其重命名为“进行付款”,并添加注释,说明该状态的目的是显示有关付款和新余额的消息。
然后,我们使用Entry块中的MessageBox通知用户付款已成功处理。
我们现在需要从当前余额中减去付款金额。为此,我们在MessageBox上方添加一个Assign活动,并将其重命名为ReAssignCurrentBalance。然后,我们键入从当前余额中减去付款值的方法。
现在,我们已经制定了涵盖所有可能场景的状态。我们只需要添加剩余的过渡。
⭐ Insufficient Funds
因此,如果用户的付款输入有效,但他们没有足够的余额来支付金额,他们的付款将被拒绝,因此过程将从“获取付款值”状态转换为“拒绝付款”状态。
让我们添加这个转换,打开它,然后将其命名为“资金不足”,并确保我们设置了正确的条件:IsValidInput and CurrentBalance小于PaymentValue。
⭐ Sufficient Funds
如果用户的付款输入是有效的,并且他们有足够的余额来支付金额,他们的付款将被支付,因此过程将从“获取付款值”状态转换为“进行付款”状态。
让我们添加此转换,打开它,然后将其命名为充足资金,并确保设置了正确的条件:IsValidInput and CurrentBalance大于或等于PaymentValue。
现在,让我们确保从Get payment value状态正确设置了所有转换。
太好了,一切都准备好了。
请注意,建议定义转换时,一次只有一个转换是正确的,正如我们在示例中所做的那样。我们通过在“拒绝付款”和“进行付款”状态中添加一个条件来设置这一点,以便只有当我们有来自用户的有效输入时才触发转换。
但是,您应该知道,如果同时有更多的转换处于活动状态,那么将只执行定义的第一个转换。
⭐ Stop
因此,让我们回到我们的流程,现在我们只需要确保所有的过渡都已到位,用于“拒绝付款”和“进行付款”状态。有两种可能的转换。当提示继续时,用户可以回答“是”或“否”。让我们从用户不想继续并选择“否”的场景开始。
我们将从拒绝付款状态开始。在这种情况下,工作流将从拒绝付款状态转换为最终状态。
让我们创建转换,将其重命名为Stop并设置条件:ContinueAnswer.Equals No。
我们将重复“付款”状态的过程,提供相同的目的地、名称和条件。
现在,让我们讨论用户希望继续并选择Yes的场景。
我们将从拒绝付款开始。如果用户选择“是”,则将返回添加付款值。因此,在我们的工作流中,将触发从拒绝付款状态到获取付款值状态的转换。
⭐ Continue
让我们创建转换,将其重命名为Continue,并将条件设置为ContinueAnswer.Equals Yes。
我们将继续付款。如果用户选择“是”,同样的情况也会发生,他们将被发送回添加付款值,因此在我们的工作流中,将触发从“付款”状态到“获取付款值”状态的转换。
让我们创建转换,将其重命名为Continue,并设置与前面案例中相同的条件。
这样,我们所有的状态和转变都被定义了。我们最后一次检查是否涵盖了所有可能的情况。是的,一切似乎都很到位。
我们现在可以运行流程了!
如您所见,我们被提示添加当前余额。提供的输入有效。
我们怎么知道的?因为否则我们将无法增加付款的价值。
然后从原始余额中减去付款金额,并显示新的余额。
我们现在可以选择继续这一进程。
一旦我们选择“是”,我们将被要求进行新的付款。
我们添加新付款的值,然后再次显示新余额。
选择“否”后,消息框通知我们流程已完成,这是流程的最终状态。
我们的状态机演示到此结束。
关键要点
- 我们可以从Activities面板添加State Machine布局、States和Final States。
- State活动包含三个部分,Entry、Exit和Transitions,而Final State仅包含一个部分Entry。
- “进入”和“退出”部分使我们能够为所选状态添加进入和退出触发器,而“转换”部分显示链接到所选状态的所有转换。
- 我们可以通过连接设计器面板中的状态并为它们提供名称和条件来添加转换。
5️⃣ 参考资料
⭐写在结尾:
文章中出现的任何错误请大家批评指出,一定及时修改。
希望写在这里的小伙伴能给个三连支持!