- 入门指南
- 设置和配置
- 自动化项目
- 依赖项
- 工作流类型
- 控制流程
- 文件比较
- 自动化最佳实践
- 源代码控件集成
- 调试
- 日志记录
- 诊断工具
- 工作流分析器
- 变量
- 参数
- 导入的命名空间
- 编码自动化
- 简介
- 注册自定义服务
- “前”和“后”上下文
- 正在生成代码
- 根据手动测试用例生成编码测试用例
- 编写画布友好的编码工作流
- 故障排除
- 基于触发器的 Attended 自动化
- 对象存储库
- ScreenScrapeJavaSupport 工具
- 扩展程序
- Studio 测试
- 故障排除
构建编码工作流的建议,以便低代码查看器将其呈现为清晰、可读的低代码图表。
少量的结构有助于构建干净的画布。以下建议可帮助低代码查看器将编码工作流呈现为可读低代码块,而非不透明的代码块。变更按影响排序,从最重要的更改开始。
UiPath 服务而非手动代码
对项目服务的调用(system.AddQueueItem(...)、excel.ReadRange(...)、mail.SendSmtp(...)、uiAutomation.Click(...))呈现为丰富的活动卡:友好显示名称、服务图标、可编辑的属性和带类型的输出变量。
使用 HttpClient、System.IO 或 NuGet Excel 库从头实施的相同操作最多呈现为包含一个长表达式的赋值卡,最多呈现为代码块。首先找到活动包,仅在没有活动满足需求时才拖放到自定义 C#,这样可以使更多工作流可见。
// Renders as a "Write Range" activity card with editable properties:
excel.WriteRange("C:\\out.xlsx", "Sheet1", "A1", table);
// Renders as an opaque code block:
using var writer = new StreamWriter("C:\\out.csv");
// Renders as a "Write Range" activity card with editable properties:
excel.WriteRange("C:\\out.xlsx", "Sheet1", "A1", table);
// Renders as an opaque code block:
using var writer = new StreamWriter("C:\\out.csv");
作为编排层的入口方法
“图形”视图仅绘制进入方法(“[Workflow]”或“Execute”)。每次调用自己的方法都将成为一个带标签的块,选择该块可深入查看帮助程序。
将顶层分支、循环和错误处理保留在入口方法中,并将详细的步骤序列移至命名正确的私有方法中,可使图表读取为清晰的高级流 — ValidateInvoice → PostToQueue → NotifyFinance —,而不是一面低级别卡牌。每个帮助程序在“工作流”视图中都有专属版块,因此不会隐藏任何内容。在这里,意图揭示名称非常重要:方法名称是块标签。
将流程作为语句进行控制,而非表达式
画布只能绘制语句级别存在的分支和循环。表达式(Lambda、语言集成查询 (linq) 链、嵌套三元表达式或 switch 表达式)中包含的逻辑被压缩到单张卡片中,这违反了可视化工具的目的。
switch 的区别值得注意:switch 语句完全呈现为 Switch 容器,每个用例一个分支,而表达式表单 (var label = total switch { ... };) 则在单个赋值卡内保持压缩状态。当分支是读者应该看到的流程步骤时,语句形式是更好的选择。
// Invisible logic — one code block, the filtering and branching are not drawn:
invoices.Where(i => i.Amount > 1000).ToList().ForEach(i => Approve(i));
// Visible logic — a loop containing a decision containing an Invoke block:
foreach (var invoice in invoices)
{
if (invoice.Amount > 1000)
{
Approve(invoice);
}
}
// Invisible logic — one code block, the filtering and branching are not drawn:
invoices.Where(i => i.Amount > 1000).ToList().ForEach(i => Approve(i));
// Visible logic — a loop containing a decision containing an Invoke block:
foreach (var invoice in invoices)
{
if (invoice.Amount > 1000)
{
Approve(invoice);
}
}
当您乐意隐藏其详细信息的简单投影(var names = rows.Select(r => r.Name).ToList(); 呈现为一张“分配”卡)时,单引号(单引号)仍然可以使用。经验法则:如果图表的读者应看到分支,请将其写为 if、switch 或 foreach。
回退结构的可渲染等效项
几种常见的结构可以回退为代码块。每个元素都有可渲染的等效元素,可生成可见块。
| 代替 | 写入 | 原因 |
|---|---|---|
list.ForEach(x => ...) | foreach (var x in list) | 正文变为可见块 |
| 局部函数 | 私有方法 | 私有方法呈现为可导航的调用块 |
using var handle = excel.UseWorkbook(...); | using (var handle = excel.UseWorkbook(...)) { ... } | 块表单呈现为作用域框架,并可让对其内的 handle 调用解析为活动 |
int a = 1, b = 2; | 每行一个声明 | 每张卡都有自己的分配卡 |
string result; result = ...; 后... | 首次使用时带有初始值设定项的声明 | 裸声明回退为代码块 |
内联变量声明,每个语句一个
带有初始值设定项的声明呈现为“分配”卡(或活动卡的输出),并提供给每种方法的“变量”面板。裸声明呈现为代码块。在首先生成值的位置对每个变量进行声明,可使其值可见。
var asset = system.GetAsset("Config"); // activity card, output: asset
int retryCount = 0; // Assign card, typed
var asset = system.GetAsset("Config"); // activity card, output: asset
int retryCount = 0; // Assign card, typed
查看者无法推断的显式类型
画布会使用能找到的最佳类型来标记每个输出变量:
- 对于已识别的活动调用,类型将自动来自包元数据。
var asset = system.GetAsset(...)已显示实际返回类型,因此var不会产生任何成本。 - 对于其他所有内容(普通赋值、对您自己的方法的调用和计算表达式),
var按字面意思显示为var。显式类型会将真实类型放置在卡和“变量”面板中。
var totals = ComputeTotals(rows); // Variables panel shows: totals : var
DataTable totals = ComputeTotals(rows); // Variables panel shows: totals : DataTable
var totals = ComputeTotals(rows); // Variables panel shows: totals : var
DataTable totals = ComputeTotals(rows); // Variables panel shows: totals : DataTable
描述意图的注释
直接放置在活动、方法调用、if、foreach、for、switch、try、return 或 #region 上方的 // 注释会附加到该块。它将成为“图形”视图中的卡说明、“工作流”视图中的行工具提示以及“属性”面板中的“说明”字段。连续的注释行已合并。
// High-value invoices need manual approval before posting
system.AddQueueItem("InvoiceApproval", reference: invoice.Id);
// High-value invoices need manual approval before posting
system.AddQueueItem("InvoiceApproval", reference: invoice.Id);
不在此类语句上方的注释呈现为自己的小代码行,因此每个步骤只有一个有目的的注释,比零散的注释更易读。
按区域分组的流程阶段
#region Name ... #endregion 在两个视图中呈现为命名的可折叠组,并且区域可以嵌套。当区域按业务阶段命名时(Login、Process invoices、Reporting),折叠的图表读起来像流程摘要,展开区域会显示其步骤。
分组到一起的相关分配
两个或以上的连续分配可合并到一张“多重分配”卡中。在一次不间断运行中初始化相关值可将其保留在一张整洁的卡片中,而不是分散在整个流程中。相反,对于值得拥有自己的卡片的作业,应与其他作业区分开。
每个语句调用一次
当调用被链接 (row.GetValue("col").ToString().Trim()) 时,查看者只能将链显示为单个行,无法识别的接收器上的链将完全回退。将有意义的链拆分为多个具有命名中间变量的步骤,可使每个步骤拥有自己的块。对于句柄 API,例如 Excel 工作簿和邮件文件夹,它还让查看者跟踪句柄,以便后续调用呈现为正确的活动。
可识别的工作流调用
workflows.MyOtherWorkflow(arg1, arg2)呈现为专用的“调用工作流”卡,每个参数按方向(In、Out 或 InOut)标记,并导航到工作流文件。SharedHelpers.Method(...)调用项目的另一个.cs文件,该文件呈现为可导航的调用块。将这些活动保留为每个语句一次调用,而不是较长链的一部分,这就是它们可以进行“解析”的原因。
快速清单
- 步骤使用活动服务(
system.、excel.、mail.等),而非手动等效服务。 [Workflow]方法很短,可编排命名良好的私有方法。- 分支和循环是语句(
if、switch、foreach、for、while、try),没有隐藏在 Lambda 表达式或 Linux 管道中的逻辑。 - 变量是使用初始值设定项内联声明的,每个语句一个。
- 在查看者无法推断类型的情况下使用显式类型,例如辅助方法的结果和计算的值。
- 每个重要步骤上方都有一个单行
//注释。 - 流程的各个阶段包含在
#region中。 - 每个语句包含一个服务或帮助程序调用,没有长链。
- 其他工作流通过
workflows.X(...)调用。 - 画布上不留任何灰色代码块卡片,每个卡片都是可视化视图缺失的一个点。