简单记录
- DataTable相关
- 新建一个空的DataTable
- DataTable.Select()
- DataTable获取筛选后的某一字段
- DataTable.Compute()
- DataTable.AsEnumerable().Where
- DataTable.Clone()
- DataTable.Copy()
- 给 DataTable 添加列(指定位置)
- 给 DataTable 添加列(指定位置、默认值)
- DataTable 调整列的顺序
- DataTable 判断是否存在某列
- DataColumn转list
- DataTable 去重1
- DataTable 去重2
- DataTable 列名去掉空格
- DataTable 删除行1
- DataTable 删除行2
- DataColumn.Expression
- LINQ
- 数据类型
- 运算符
- String相关
- 字符串函数
- 输出”
- String 大写
- String 小写
- String 转 Double 型
- 转成两位精度小数
- 判断能不能转换为整数
- 转成百分比
- SecurePassword
- Password
- 字符串加双引号
- String.Format
- String.Format补全0
- String 去掉前面的0
- String 换行
- String 替换掉换行
- String 分割
- 获取特定字符串在某字符串出现的位置
- Substring 截取
- String 截取前四位
- String 截取后四位
- String 转 ASCII 码
- ASCII 码转 String
- 替换匹配
- 判断字符串是否为Null或者为空字符串
- 判断字符串是否为数字
- 选取器(Selectors)
- 数据操作
- 邮件相关
- 日期时间相关
- 文件/文件夹相关
- 环境相关
- Windows 系统相关
- Http请求
- 短信(验证码)相关
- Excel相关
- VBA相关
- SQL
- 正则
- SAP
- Bat脚本(cmd命令行)
- PowerShell
- 浏览器相关
- 奇奇怪怪的坑
- ctrl v 失效
- Selector 能找到元素,但是运行报错 time out
- 客户机的系统和服务器日期不为同一天
- 选择元素,F2倒计时结束后元素消失
- Cannot find the UI element corresponding to this selector
- Cannot communicate with the browser, please check the UiPath extension
- 你要允许来自未知发布者的此应用对你的设备进行更改吗?
- 以管理员身份运行Uipath应用程序
- Block User Input 锁不了鼠标键盘
- 批量插入数据(Insert DataTable)到数据库报错
- UiPath Data Scraping只能抓取网页表格的数据
- 报错:Scrape returned empty text
- 能运行的代码,突然有一天不能运行了1
- 能运行的代码,突然有一天不能运行了2
- IsNumeric() 报错
- Studio 运行流程报错 Unable to start execution
- UiPath 相关
- UiPath Studio
DataTable相关
新建一个空的DataTable
New System.Data.DataTable
DataTable.Select()
使用 sql 语法筛选数据
dt.Select("[semployerName] like '*[*]*' or [semployerName] like '*''*' ")
Datatable Filtered_Results = dt.Select("[Column1] = '"+param_1+"' AND [Column2] = '"+param_2+"'").CopyToDataTable()
https://www.cnblogs.com/TeresaMu/p/12058559.html
https://docs.microsoft.com/zh-cn/dotnet/api/system.data.datatable.select?view=net-5.0
DataTable获取筛选后的某一字段
dt.Select("是否新增= '是'").Select( Function(row) row.Item("名称").ToString ).ToList()
筛选出来的是一个列表,可以转换成文本。
Join( dt.Select("是否新增= '是'").Select( Function(row) row.Item("名称").ToString ).ToList().ToArray, "、")
DataTable.Compute()
Compute (string? expression, string? filter);
用来计算值。
https://learn.microsoft.com/zh-cn/dotnet/api/system.data.datatable.compute?view=net-7.0
expression | 解释 |
---|---|
count() | 求数量 |
sum(value) | 求和 |
avg(value) | 求平均 |
min(value) | 求最小 |
max(value) | 求最大 |
StDev(value) | 统计标准偏差 |
Var(value) | 统计方差 |
max(value)/sum(value) | 其他计算 |
例: 计算 DataTable 中,【级别】为信息的条数。
级别 | 机器人 |
---|---|
信息 | UR015 |
错误 | UR015 |
信息 | UR015 |
警告 | UR015 |
信息 | UR015 |
dt.Compute(" Count(级别) ", " 级别 = '信息' ")
例:计算 DataTable 中,【资金类型】为代理费的 应划付金额 的总计。
资金类型 | 应划付金额 |
---|---|
现金红利 | 517.97 |
代理费 | 13.71 |
交易净额 | 3,841.14 |
交易净额 | 2,300.00 |
dt.Compute(" Sum(应划付金额) ", " 资金类型 = '代理费' ")
【应划付金额】这一列不能为 String 型,String 型的会报错:Invalid usage of aggregate function Sum() and Type: Object.
把代码改成
dt.Compute(" Sum( Convert(应划付金额, 'System.Double' ) ) ", " 资金类型 = '代理费' ")
也不行,会报错:Syntax error in aggregate argument: Expecting a single column argument with possible ‘Child’ qualifier.如果真的要实现,只能换方式:
dt.AsEnumerable().Where(Function(row) row.Item("资金类型").ToString = "代理费").Sum(Function(row) Convert.ToDouble( row.Item("应划付金额") ) )
或者是用 dt.Clone() 克隆表结构到 dtCloned,dtCloned.Columns(“应划付金额”).DataType = GetType(System.Decimal),然后把 dt 每一行的数据插入到 dtCloned,最后是使用 dtCloned.Compute 进行计算。(思路是这样,但是觉得太麻烦了)
DataTable.AsEnumerable().Where
筛选数据
dt.AsEnumerable().Where(Function(y) y.Item("semployerName").ToString.Contains("'") or y.Item("semployerName").ToString.Contains("*")).ToList()
https://forum.uipath.com/t/checking-special-characters-in-column-values-in-data-table/14599/2
DataTable.Clone()
克隆可创建具有与原始 DataTable 相同的结构的新 DataTable,但不复制任何数据(新 DataTable 将不会包含任何 DataRows
)。
https://docs.microsoft.com/zh-cn/dotnet/api/system.data.datatable.clone?view=net-5.0
DataTable.Copy()
同时将结构和数据复制到新 DataTable 中,使用 Copy。
给 DataTable 添加列(指定位置)
SetOrdinal(0)里面的 0 就是想添加到的位置。
dt.Columns.Add("列名").SetOrdinal(0)
dt.Columns.Add("列名", typeof(String)).SetOrdinal(0)
给 DataTable 添加列(指定位置、默认值)
Dim column As DataColumn
column = New DataColumn("日期")
column.DefaultValue = strBalanceDate
dtBankDataTable.Columns.Add(column)
column.SetOrdinal(0)
DataTable 调整列的顺序
将顺序调到第4列,计数从0开始
dt.Columns("ColumnName").SetOrdinal(4)
使用 Invoke Method 或者 Invoke Code 都可以实现
DataTable 判断是否存在某列
dt.Columns.Contains("列名")
DataColumn转list
( From row In dt.AsEnumerable() Select Convert.Tostring(row("列名")) ).ToList()
DataTable 去重1
Remove Duplicate Rows
DataTable 去重2
NameList = (From name in dtAllDataTable.Columns.Cast(of DataColumn) select name.ColumnName).ToArray
dvDataView = dtAllDataTable.DefaultView
dtAllDataTable = dvDataView.ToTable(True, NameList)
DataTable 列名去掉空格
TypeArgument : System.Data.DataColumn
或者循环里面直接使用
item.ColumnName = item.ToString.Trim
DataTable 删除行1
使用 For Each ,
For Each row in dt.Select( "[文件名称] like '*' " )
dt.Select() 或者 dt.Rows 都可以。用 dt.Select() 主要是为了筛选数据,如果不需要的话,直接用 dt.Rows 即可。
TypeArgument 选择 System.Data.DataRow
Index 填写 intIndex
循环里面使用 Remove Data Row 。
增加行的逻辑类似,只不过是把 Remove Data Row 换成 Add Data Row。
DataTable 删除行2
建一个列表 lstRowIndex 来存储需要删除的行数,New List(of integer),变量类型:System.Collections.Generic.List
使用 For Each Row in dt
Index 填写 intIndex
使用控件 Add To Collection,把需要删除的行加到 lstRowIndex。
遍历完成之后,使用 For Each item in lstRowIndex.ToArray.Reverse()
,进行倒序删除。
DataColumn.Expression
https://learn.microsoft.com/zh-cn/dotnet/api/system.data.datacolumn.expression?view=net-6.0
LINQ
https://learn.microsoft.com/zh-cn/dotnet/visual-basic/programming-guide/concepts/linq/
https://docs.microsoft.com/zh-cn/dotnet/csharp/linq/
https://learn.microsoft.com/zh-cn/dotnet/api/system.linq?view=net-6.0
https://forum.uipath.com/t/how-to-use-arithmetic-operator-using-linq/471768
LINQ 查询操作由以下三个操作组成:
- 获取数据源。
- 创建查询。
- 执行查询。
From num In numbers
Where num Mod 2 = 0
Select num
Lambda 表达式
Lambda 表达式是没有名称的函数,用于计算并返回单个值。 与命名函数不同,Lambda 表达式可以同时定义和执行。
在 LINQ 中,Lambda 表达式是许多标准查询运算符的基础。 编译器创建 Lambda 表达式来捕获基本查询方法(如 Where
、Select
、Order By
、Take While
等)中定义的计算。
(Function(num As Integer) num + 1)(6)
结果是:7
Dim add1 = Function(num As Integer) num + 1
Console.WriteLine(add1(3))
From stdnt In students
Where stdnt.Year = "Senior"
Select stdnt
students
.Where(Function(st) st.Year = "Senior")
.Select(Function(s) s)
获取压缩包
(From n In Directory.GetFiles(strFolderPath)
Where n.ToLower.EndsWith(".zip") Or n.ToLower.EndsWith(".7z")
Select n).ToArray
去掉数组里面空的元素
myArray = myArray.Where(Function(s) Not String.IsNullOrEmpty(s)).ToArray()
数据类型
Visual Basic 类型 | 公共语言运行时类型结构 | 名义存储分配 | 取值范围 |
---|---|---|---|
布尔值 | Boolean | 取决于实现平台 | True 或 False |
Byte | Byte | 1 个字节 | 0 到 255(未签名) |
Char(单个字符) | Char | 2 个字节 | 0 到 65535(未签名) |
日期 | DateTime | 8 个字节 | 0001 年 1 月 1 日 0:00:00(午夜)至 9999 年 12 月 31 日晚上 11:59:59 |
十进制 | Decimal | 16 个字节 | 0 至 +/-79,228,162,514,264,337,593,543,950,335 (+/-7.9…E+28) †,不带小数点;0 至 +/-7.9228162514264337593543950335,小数点右侧 28 位小数; 最小的非零数字为 +/-0.0000000000000000000000000001 (+/-1E-28) † |
Double(双精度浮点数) | Double | 8 个字节 | 对于负值,-1.79769313486231570E+308 至 -4.94065645841246544E-324 †; 对于正值,4.94065645841246544E-324 至 1.79769313486231570E+308 † |
整数 | Int32 | 4 个字节 | -2,147,483,648 至 2,147,483,647(已签名) |
Long(长整型) | Int64 | 8 个字节 | -9,223,372,036,854,775,808 至 9,223,372,036,854,775,807 (9.2…E+18 †)(已签名) |
Object | Object(类) | 32 位平台上的 4 个字节 64 位平台上的 8 个字节 | 在 Object 类型的变量中可存储任何类型 |
SByte | SByte | 1 个字节 | -128 至 127(已签名) |
Short(短整型) | Int16 | 2 个字节 | -32,768 至 32,767(已签名) |
Single(单精度浮点) | Single | 4 个字节 | 对于负值,-3.4028235E+38 至 -1.401298E-45 †; 对于正值,1.401298E-45 至 3.4028235E+38 † |
String(可变长度) | String(类) | 取决于实现平台 | 0 到大约 20 亿个 Unicode 字符 |
UInteger | UInt32 | 4 个字节 | 0 到 4,294,967,295(未签名) |
ULong | UInt64 | 8 个字节 | 0 到 18,446,744,073,709,551,615 (1.8…E+19 †)(未签名) |
User-Defined(结构) | (继承自 ValueType) | 取决于实现平台 | 结构中的每个成员都有一个由其数据类型确定的范围,且该范围不依赖其他成员的范围 |
UShort | UInt16 | 2 个字节 | 0 到 65,535(未签名) |
Decimal 与 Double 的不同
一句话总结:Single 和 Double 只能用来做科学计算或者是工程计算,在商业计算中用 Decimal。
商业计算中,建议使用 Decimal,而不是使用 Double。Decimal
数据类型为数字提供的有效位数最多。 它最多支持 29 个有效位数,并可表示超过 7.9228 x 10 ^ 28 的值。 它特别适用于需要大量数字但不允许舍入误差的计算(例如财务)。
Decimal
不是浮点数据类型。 Decimal
结构包含一个二进制整数值以及一个符号位和一个整数比例因子,该比例因子用于指定该值的小数部分。 因此,在内存中,Decimal
数字的表示形式比浮点类型(Single
和 Double
)更精确。
Convert.ToDouble( "66.144421" )
Double.Parse("17.89")
Convert.ToDecimal( 66.144421 )
Decimal.Parse("17.89")
浮点表达式不比较为等于
使用浮点数(单数据类型和双数据类型)时,请记住,它们存储为二进制分数。 这意味着对于任何不是二进制分数的数量,它们无法提供准确的表示形式(采用 k / (2 ^ n) 的形式,其中 k 和 n 是整数)。 例如,0.5 (= 1/2) 和 0.3125 (= 5/16) 可以作为精确的值,而 0.2 (= 1/5) 和 0.3 (= 3/10) 只能是近似值。
由于这种不精确性,在使用浮点值时,不要指望获得准确的结果。 具体而言,理论上相等的两个值的表示形式可能略有不同。
比较浮点数量 1. 使用 System 命名空间中 Math 类的 Abs 方法计算其差值的绝对值。 2. 确定可接受的最大差值,这样,如果两个数量的差值不大于该值,则出于实用目的,你可以认为这两个数量相等。 3. 将差值的绝对值与可接受的差值进行比较。 Mod 运算符不返回准确的结果
由于浮点存储的不精确性,当至少有一个操作数为浮点时,Mod 运算符可能会返回意外的结果。
十进制数据类型不使用浮点表示形式。 在
Single
和Double
中不准确的许多数字在Decimal
中是准确的(例如 0.2 和 0.3)。 尽管算术在Decimal
中比在浮点中慢,但为了实现更好的精度,性能降低是值得的。
查找浮点数量的整数余数 1. 将变量声明为 Decimal
。 2. 使用文本类型字符D
将文本强制为Decimal
,以免其值对于Long
数据类型来说太大。
举例:
dblVariable1 = Double.Parse("4.17")
dblVariable2 = Double.Parse("17.89")
dblVariable3 = dblVariable1 + dblVariable2
dblVariable4 = Double.Parse("22.06")
输出 dblVariable3 = dblVariable4
的结果为 False。
或者直接输出 Double.Parse("4.17") +Double.Parse("17.89") = Double.Parse("22.06")
,结果也是 False。
把相关变量换成 Decimal 型
decVariable1 = Decimal.Parse("4.17")
decVariable2 = Decimal.Parse("17.89")
decVariable3 = decVariable1 + decVariable2
decVariable4 = Decimal.Parse("22.06")
输出 decVariable3 = decVariable4
的结果为 True。
或者直接输出 Decimal.Parse("4.17") +Decimal.Parse("17.89") = Decimal.Parse("22.06")
,结果也是 True。
在 19.10.4 版本的 Studio 上,输出 Double.Parse("4.17") +Double.Parse("17.89")
,虽然日志里面是 22.06,但是直接 Debug 看 Message 的 in,其实是 22.060000000000002。但在 22.12.0 版本的 Studio 上,却是输出 22.060000000000002。
直接导致了我接手的一个流程,报错时,抛出的异常信息是:代理佣金管理界面表格中【发生额】合计:22.06,与【应划付金额】总计:22.06 不一致。都不好和业务老师解释,只能怪自己接手代码的时候没有注意到这里选用的数据类型。
运算符
And 运算符
逻辑与,两个都为真才为真。
AndAlso 运算符
如果编译的代码可以根据一个表达式的结果绕过另一个表达式的计算,则称逻辑运算为短路。
如果第一个表达式的计算结果决定运算的最终结果,则无需计算第二个表达式,因为这无法改变最终结果。 如果绕过的表达式很复杂,或者涉及过程调用,短路可以提高性能。
逻辑与运算的话,两个表达式为真才为真,有一个不为真,则为假。
用 And,哪怕第一个表达式是假,也会去计算第二个表达式;
用 AndAlso,只要第一个表达式是假,就会直接返回假,不计算第二个表达式,如下表所示。
如果 表达式1 为 |
且 表达式2 为 |
结果 的值为 |
---|---|---|
True |
True |
True |
True |
False |
False |
False |
(不计算) | False |
举个例子,假如在一个判断里面,我需要判断文件路径是否在某个字典里面,且还需要判断该路径是否在电脑本地存在。
dic.Keys.Contains("文件路径") AndAlso File.Exists( dic("文件路径").ToString )
这里用 AndAlso 就没问题,用 And 的话,在文件路径没有添加到字典的时候,File.Exists( dic("文件路径").ToString )
就会报错,说这个key 不在字典里面。
所以,从方便、提高效率、避免错误的角度来说,用 AndAlso 会更好一些。
愿我不会再接手别人的代码。
Or 运算符
逻辑或,有一个为真则为真。
OrElse 运算符
用 Or,哪怕第一个表达式是真,也会去计算第二个表达式;
用 OrElse,只要第一个表达式是真,就会直接返回真,不计算第二个表达式,如下表所示。
如果 表达式1 为 |
且 表达式2 为 |
结果 的值为 |
---|---|---|
True |
(不计算) | True |
False |
True |
True |
False |
False |
False |
Xor 运算符
逻辑异,不短路的。
两个表达式之一的计算结果为 真
时,结果
才是 真
。
两个表达式同真同假,结果
皆为 假
。
如果 表达式1 为 |
且 表达式2 为 |
结果 的值为 |
---|---|---|
True |
True |
False |
True |
False |
True |
False |
True |
True |
False |
False |
False |
IF
IIf(expr, truepart, falsepart)
参数描述 : expr 必要参数。用来判断真伪的表达式。 truepart 必要参数,只能为文本。如果 expr 为 True,则返回这部分的文本。 falsepart 必要参数,只能为文本。如果 expr 为 False,则返回这部分的文本。
If( out_blIsCheckSuccess, "校验成功", "校验失败" )
IIF
IIf(expr, truepart, falsepart) 参数描述 : expr 必要参数。用来判断真伪的表达式。 truepart 必要参数。如果 expr 为 True,则返回这部分的值或表达式。 falsepart 必要参数。如果 expr 为 False,则返回这部分的值或表达式。
IIf( out_blIsCheckSuccess, "校验成功", "校验失败" )
Note:使用 IIF 时,不管 expr 是真还是假,后面的 truePart 和 falsepart都会进行计算,虽然它只返回其中的一个。也就是 IIF 函数是不短路的。
例如,如果 falsepart 产生一个被零除错误,那么程序就会发生错误,即使 expr 为 True。
它对每个表达式都会进行计算,如果某一项为 DBnull 则就会抛出异常,所以在进行非空判断时应该用 IF 的形式,而不应该用 IIF。
下面这个例子就会引发被零除错误。
intIndex = 100
IIf( out_blIsCheckSuccess, "校验成功", intIndex \ 0 )
https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.visualbasic.interaction.iif?view=net-7.0
String相关
字符串函数
https://learn.microsoft.com/zh-cn/dotnet/visual-basic/language-reference/functions/string-functions
https://learn.microsoft.com/zh-cn/dotnet/api/system.string?view=netframework-4.8#methods
输出”
""""
String 大写
str.ToUpper
String 小写
str.ToLower
String 转 Double 型
Convert.ToDouble("1.2")
转成两位精度小数
用 0 占位
Double.Parse("1.2").ToString("0.00")
Double.Parse("1").ToString("f")
去掉数字 0
Decimal.Parse("1.20").ToString("0.0#")
判断能不能转换为整数
Integer.TryParse("asd",0)
输出为:False
Integer.TryParse("123",0)
输出为:True
https://learn.microsoft.com/zh-cn/dotnet/api/system.int32.tryparse?view=net-6.0
转成百分比
Double.Parse("0.5").ToString("p")
https://docs.microsoft.com/zh-cn/dotnet/api/system.double.tostring?view=net-5.0
SecurePassword
获取或设置 SecureString 实例形式的密码。
secStrPassWord = New System.Net.NetworkCredential("","123456").SecurePassword
https://docs.microsoft.com/zh-cn/dotnet/api/system.net.networkcredential
Password
获取或设置与凭据关联的用户名的密码。
New System.Net.NetworkCredential("",pwd).Password
字符串加双引号
"test""Test" + """"
输出:test”Test”
String.Format
String.Format("银行名称:{0},账户类型:{1},文件名称:{2}", strBankName, strAccountType, strFileName)
https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.visualbasic.strings.format?view=net-6.0
将对象的值转换为字符串
String.Format补全0
Strings.Format(7, "000")
输出:007
也可以:https://docs.microsoft.com/zh-cn/dotnet/api/system.string.padleft?view=net-6.0
String 去掉前面的0
"0000abc".TrimStart("0".ToCharArray)
输出:abc
https://docs.microsoft.com/zh-cn/dotnet/api/system.string.trimstart?view=net-6.0
String 换行
"asdf"+ _
"dssffg"
输出:asdfdssffg
String 替换掉换行
str.Trim.Replace( Chr(10) , "").Replace( Chr(13) , "")
str.Trim.Replace( vbcrlf , "")
String 分割
Split(str, ",")
str.Split(","c)
str.Split({","})
str.split(CChar(","))
str.Split(Char.Parse(","))
str.Split(convert.ToChar(","))
https://learn.microsoft.com/zh-cn/office/vba/language/reference/user-interface-help/split-function
https://learn.microsoft.com/zh-cn/dotnet/api/system.string.split?view=net-7.0
用两个分隔符来分割
str.Split(","c, " "c)
去掉结果中包含空字符串的数组元素
str.Split( (",").ToArray, StringSplitOptions.RemoveEmptyEntries)
str.Split( (" "+",").ToArray, StringSplitOptions.RemoveEmptyEntries)
str.Split( {",", " "}, StringSplitOptions.RemoveEmptyEntries)
https://learn.microsoft.com/zh-cn/dotnet/api/system.stringsplitoptions?view=net-7.0
获取特定字符串在某字符串出现的位置
Instr( str, "特定字符串")
https://learn.microsoft.com/zh-cn/office/vba/language/reference/user-interface-help/instr-function
Substring 截取
从第六个字符开始,截取两个字符
str.Substring(6,2)
截第六个字符后的所有字符
str.Substring(6)
https://docs.microsoft.com/zh-cn/dotnet/api/system.string.substring?view=net-6.0
String 截取前四位
注意:不足 4 位也不会出错
Left(str, 4)
Strings.Left(str, 4)
String 截取后四位
注意:不足 4 位也不会出错
Right(str , 4)
Strings.Right(str , 4)
String 转 ASCII 码
每个字符串中的第一个字母的字符代码
Asc("A")
https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.visualbasic.strings.asc?view=net-6.0
ASCII 码转 String
Chr(65)
https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.visualbasic.strings.chr?view=net-6.0
替换匹配
System.Text.RegularExpressions.Regex.Replace(text, "\W","")
判断字符串是否为Null或者为空字符串
String.IsNullOrEmpty(str)
https://docs.microsoft.com/zh-cn/dotnet/api/system.string.isnullorempty?view=net-6.0
判断字符串是否为数字
.IsNumeric
"7".IsNumeric
IsNumeric( "7" )
选取器(Selectors)
<html omit:title='*新意*' />
带有通配符的选取器
<wnd app='notepad.exe' cls='Notepad' title='Untitled - Notepad' />
<wnd app='notepad.exe' cls='Notepad' title='*- Notepad' />
<wnd app='notepad.exe' cls='Notepad' title='Untitled?- Notepad' />
- 星号 (*) – 替换零个或更多个字符
- 问号 (?) – 替换单个字符
https://docs.uipath.com/studio/lang-zh_CN/docs/selectors-with-wildcards
动态选取器
MenuOption 为变量
<wnd app='notepad.exe' cls='Notepad' title='Untitled - Notepad' />
<ctrl automationid='MenuBar' idx='1' name='Application' role='menu bar' />
<ctrl name='' role='menu item' />
https://docs.uipath.com/studio/lang-zh_CN/docs/dynamic-selectors
正则表达式搜索
<wnd app='applicationframehost.exe' title='Calculator' />
<uia cls='LandmarkTarget' />
<uia automationid='CalculatorResults' name='Display is \d' role='text' matching:name='regex' />
https://docs.uipath.com/studio/lang-zh_CN/docs/regex-search
模糊搜索
<html title='*新意*' />
<webctrl id='depName' tag='SPAN' aaname='总部清算中心' matching:aaname='fuzzy' fuzzylevel:aaname='0.8' />
matching:<tag_name>=fuzzy |
用于指定目标搜索标签,具体取决于 <tag_name> 值。 |
---|---|
fuzzyLevel:<tag_name>=<numerical_value> |
确定目标 <tag_name> 的匹配阈值。此选项支持 0 到 1 之间的数值,如下所示: 更趋近 0 - 返回的结果与 <tag_name> 的相似度较低 更趋近 1 - 返回的结果与 <tag_name> 的相似度较高 |
区分大小写的选取器
UiPath Selector 里面,属性默认是大小写敏感的,但是可以使用 casesensitive:<attribute-name>='false'
进行更改。
例:
<html app='chrome.exe' title='区分大小写的选取器' />
<webctrl parentid='content-container' tag='STRONG' aaname='RegEx' />
如果 RegEx 变成了 regex,那么上面的 Selector 就会报错,但是修改为下面这样,大小写不敏感,就不会报错了。
<html app='chrome.exe' title='区分大小写的选取器' />
<webctrl parentid='content-container' tag='STRONG' aaname='RegEx' casesensitive:aaname='false' />
https://docs.uipath.com/studio/lang-zh_CN/docs/case-sensitive-selectors
数据操作
新建数组
{"1", "2", "3"}
New String() {"1", "2", "3"}
新建一个List
New List(Of String)
实例化一个List
New List(Of String) From {"1", "2", "3"}
快速输出 list
先转为Array,然后再处理
Join( list.ToArray, "、" )
String.Join( ",", list)
https://learn.microsoft.com/zh-cn/dotnet/api/system.string.join?view=net-8.0
List 去重
list.Distinct().ToList
List 筛选
list1.Where( Function(y) y.Contains("2") ).ToList
遍历 List 的时候删除 List 元素
正常的 for each in list,删除完 List 元素之后肯定会出错,对 list 再 ToList 一下就可以了。
list.ToList
或者 list 再 ToArray 一下
list.ToArray
甚至可以 ToArray 之后再翻转一下
list.ToArray.Reverse()
甚至还可以 ToArray 之后再翻转两次,再 ToList 一下
list.ToArray.Reverse().Reverse().ToList
判断 List 里面是否包含某字符
list.Contains(str)
https://learn.microsoft.com/zh-cn/dotnet/api/system.collections.generic.list-1.contains?view=net-6.0
判断 List 是否包含符合特定条件的数据
list1.Exists( Function(y) y.Contains("2") )
两个 List 操作
list1 = New List(Of String) From {"1", "2", "3"}
list2 = New List(Of String) From {"1", "3","5","7"}
两个 List 取交集
FinalList = list1.Intersect(list2).ToList
FinalList 的值为 1、3
两个 List 取差集
FinalList = list1.Except(list2).ToList
FinalList 的值为 2
FinalList = list2.Except(list1).ToList
FinalList 的值为 5、7
两个 List 取并集
取并集是去重的
FinalList = list1.Union(list2).ToList
FinalList 的值为 1、2、3、5、7
两个 List 相加
Concat 是不去重的
FinalList = list1.Concat(list2).ToList
FinalList 的值为 1、2、3、1、3、5、7
新建字典
New Dictionary(Of String,Object) From{ {"异常结果收件邮箱",""}, {"发件邮箱账号密码凭据","发件邮箱账号密码"}, {"RobotWorkFolder","C:\Robots\asdf"} }
判断字典里面是否包含某个key
dic.ContainsKey("异常结果收件邮箱")
判断字典里面是否包含某个Value
Config.ContainsValue("发件邮箱账号密码")
遍历字典的键
for key in dic.Keys
遍历字典的值
for value in dic.Values
遍历字典
For Each 的 TypeArgument 选择 KeyValuePair
键:item.Key
值:item.Value
String 转 list
, 为分隔符,先按照分割符转为数组,再转为 list
str.Split( CChar(",") ).ToList
获取文本中的最后 15 行
用 chr(10) ,也就是换行来分割获取到的日志,然后获取最后的15条日志。
Split( strlogText, chr(10) ).TakeLast(15).ToList
把 strlogText 分割成之后数组,取前 15 条,再反转回去,接着转成 list
Split( strlogText, chr(10) ).Reverse().Take(15).Reverse().ToList
chr(13)是回车,把获取好的内容用回车拼接成文本
Join( Split( strlogText, chr(10) ).Reverse().Take(15).Reverse().ToArray, chr(13))
Skip 是跳过,把倒数 15 行前面的内容跳过
Split( strlogText, vbCrLf ).Skip( Split( strlogText, vbCrLf ).Count - 15 )
Math.Max 是返回两个值中的最大值
Split( strlogText, vbCrLf ).Skip( Math.Max(0, Split( strlogText, vbCrLf ).Count - 15) )
文本分割成数组
将字符串 strText
按照换行符进行分割,并返回一个包含分割后所有子字符串的数组,然后对于数组中的每个元素,都选取它本身作为结果。
From r In Split( strlogText,chr(10))
Select r
文本分割,获取符合指定条件的字符串数组
将字符串strErrorMsg
按照换行符进行分割,并返回一个包含分割后所有子字符串的数组,然后选取其中所有包含字符串”新增代码”的子字符串,并返回一个新的数组,其中只包含符合条件的子字符串。
From r In Split( strErrorMsg,chr(10))
Where r.Contains("新增代码")
Select r
Base64 转 Byte Array
Convert.FromBase64String( strImageBase64 )
Byte Array 保存为图片
File.WriteAllBytes( strImgPath, arrByteArray )
生成一个随机数
范围是 0 到 9
Cint( Rnd()*9 )
范围是 10 到 100
New Random().Next(10, 100)
范围是1到15
New Random(DateTime.Now.Millisecond).Next(1, 15)
邮件相关
内容 | 代码 |
---|---|
发件时间 | mail.Headers(“Date”) |
邮件时间 | mail.DateAsDateTime |
收件时间 | mail.Headers(“Recieved”) |
发件地址 | mail.From.Address |
邮件标题 | mail.Subject.ToString |
附件数量 | mail.Attachments.Count |
邮件正文 | mail.Body |
邮件正文里面带图片
strMailBody = "邮件里面的文字信息"
byteArray = File.ReadAllBytes(strScreenshotPath)
strPicBase64 = Convert.ToBase64String(byteArray)
strPicHtml = "<img src=data:image/jpeg;base64," + strPicBase64 + ">"
"<html><body>"+ strMailBody + strPicHtml +"</body></html>"
调整邮件正文内容的 css
需要勾选 IsBodyHtml ,或 IsBodyHtml 为 True
"<STYLE type=text/css>
font {
font-size: 22px !important;
}
</STYLE><font>邮件正文内容</font>"
邮件里面带上表格
需要勾选 IsBodyHtml ,或 IsBodyHtml 为 True
如果是有 Create HTML Content 这个控件,则可以使用这个控件。
若是没有,则使用遍历表头+表的内容组合出 DataTable 的 Html
163 邮箱配置
关闭SSL验证
System.Net.ServicePointManager.ServerCertificateValidationCallback =
Function(se As Object,
cert As System.Security.Cryptography.X509Certificates.X509Certificate,
chain As System.Security.Cryptography.X509Certificates.X509Chain,
sslerror As System.Net.Security.SslPolicyErrors) True
日期时间相关
https://learn.microsoft.com/zh-cn/dotnet/api/system.datetime
输出当前时间
yyyy:年; MM:月; dd:日;
hh:小时,12 小时制。如果是下午三点,会输出 03; HH:小时,24 小时制。如果是下午三点,会输出 15; mm:分 ss:秒
Now.ToString("yyyyMMdd hh:mm:ss")
输出:20221216 10:06:58
其实 Now 就是 DateTime.Now,为了方便,省略了。
DateTime.Now.ToString("yyyyMMdd hh:mm:ss")
输出:20221216 10:06:58
输出结果是一样的。
时间转为当地时间
DateTime.UtcNow.ToLocalTime()
https://learn.microsoft.com/zh-cn/dotnet/api/system.datetime.tolocaltime?view=net-7.0
获取日期的星期
Now.DayOfWeek
输出:Sunday
https://learn.microsoft.com/zh-cn/dotnet/api/system.datetime.dayofweek?view=net-6.0
Now.ToString("dddd")
输出:Sunday
Now.ToString("ddd")
输出:Sun
Now.ToString("dddd",New Globalization.CultureInfo("zh-cn"))
输出:星期日
Now.ToString("ddd",New Globalization.CultureInfo("zh-cn"))
输出:周日
Weekday(Now,vbSunday)
Weekday(date, [firstdayofweek])
Part | 说明 |
---|---|
date | 必需。 可以表示日期的 Variant、数值表达式、字符串表达式或任意组合。 如果 date 包含 Null,则返回 Null。 |
firstdayofweek | 可选。 指定一周的第一天的常量。 如果不指定,则假定为 vbSunday。 |
设置
firstdayofweek 参数具有以下设置:
常量 | 值 | 说明 |
---|---|---|
vbUseSystem | 0 | 使用 NLS API 设置。 |
vbSunday | 1 | 周日(默认) |
vbMonday | 2 | 星期一 |
vbTuesday | 3 | 星期二 |
vbWednesday | 4 | 星期三 |
vbThursday | 5 | 星期四 |
vbFriday | 6 | 星期五 |
vbSaturday | 7 | 星期六 |
返回值
Weekday 函数可以返回以下任一值:
常量 | 值 | Description |
---|---|---|
vbSunday | 1 | 星期日 |
vbMonday | 2 | 星期一 |
vbTuesday | 3 | 星期二 |
vbWednesday | 4 | 星期三 |
vbThursday | 5 | 星期四 |
vbFriday | 6 | 星期五 |
vbSaturday | 7 | 星期六 |
https://learn.microsoft.com/zh-cn/office/vba/language/reference/user-interface-help/weekday-function
获取这周几的日期
获取周一的日期
Now.AddDays(1 - Weekday(Now,vbMonday) ).ToString("yyyyMMdd")
周日的话,把 vbMonday 改成 vbSunday
Now.AddDays(1 - weekday(now,vbSunday)).ToString("yyyyMMdd")
获取某年某月的天数
DateTime.DaysInMonth(2023, 2)
输出:28
https://learn.microsoft.com/zh-cn/dotnet/api/system.datetime.daysinmonth?view=net-6.0
对日期进行加减年月日
加一年:.AddYears(-1) 加一月:.AddMonths(-1) 加一天:.AddDays(-1)
减一年:.AddYears(+1) 减一月:.AddMonths(+1) 减一天:.AddDays(+1)
Now.AddMonths(+1).ToString("yyyyMMdd")
输出:20230116
字符串转为DateTime
转换为 DateTime 变量,一般是够用的
Convert.ToDateTime("2022/05/25")
DateTime.Parse("2022/05/25")
如果格式特别奇怪的话,可以使用 DateTime.ParseExact:
DateTime.ParseExact( "Tue May 25 18:11:19 CST 2022", "ddd MMM dd HH:mm:ss CST yyyy", Nothing)
DateTime.ParseExact( "Tue May 25 18:11:19 CST 2022", "ddd MMM dd HH:mm:ss CST yyyy", New System.Globalization.CultureInfo("en-US") )
将日期时间的字符串转换为 DateTime
strReceiptime = "Wed, 15 Dec 2021 15:00:04 +0800"
format = "ddd, dd MMM yyyy HH:mm:ss zzz (CST)"
strReceiptime = "Wed, 15 Dec 2021 15:00:04 +0800 (CST)"
format = "ddd, dd MMM yyyy HH:mm:ss zzz (CST)"
DateTime.ParseExact(strReceiptime, format, System.Globalization.CultureInfo.InvariantCulture)
https://docs.microsoft.com/zh-cn/dotnet/api/system.datetime.parseexact
https://blog.csdn.net/bigheadsheep/article/details/12013267
判断能否把字符串转化为DateTime
直接进行转化的判断
DateTime.TryParse("2022/08/05", dtmdateValue)
提供日期格式的转化判断
DateTime.TryParseExact("20220805", "yyyyMMdd", Nothing, System.Globalization.DateTimeStyles.None, dtmdateValue)
Subtract
输出时间差
Time1 = DateTime.now()
Time2 = DateTime.now()
System.TimeSpan diff1 =Time1.Subtract(Time2)
System.TimeSpan diff2 =Time2-Time1
https://docs.microsoft.com/zh-cn/dotnet/api/system.datetime.subtract?view=net-6.0
Subtract(DateTime) | 返回一个新的 TimeSpan,从此实例的值中减去指定的日期和时间。 |
---|---|
Subtract(TimeSpan) | 返回一个新的 DateTime,从此实例的值中减去指定持续时间。 |
DateDiff
输出时间差,DateInterval.Second是秒数,DateInterval.Minute 是分钟数,DateInterval.Day 是日期数
DateDiff(DateInterval.Minute, Time1,Time2)
https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.dateandtime.datediff?view=net-6.0
https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.dateinterval?view=net-6.0
TimeSpan 结构
https://docs.microsoft.com/zh-cn/dotnet/api/system.timespan?view=net-6.0
TimeSpan(Int32, Int32, Int32) | 将 TimeSpan 结构的新实例初始化为指定的小时数、分钟数和秒数。 |
---|---|
TimeSpan(Int32, Int32, Int32, Int32) | 将 TimeSpan 结构的新实例初始化为指定的天数、小时数、分钟数和秒数。 |
TimeSpan(Int32, Int32, Int32, Int32, Int32) | 将 TimeSpan 结构的新实例初始化为指定的天数、小时数、分钟数、秒数和毫秒数。 |
TimeSpan(Int64) | 将 TimeSpan 结构的新实例初始化为指定的刻度数。 |
Delay 500 毫秒
00:00:00.500
New TimeSpan(0, 0, 0, 0,500)
TimeSpan.FromSeconds( 0.500 )
Delay 5 秒
00:00:05
New TimeSpan(0, 0, 5)
New TimeSpan(0, 0, 0, 5)
TimeSpan.FromSeconds( 5 )
https://learn.microsoft.com/zh-cn/dotnet/api/system.timespan.fromseconds?view=net-7.0
Delay 1 分钟
00:01:00
New TimeSpan(0, 1, 0)
TimeSpan.FromMinutes( 1 )
https://learn.microsoft.com/zh-cn/dotnet/api/system.timespan.fromminutes?view=net-7.0
获取当前是第几季度
DatePart( "q", Now() )
文件/文件夹相关
获取某个文件夹下的所有文件夹
Directory.GetDirectories("C:\Robots\asdf")
获取某文件夹下的所有 .csv 文件
Directory.GetFiles("C:\Robots\asdf", "*.csv")
https://docs.microsoft.com/zh-cn/dotnet/api/system.io.directory.getfiles?view=net-6.0
获取某文件夹下的所有 .xls 文件的数量
Directory.GetFiles("C:\Robots\asdf","*.xls").Count
获取某文件夹下,包含子文件夹的所有文件
Directory.GetFiles( in_strInputPath, "*" , SearchOption.AllDirectories )
AllDirectories | 1 | 在搜索操作中包括当前目录和所有它的子目录。 此选项在搜索中包括重解析点,比如安装的驱动器和符号链接。 |
---|---|---|
TopDirectoryOnly | 0 | 仅在搜索操作中包括当前目录。 |
获取某文件夹下,包含子文件夹的文件数量
Directory.GetFiles( in_strInputPath,"*", searchOption.AllDirectories).Count
获取某文件夹下,所有 .dat 或 .gz 文件
Directory.GetFiles(in_strInputPath, "*" ).Where(Function(s) s.EndsWith(".dat") or s.EndsWith(".gz") )
获取某文件夹下,包含子文件夹的所有的文件夹
Directory.GetDirectories(in_strInputPath,"*", searchOption.AllDirectories)
删除某文件夹下,所有空文件夹
- 先
Directory.GetDirectories(in_strInputPath,"*", searchOption.AllDirectories)
,遍历所有文件夹; - 然后
Directory.GetFiles( item,"*", searchOption.AllDirectories).Count = 0
, 判断文件夹是否为空,如果文件数量为 0,则把文件夹路径添加到待删除文件列表; - 最后待删除文件列表去重,遍历列表,删除文件夹。
选择文件(SelectFile)
如果是需要自定义文件的筛选 ,比如说要筛选出 .nupkg 的文件,Filter 就填写
nupkg包 (*.nupkg)|*.nupkg
例如,如果只想选择 PDF 文件,则筛选器应类似于 PDF files (*.pdf)|*.pdf
;
如果需要多种图像文件类型以及所有文件,则筛选器应类似于 Image files (*.bmp, *.jpg)|*.bmp;*.jpg|All files (*.*)|*.*
;
https://docs.uipath.com/activities/lang-zh_CN/docs/select-file
获取文件大小(字节数)
code
fileSize = FileLen(filePath).ToString
文件重命名
code
FileSystem.Rename(oldPathName,newPathName)
文件压缩
strSourcePath, 压缩的目录路径;strZipFilePath, 要生成压缩包的所在路径。strZipFilePath 貌似不能在 strSourcePath 里面。
code
System.IO.Compression.ZipFile.CreateFromDirectory(strSourcePath, strZipFilePath)
设置压级别、压缩包不包含基目录
System.IO.Compression.ZipFile.CreateFromDirectory(System.IO.Compression.CompressionLevel.Fastest, False)
文件解压
将指定 zip 压缩包中的所有文件都解压缩到文件系统的一个目录下。
System.IO.Compression.ZipFile.ExtractToDirectory(strZipFilePath,strUnzipFilePath,System.Text.Encoding.Default)
获取文件路径
Path.GetDirectoryName("C:\Robots\港股通权限补报送\港股通权限补报送_日志表.xlsx")
运行结果:C:\Robots\港股通权限补报送
获取文件扩展名
Path.GetExtension("C:\Robots\港股通权限补报送\港股通权限补报送_日志表.xlsx")
运行结果:.xlsx
获取文件名
Path.GetFileName("C:\Robots\港股通权限补报送\港股通权限补报送_日志表.xlsx")
运行结果:港股通权限补报送_日志表.xlsx
获取文件名,不带扩展名
Path.GetFileNameWithoutExtension("C:\Robots\港股通权限补报送\港股通权限补报送_日志表.xlsx")
运行结果:港股通权限补报送_日志表
获取文件名所在的根目录
Path.GetPathRoot("C:\Robots\港股通权限补报送\港股通权限补报送_日志表.xlsx")
运行结果:C:\
当前用户的临时文件夹的路径
Path.GetTempPath
https://docs.microsoft.com/zh-cn/dotnet/api/system.io.path.gettemppath?view=net-6.0&tabs=windows
环境相关
获取当前文件夹路径
Environment.CurrentDirectory
字符串组合成路径
Path.Combine(Environment.CurrentDirectory,"Data")
https://docs.microsoft.com/zh-cn/dotnet/api/system.io.path.combine?view=net-5.0
文件在远程桌面的路径
Path.Combine("\\tsclient\", in_Config("RobotWorkFolder").ToString.Replace(":\","\"), strFileName)
获取文件夹里面最新的一个文件
Directory.GetFiles(Environment.CurrentDirectory,"Exceptions_Screenshots\").OrderByDescending(Function(d) New FileInfo(d).CreationTime)(0)
Windows 系统相关
自动登录Windows
免费:https://www.logonexpert.com/freeautologon/
付费:LogonExpert(可试用),配置好之后就可以自动登录Windows系统了
命令行使用:
"C:\Program Files\Softros Systems\LogonExpert\le.exe" -logon username [password][domain]
详细信息请参考:https://www.logonexpert.com/help/command-line/
如果有域名的话,一定要加上域名。
也可以在LogonExpert Administrator 配置好,然后直接使用
"C:\Program Files\Softros Systems\LogonExpert\le.exe" -logon *
启动进程
WorkingDirectory:如果未设置该属性,则默认工作目录为 %SYSTEMROOT%\system32。
UiPath 的控件 Open Application 打开应用,除非指定工作目录,否则都是默认使用 %SYSTEMROOT%\system32
NewProcess = New System.Diagnostics.Process
NewProcess.StartInfo.CreateNoWindow = False '是否创建窗口
NewProcess.StartInfo.FileName = '文件名称
NewProcess.StartInfo.Arguments = " " + argInstrArguments '参数
NewProcess.StartInfo.WorkingDirectory = '工作目录
NewProcess.StartInfo.UseShellExecute = '是否使用shell来执行
NewProcess.Start() '启动进程
NewProcess.WaitForExit() '等待进程退出
System.Diagnostics.Process.Start 用法
https://docs.microsoft.com/zh-cn/dotnet/api/system.diagnostics.process?view=net-6.0
打开文件管理器
System.Diagnostics.Process.Start("explorer.exe")
打开文件管理器,指定路径
System.Diagnostics.Process.Start("explorer.exe", "C:\Users\lbj\Documents\ChromeDownloads")
打开文件管理器,选中指定文件
System.Diagnostics.Process.Start("explorer.exe", "/select,"+ "C:\Users\lbj\Documents\ChromeDownloads\031002100311_43538867.pdf" )
打开远程桌面的文件管理器,指定路径
Argument:文件夹路径
FileName:”C:\Windows\explorer.exe”
Selector:```
![Uipath打开远程桌面的文件管理器,指定路径](https://img.lbjheiheihei.xyz/img/20220416_Uipath打开远程桌面的文件管理器,指定路径.png?imageView2/0/format/webp/interlace/1/q/75 "Uipath打开远程桌面的文件管理器,指定路径")
### 设置已中断会话时间限制
为防止流程在系统启动后处于锁屏状态,通过设置 ”**已中断会话时间限制**“ 来让会话注销,达到每次进去之后都创建一个新的远程链接。
在运行中输入:**gpedit.msc** 打开本地组策略编辑器
计算机设置->管理模板->Windows 组件->远程桌面服务->远程桌面会话主机->会话时间限制
双击打开“**设置已中断会话的时间限制**”,选中“**已启用**”,“结束已断开连接的会话”设置为“**1分钟**”
### 设置Windows Server登录时禁止自动启动服务器管理器
[https://blog.csdn.net/allway2/article/details/103940157](https://blog.csdn.net/allway2/article/details/103940157)
## 输入法相关
### 切换为英文输入法
安装依赖 LanguageChange,然后使用控件Language Change Activity 切换成英文
![](https://img.lbjheiheihei.xyz/img/20220810_切换为英文输入法.png?imageView2/0/format/webp/interlace/1/q/75 "切换为英文输入法")
## 鼠标相关
### 鼠标滚轮上下滑动
安装依赖包:ScrollActivity
### 鼠标移动到具体的元素位置
控件:Hover
### 鼠标循环滚动到具体的元素位置
循环 + 控件:Hover
### 鼠标移动指定的距离
Uipath 实现起来挺麻烦的,cmd 使用工具 [nircmd](http://www.nirsoft.net/utils/nircmd.html) 可以实现,但是 nircmd 会报毒(实测火绒、360)。
鼠标位置相对移动 movecursor [X] [Y]
move the mouse cursor. The **[X]** and **[Y]** parameters specifies the number of pixels to move.
Example: movecursor 100 100
```shell
nircmdc movecursor 100 100
Http请求
安装依赖包 UIPath.WebAPI.Activities
短信(验证码)相关
使用短信猫、双卡助手(安卓)、短信转发器 (安卓)、 IFTTT(安卓)、Tasker(安卓)、快捷指令(iOS 半自动)、来转发短信。
可以查看影刀的文档
也可以试试:sms_forwarding
Excel相关
将列索引转换为列字母
UiPath.Excel.Helpers.ExcelUtilities.ConvertColumnIndexToColumnLetter(number)
将列字母转换为列索引
UiPath.Excel.Helpers.ExcelUtilities.ConvertColumnLetterToColumnIndex("A")
Write Range 后的数据不对
使用 Workbook 的 Write Range,不要使用 Excel 的 Write Range。前者的单元格格式是文本,后者则不一定。
Excel 去重
使用 Remove Duplicates Range,如果数据是A到Z列,则范围填写A:Z
无法导入 UiPath 生成的 Excel 文件
SAP或者别的应用,可能是因为 UiPath 生成的 Excel 文件不带有用户信息?
需要信任一下才能导入 Excel 文件
Write Range报错: Cannot write to the target range because it has hidden rows. Remove any filters or unhide rows and try again.
打开的 Excel 里面的 Sheet 有隐藏的行或者列,无法使用 Excel 的 Write Range,但是可以用 Workbook 的 Write Range
一个一个cell填写数据特别慢
- Excel Scope 取消勾选 Save changes,填写完成后使用控件 Save Workbook
- 打开excel之后,先按下滚动条,滑动一下
Excel 自动填写数据
控件:Auto Fill Range
Delete Range
range填写 “A:Z”,代表删掉 A 到 Z 列的数据。
Excel 在表格里面筛选数据
前提:已有 excel 文件,里面的数据已经设置好筛选
使用控件:Filter Table,疑似对表有用,对透视表无用。
别的都还好填写,但是 TableName 真的不知道在哪。
https://docs.uipath.com/activities/lang-zh_CN/docs/table-functions
第三方控件
官方的控件不够用的话,可以使用
表格转置:https://marketplace.uipath.com/listings/transpose-datatable9373/versions
VBA相关
UiPath 运行VBA,前置操作
Excel:
如果报错 Invoke VBA: 不信任到 Visual Basic Project 的程序连接,那么去 Excel 的 文件-> 选项,找到信用中心,点击信用中心设置。
接着找到宏设置, 在开发人员宏设置里面勾选「启用所有宏 」、「信任对VBA工程对象模型的访问」
WPS:
设置1、开发工具->宏安全性->可靠发行商, 勾选信任对于”Visual Basic 项目”的访问。
设置2、文件->选项->信任中心,勾选【启用宏后自动添加为受信任的文档】。
VBA 删除Sheet页
delSheet.txt 的内容:
Sub Deletesheet(sheetName)
Sheets(sheetName).Delete
End Sub
想删除的是 Sheet2
VBA 删除Sheet
Function DeleteSheet(in_StrFilePath, in_StrSheetName As String) As String
Application.DisplayAlerts = False '禁止弹窗
Application.ScreenUpdating = False '禁止显示
On Error GoTo Myerr '异常处理
Dim Wb_Root As Workbook
Set Wb_Root = Workbooks.Open(in_StrFilePath, 0)
'初始化结束
Wb_Root.Sheets(in_StrSheetName).Delete
Wb_Root.Save
Wb_Root.Close
Myerr:
DeleteSheet = Err.Description
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Function
VBA 删除C列为空的行
Worksheets("指数转化表").Columns("c:c").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
若C列没有空的数据,会报错【未找到单元格】。
VBA 删除指定范围的行
Worksheets("指数转化表").Range("H20:N1171").EntireRow.Delete
VBA 从最后一行删到指定行
Sheet<指数转化表>, 从最后一行开始删数据,删到第20行指数转化表>
Dim i As Integer
For i = Worksheets("指数转化表").UsedRange.Rows.Count To 20 Step -1
Worksheets("指数转化表").Rows(i).Delete
Next i
VBA 从指定行开始删数据
Sheet<指数转化表>, 从20行开始删数据指数转化表>
Worksheets("指数转化表").UsedRange.Offset(20).Delete
注:对表不可用,会报错【不允许此操作,因为它会移动工作表上表格中的单元格】
VBA 粘贴数据
Wb_Root.ActiveSheet.Paste
VBA 自动调整所选列列宽
调整 i 列的列宽
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
ActiveSheet.Range("i:i").EntireColumn.AutoFit
End Sub
VBA 打开 Excel
Function OpenExcel(in_StrFilePath As String)
Application.DisplayAlerts = False '禁止弹窗
Application.ScreenUpdating = False '禁止显示
On Error GoTo ErrorHandler '异常处理
Dim Wb As Workbook
Set Wb = Workbooks.Open(in_StrFilePath, 0)
'初始化结束
Application.Workbooks(wb).Activate '测试异常的情况
Wb.Save
Wb.Close
Exit Function '正常运行完成,退出 Function
ErrorHandler:
OpenExcel = "运行错误,错误号:" & Err.Number & ",错误信息:" & Err.Description
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Function
Err 对象
Error对象
Description | 设置或返回一个描述错误的字符串 |
Number | (缺省属性)设置或返回指定一个错误的值 |
Source | 设置或返回产生错误的对象的名称 |
Clear | 清除当前所有的Err对象设置 |
Raise | 产生一个运行期错误 |
https://docs.microsoft.com/zh-cn/office/vba/api/excel.error
https://learn.microsoft.com/zh-cn/office/vba/language/reference/user-interface-help/err-object
https://learn.microsoft.com/zh-cn/office/vba/language/reference/user-interface-help/error-statement
Sub 和 Function 的区别
可以简单的理解为 ,Sub 是过程,没有返回值。Function 是函数,有返回值。
SQL
MySQl 配置 ODBC
执行 sql 前,需要安装 mysql-connector-odbc (32位的),安装完成后打开ODBC数据源(32位),选择用户DSN,随后点击添加。
选择 MySQL ODBC Unicode Driver(旧版本只有 MySQL ODBC Driver)
输入DNS名字以及描述、MySQL数据库的IP地址与端口,点击ok。点击 Details 展开,设置中文字符集。
清空一个表
TRUNCATE TABLE 表名;
把一个表的数据去重放入另一个表
vcp_all 表不设置主键,vcp_distinct 表设置主键。
如果 all 表有,distinct 表没有,则会把数据插入到 distinct 表;
如果 all 表有,distinct 表也有,则会把 distinct 表的数据更新;
replace INTO vcp_distinct select * from vcp_all;
正则
正则表达式构建器
https://docs.uipath.com/activities/lang-zh_CN/docs/regex-builder-wizard
日期是否是yyyy/MM/dd
^[12]\d{3}/(?:0[1-9]|1[0-2])/(?:0[1-9]|[12][0-9]|30|31)$
获取数字
用正则把非数字的字符去掉
System.Text.RegularExpressions.Regex.Replace( str, "[^0-9]+", "")
获取英文
用正则把非英文的字符去掉
System.Text.RegularExpressions.Regex.Replace( str, "[^A-Za-z]+", "")
获取中文
用正则把非中文的字符去掉
System.Text.RegularExpressions.Regex.Replace( str, "[^\u4e00-\u9fa5]]+", "")
判断字符串中是否含有5个下划线
System.Text.RegularExpressions.Regex.Matches(str,"_").Count=5
匹配日期(年-月-日)
匹配(年-月-日)格式日期
([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))
匹配数字+英文
[A-Za-z0-9]+$
匹配数字+英文(至少是五位)
[A-Za-z0-9]+${5,}
匹配数字+英文+()()_(至少是五位)
[A-Za-z0-9\+\-()\(\)]+${5,}
匹配中文
pattern: “[\u4e00-\u9fa5]+”
匹配非中文
[^\u4e00-\u9fa5]
SAP
启用 SAP GUI 脚本编写
或者看 Uibot 的 https://docs.uibot.com.cn/guide/d1/ch004.html?version=0.6422463797095322#sap%E7%A8%8B%E5%BA%8F
支持的 SAP WinGUI 元素
https://docs.uipath.com/studio/lang-zh_CN/docs/supported-sap-wingui-elements#sap-alv-table
Bat脚本(cmd命令行)
在远程控制的使用可以使用 bat 脚本来实现某些功能
修改cmd窗口编码为UTF-8
chcp 65001
创建虚拟磁盘
把 C:\O32_d 映射到 H 盘
@echo off
C:\Windows\System32\Subst H: C:\O32_d
Pause
删除虚拟盘
取消 H 盘的映射
@echo off
C:\Windows\System32\Subst H: /d
Pause
杀进程
以 UiPath.Executor 为例,可以在任务管理器的详细信息里面找到执行的程序名称。
taskkill /f /t /im UiPath.Executor.exe
7Zip 压缩文件
a:将文件添加到压缩档案中 b:测试压缩或解压算法执行时的 CPU 占用 d:从压缩档案中删除文件 e:将压缩档案中的所有文件解压到指定路径,所有文件将输出到同一个目录中 h:计算文件的哈希值 i:显示有关支持格式的信息 l:列出压缩档案的内容 rn:重命名压缩档案中的文件 t:测试压缩档案的完整性 u:更新要进入压缩档案中的文件 x:将压缩档案中的所有文件解压到指定路径,并包含所有文件的完整路径
"C:\Program Files\7-Zip\7z.exe" a 压缩包路径 压缩文件路径
7Zip 解压文件
-o和解压路径不要用空格分开
"C:\Program Files\7-Zip\7z.exe" x 压缩包路径 -o解压路径
WinRAR 压缩文件
压缩文件的一般命令行命令语法为:
WinRAR A [-参数] <压缩文件> [文件] [@文件列表]压缩文件>
例如说,您希望添加文件 LETTER.TXT 到压缩文件 LETTERS.RAR ,请输入:
WinRAR A LETTERS.RAR LETTER.TXT
建议是使用
WinRAR A -ep1 LETTERS.RAR LETTER.TXT
添加文件夹 “c:\latest data” 到压缩文件 Info.rar 中
WinRAR a Info.rar "c:\latest data"
WinRAR 解压文件
解压压缩文件 Info.rar 到文件夹 d:\data
WinRAR x Info.rar d:\data\
xcopy 复制文件
把 D:\666 文件夹下面的所有文件和文件夹复制到E:\777,其中包含空的文件夹,不提示是否要覆盖现有目标文件。
xcopy "D:\666" "E:\777" /s /e /y
把 D:\666 文件夹下面的 *_compare_result.xlsx 复制到E:\777,不提示是否要覆盖现有目标文件。
xcopy "D:\666\*_compare_result.xlsx" "E:\777" /y
https://docs.microsoft.com/zh-cn/windows-server/administration/windows-commands/xcopy
参数 | 说明 |
---|---|
/f | 复制时显示源和目标文件名。 |
/d [:MM-DD-YYYY] | 仅复制指定日期或之后更改的源文件。 如果未包含 MM-DD-YYYYY 值,xcopy 则复制比现有目标文件更新的所有源文件。 此命令行选项允许更新已更改的文件。 |
/s | 复制目录和子目录,除非它们为空。 如果省略 /s, xcopy 可在单个目录中工作。 |
/e | 复制所有子目录,即使它们为空也是如此。 将 /e 与 /s 和 /t 命令行选项配合使用。 |
/exclude:FileName1[+[FileName2]][+[FileName3] ( ) ] | 排除文件列表。 必须至少指定一个文件。 每个文件将包含搜索字符串,其中每个字符串位于文件中的单独行上。 当任一字符串与要复制的文件绝对路径的任何部分匹配时,将排除该文件被复制。 例如,指定字符串 obj 将排除目录 obj 下的所有文件或 扩展名为 .obj 的所有文件。 |
/y | 禁止提示确认要覆盖现有目标文件。 |
/j | 在不缓冲的情况下复制文件。 建议用于非常大的文件。 此参数已在 Windows Server 2008 R2 中添加。 |
移动鼠标
rundll32 user32.dll,SetCursorPos
等待 10 秒
@echo off
timeout /t 10 /NOBREAK
https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/timeout
等待 5 秒 (ping 127.1 的方式)
这个等待时间不太准确
ping 127.1 -n 5 > nul
PowerShell
PowerShell 移动鼠标一段距离(X轴)
使用控件:Invoke Power Shell
勾选:IsScript
Paramenters:MoveX、speed
参数说明:MoveX 为 X 轴要移动的距离,可以为正,可以为负;speed 为移动的速度,实际为 Sleep 的毫秒数。
实际效果:在当前位置上,鼠标在X轴移动一段距离
Param(
[Parameter(Mandatory=$true)] [int32]$MoveX, # X轴要移动的距离,可以为正,可以为负
[Parameter(Mandatory=$true)] [Int32]$speed # 移动的速度,实际为 Sleep 的毫秒数
)
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# $MoveX = -100 # X轴要移动的距离
$MoveCount = 0 # 移动的次数
while($MoveX -gt 0) # 遍历到 MoveX 为 0。-ge :大于等于,如果 MoveX 大于等于0,则进入循环
{
$MoveX = $MoveX-1
$x = [Windows.Forms.Cursor]::Position.X+1 # 鼠标当前 X 轴的位置 +1
$y = [Windows.Forms.Cursor]::Position.Y # 鼠标当前 Y 轴的位置
$MoveCount= $MoveCount +1
if ($MoveCount -eq 10) # 如果移动的次数等于10,则随机变动一下位置,可以去掉,感觉也不太好用。
{
$RandomX = Get-Random -Minimum -1 -Maximum 1 # 随机数,最小为-1,最大为1
$RandomY = Get-Random -Minimum -1 -Maximum 1 # 随机数,最小为-1,最大为1
$x = $x + $RandomX
$y = $y + $RandomY
$MoveCount = 0 # 移动的次数归零
}
[Windows.Forms.Cursor]::Position = new-object Drawing.Point $x,$y
Start-Sleep –m $speed
}
while($MoveX -le 0) # 遍历到 MoveX 为 0 。-le :小于等于,如果 MoveX 小于等于0,则进入循环
{
$MoveX = $MoveX+1
$x = [Windows.Forms.Cursor]::Position.X-1 # 鼠标当前 X 轴的位置 -1
$y = [Windows.Forms.Cursor]::Position.Y # 鼠标当前 Y 轴的位置
$MoveCount = $MoveCount +1
if ($MoveCount-eq 10) # 如果移动的次数等于10,则随机变动一下位置,可以去掉,感觉也不太好用。
{
$RandomX = Get-Random -Minimum -1 -Maximum 1 # 随机数,最小为-1,最大为1
$RandomY = Get-Random -Minimum -1 -Maximum 1 # 随机数,最小为-1,最大为1
$x = $x + $RandomX
$y = $y + $RandomY
$MoveCount = 0 # 移动的次数归零
}
[Windows.Forms.Cursor]::Position = new-object Drawing.Point $x,$y
Start-Sleep –m $speed
}
移动鼠标到指定位置
使用控件:Invoke Power Shell
勾选:IsScript
Paramenters:x3、y3、speed
参数说明:speed 为移动的速度,实际为 Sleep 的毫秒数。
使用说明:这里其实是三阶贝塞尔曲线,当前鼠标位置为起点,而(x1,y1)、(x2,y2) 为控制点,(x3,y3) 为终点。
实际效果:在当前位置上,鼠标开始移动到指定位置
代码思路借鉴了https://www.techotopia.com/index.php/Drawing_Graphics_using_PowerShell_1.0_and_GDI%2B,只不过别人是画图,我是移动鼠标。没有办法,暂时没找到更拟人的轨迹。
可以考虑学习:https://zhuanlan.zhihu.com/p/58284406
#
Param(
[Parameter(Mandatory=$true)] [Int32]$x3,
[Parameter(Mandatory=$true)] [Int32]$y3,
[Parameter(Mandatory=$true)] [Int32]$speed # 移动的速度,实际为 Sleep 的毫秒数
)
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$x0 = [Windows.Forms.Cursor]::Position.X # 鼠标当前 X 轴的位置
$y0 = [Windows.Forms.Cursor]::Position.Y # 鼠标当前 Y 轴的位置
$x1 = 100 #
$y1 = 100 #
$x2 = 800 #
$y2 = 800 #
# $x3 = 500 # 目标 X 轴的位置
# $y3 = 500 # 目标 Y 轴的位置
$u = 0 #
while($u -le 1)
{
$u = $u+0.005
$x = [math]::pow( (1-$u) , 3) * $x0 + 3 * [math]::pow( (1-$u) , 2) * $u * $x1 + 3 * [math]::pow( ($u) , 2) * (1-$u) *$x2 + [math]::pow( ($u) , 3) * $x3
$y = [math]::pow( (1-$u) , 3) * $y0 + 3 * [math]::pow( (1-$u) , 2) * $u * $y1 + 3 * [math]::pow( ($u) , 2) * (1-$u) *$y2 + [math]::pow( ($u) , 3) * $y3
[Windows.Forms.Cursor]::Position = new-object Drawing.Point $x,$y
Start-Sleep –m $speed
}
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Mouse{
[DllImport("user32.dll")]
public static extern bool SetCursorPos(int x, int y);
}
"@
# 模拟鼠标移动到指定位置
[Mouse]::SetCursorPos(100, 100);
# 加载 System.Windows.Forms 命名空间
Add-Type -AssemblyName System.Windows.Forms
# 将鼠标移动到 (100, 100) 的位置
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point(100, 100)
浏览器相关
谷歌浏览器,下载前询问每个文件的保存位置
谷歌浏览器,设置关闭所有窗口时清除 Cookie 及网站数据
您的连接不是私密连接
solution1:
- 在当前页面点击一下,然后用键盘输入 thisisunsafe ,不是在地址栏输入,是直接敲键盘。
- 因为Chrome不信任这些自签名ssl证书,为了安全起见,直接禁止访问。thisisunsafe 这个命令,说明你已经了解并确认这是个不安全的网站,你仍要访问就给你访问了。
solution2
- 打开chrome://flags
- 找到“Show in-form warnings for sensitive fields when the top-level page is not HTTPS”设置为 disabled
- 找到 “Allow invalid certificates for resources loaded from localhost”设置为 “enabled”
- 点启用,然后重启浏览器
solution3
设置 chrome忽略证书错误
使用 –ignore-certificate-errors 参数命令行打开谷歌浏览器
谷歌浏览器黑屏
原因:可能是因为软件和显卡不兼容
解决办法:禁用硬件加速
打开谷歌浏览器加上参数 –disable-gpu –disable-software-rasterizer
"--test-type --ignore-certificate-errors --no-sandbox --new-window --disable-gpu --disable-gpu-rasterization --disable-gpu-vsync --disable-accelerated-2d-canvas --disable-software-rasterizer "+ in_strSystemUrl
谷歌浏览器崩溃:“STATUS_INVALID_IMAGE_HASH”
https://blog.csdn.net/willingtolove/article/details/106589985
弹出式窗口和重定向
关闭谷歌浏览器异常恢复弹窗
- 关闭谷歌浏览器,避免影响;
- 打开文件夹;
%UserProfile%\AppData\Local\Google\Chrome\User Data\Default
%LocalAppData%\Google\Chrome\User Data\Default
- 找到并打开 Preference 文件;
- 修改 Preference 文件中的 exit_type 的值为 Normal;
- 修改 Preferrence 文件的属性为只读;
https://docs-repo.uibot.com.cn/application-automation/close-chrome-exception-recovery-popup
https://blog.csdn.net/sarida/article/details/88212125
Win11使用 IE
用 vbs 启动 IE,新建一个记事本,填入下面的内容,重命名记事本为 打开IE.vbs
'打开IE.vbs
CreateObject("InternetExplorer.Application").Visible=true
'IE打开指定网址.vbs
StartURL = "https://www.baidu.com/"
set IE = CreateObject("InternetExplorer.Application")
IE.Visible = true
IE.Navigate StartURL
还有一种方式是 edge,可以使用 IE 模式加载网页
edge://settings/defaultBrowser
edge://compat/sitelistmanager
还有一个办法是替换 ieframe.dll
https://zhuanlan.zhihu.com/p/474585422
如何将文件所有者改为TrustedInstaller:NT SERVICE\TrustedInstaller
修复丢失或损坏的系统文件,用于恢复 ieframe.dll 等文件
以管理员身份,打开cmd ,输入 DISM.exe /Online /Cleanup-image /Restorehealth 回车运行 以管理员身份,打开cmd ,输入 sfc /scannow 回车运行
Win Server 关闭 IE 增强的安全配置
如果设置兼容性视图、加入到信任站点,用 IE 访问网站还是有问题,那么可以试试。
打开服务器管理器,在本机服务器那里找到【IE 增强的安全配置】,把它关闭掉。
iFrame
如果流程用到的系统用了 iFrame,可以试试用新版本的 UiExplorer 能不能识别到,如果可以的话,考虑升级 Studio 版本;如果不行,试一下把浏览器切换成 IE。
奇奇怪怪的坑
ctrl v 失效
ctrl c + ctrl v,无法把复制的内容粘贴到 Excel 文件里面,只输入了一个 v.
原因:未知
解决办法:Send Hotkey 控件勾选 SendWindowMessage.
Selector 能找到元素,但是运行报错 time out
开发时,使用控件的Selector 是能够定位到元素的,但是实际运行的时候,却报错,显示 time out。
原因:网站的问题,网页其实还在加载中,一直都在加载,会加载很久,但是不影响正常使用。(比如说要抓取网页数据,但是有个 gif 文件,一直都加载失败)
解决办法:WaitForReady 属性选择 None
客户机的系统和服务器日期不为同一天
使用到人民币银行结算账户管理系统,登录的时候提示【客户机的系统和服务器日期不为同一天】。
原因:未知
解决办法:用IE浏览器,把网站添加到兼容性视图。
选择元素,F2倒计时结束后元素消失
F2之后,直接鼠标按住元素,倒计时结束后能看到元素,选择元素。
Cannot find the UI element corresponding to this selector
背景信息:确认有元素,且不会变动,selector 验证是通过的,但是运行的时候报错。
异常情况:selector 不止一个 /selector 不对
解决办法1:图像识别
解决办法2:不要用 attach window
解决办法3:把界面最小化之后,再去点击。
Cannot communicate with the browser, please check the UiPath extension
背景信息:uipath扩展程序没有问题
异常情况:报错说连接不到浏览器,检查一下uipath扩展程序
解决办法:看看输入的浏览器的地址是否为空,为空则跳过
你要允许来自未知发布者的此应用对你的设备进行更改吗?
Solution1:
点击显示详细信息,选择何时显示更改通知,改为【从不通知】
不太推荐
Solution2:
- Win + R,输入 regedit,然后回车。
- 在注册表编辑器内,找到HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
-
提前把 .exe 文件的路径复制
- 在空白处右键,选择新建,字符串值,把复制的路径填入
- 在数值数据处,输入 RunAsInvoker
- 点击确定,完成
Solution3:
如果是远程机器使用 UiPath RemoteRuntime 的话,可以考虑去找到UiPath RemoteRuntime.exe 的路径,右键,在属性里面的兼容性里,勾选以管理员身份运行此程序
以管理员身份运行Uipath应用程序
识别元素报错:无法访问目标流程!可能需要提升权限,尝试以管理员身份运行Uipath应用程序。
如果是识别本机元素,那就找到 UiPath.Studio.exe 、UiPath.Executor.exe、UiRobot.exe ,勾选以管理员身份运行此程序。
如果是识别远程机器的元素,那就在远程的机器里面,找到 UiPath RemoteRuntime.exe ,勾选以管理员身份运行此程序。
勾选以管理员身份运行此程序的方式:找到指定 exe 文件,右键,点击属性,在兼容性里面,勾选【以管理员身份运行此程序】
Block User Input 锁不了鼠标键盘
用 ToDesk 连接到别的机器的话,确实不行…
以管理员身份运行UiPath.Executor.exe,没用;
以管理员身份运行UiPath Studio,再执行流程,直接报错
RemoteException wrapping System.AggregateException: One or more errors occurred. (拒绝访问。) ---> RemoteException wrapping System.ComponentModel.Win32Exception: 拒绝访问。
at System.Diagnostics.ProcessManager.OpenProcess(Int32 processId, Int32 access, Boolean throwIfExited)
at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
at System.Diagnostics.Process.GetOrOpenProcessHandle()
at System.Diagnostics.Process.EnsureWatchingForExit()
at System.Diagnostics.Process.set_EnableRaisingEvents(Boolean value)
at UiPath.Service.UserHost.AttendedServiceProxy.RegisterClientProcess(Int32 clientPid)
at UiPath.Service.UserHost.StudioOperations.Prepare(ClientProcessMessage message, CancellationToken ct)
at UiPath.Service.Core.Utils.TaskUtils.WithShortWait(Task task, TimeSpan wait)
at UiPath.Service.UserHost.StudioOperations.<>c__DisplayClass7_0.<<RunJob>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at UiPath.CoreIpc.CancellationHelper`1.Invoke[TResult](TId requestId, Func`2 func)
at UiPath.CoreIpc.Server.<>c__DisplayClass7_3.<<-ctor>g__InvokeMethod|6>d.MoveNext()
--- End of stack trace from previous location ---
at UiPath.CoreIpc.Server.<>c__DisplayClass7_1.<<-ctor>g__HandleRequest|3>d.MoveNext()
--- End of stack trace from previous location ---
at UiPath.CoreIpc.Server.<>c__DisplayClass7_2.<<-ctor>b__5>d.MoveNext()
--- End of stack trace from previous location ---
at UiPath.CoreIpc.Helpers.Timeout[TResult](TimeSpan timeout, List`1 cancellationTokens, Func`2 func, String message, Func`2 exceptionHandler)
--- End of inner exception stack trace ---
at System.Diagnostics.ProcessManager.OpenProcess(Int32 processId, Int32 access, Boolean throwIfExited)
at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
at System.Diagnostics.Process.GetOrOpenProcessHandle()
at System.Diagnostics.Process.EnsureWatchingForExit()
at System.Diagnostics.Process.set_EnableRaisingEvents(Boolean value)
at UiPath.Service.UserHost.AttendedServiceProxy.RegisterClientProcess(Int32 clientPid)
at UiPath.Service.UserHost.StudioOperations.Prepare(ClientProcessMessage message, CancellationToken ct)
at UiPath.Service.Core.Utils.TaskUtils.WithShortWait(Task task, TimeSpan wait)
at UiPath.Service.UserHost.StudioOperations.<>c__DisplayClass7_0.<<RunJob>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at UiPath.CoreIpc.CancellationHelper`1.Invoke[TResult](TId requestId, Func`2 func)
at UiPath.CoreIpc.Server.<>c__DisplayClass7_3.<<-ctor>g__InvokeMethod|6>d.MoveNext()
--- End of stack trace from previous location ---
at UiPath.CoreIpc.Server.<>c__DisplayClass7_1.<<-ctor>g__HandleRequest|3>d.MoveNext()
--- End of stack trace from previous location ---
at UiPath.CoreIpc.Server.<>c__DisplayClass7_2.<<-ctor>b__5>d.MoveNext()
--- End of stack trace from previous location ---
at UiPath.CoreIpc.Helpers.Timeout[TResult](TimeSpan timeout, List`1 cancellationTokens, Func`2 func, String message, Func`2 exceptionHandler)
批量插入数据(Insert DataTable)到数据库报错
查询没问题,单条插入也没问题,就是批量插入有问题。
报错:
ERROR [42000] [MySQL][ODBC 3.51 Driver][mysqld-8.0.28]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DEFAULT VALUES' at line 1
解决办法:
把 UiPath.Database.Activities 版本改为 1.4.0
UiPath Data Scraping只能抓取网页表格的数据
问题:只能抓取表格的数据,不能单独爬取一列一列的数据。
selector还会有点问题,像 window 软件的 selector
<ctrl role='grouping' text='展开' />
而不像是网页的selector,
<webctrl aaname='展开' tag='SPAN' />
解决办法:重启 Uipath Studio
报错:Scrape returned empty text
ocr识别的时候出图像错,因为图像没加载出来,但是元素存在。
能运行的代码,突然有一天不能运行了1
检查一下最近有没有安装什么软件,导致冲突了。
注:特指福昕阅读器。
检查一下有没有什么软件自动更新,导致出现问题了。
注:特指福昕阅读器。
只是看 PDF 的话,SumatraPDF 其实也可以的,
能运行的代码,突然有一天不能运行了2
检查一下某些安全软件有没有升级,导致文件无法删除。
IsNumeric() 报错
Compiler error(s) encountered processing expression “IsNumeric(CurrentRow(0).ToString)”. 没有类的显式实例,就无法从共享方法或共享成员初始值设定项中引用该类的实例成员。
解决办法:
"7".IsNumeric
Microsoft.VisualBasic.IsNumeric("7")
Microsoft.VisualBasic.Information.IsNumeric("7")
Studio 运行流程报错 Unable to start execution
UiPath Studio 版本,2019.4,在 Studio 运行流程,出现弹窗提示:Could not connect to UiPath Robot Service. Make sure the service is started!
试一下重启 Robot,如果还不行,那就在服务里面找到 UiPath Robot,启动一下 UiPath Robot。
UiPath 相关
教程
https://docs.uipath.com/studio/lang-zh_CN/docs/tutorials
UiPath 包路径
包含依赖包、发布在本地的包
%UserProfile%\.nuget\packages
UiPath 本地依赖包路径
nupkg 包
社区版:
%UserProfile%\AppData\Local\Programs\UiPath\Studio\Packages
%LocalAppData%\Programs\UiPath\Studio\Packages
企业版:
C:\Program Files (x86)\UiPath\Studio\Packages
UiPath Studio.exe 的路径
社区版:
%UserProfile%\AppData\Local\Programs\UiPath\Studio\UiPath.Studio.exe
%LocalAppData%\Programs\UiPath\Studio\UiPath.Studio.exe
企业版:
C:\Program Files (x86)\UiPath\Studio\UiPath.Studio.exe
UiPath UiRobot.exe 的路径
社区版
%UserProfile%\AppData\Local\Programs\UiPath\Studio\UiRobot.exe
%LocalAppData%\Programs\UiPath\Studio\UiRobot.exe
企业版
C:\Program Files (x86)\UiPath\Studio\UiRobot.exe
UiPath 本地日志的路径
%UserProfile%\AppData\Local\UiPath\Logs
%LocalAppData%\UiPath\Logs
UiPath 术语表(UiPath Glossary)
https://docs.uipath.com/overview-guide/lang-zh_CN/docs/uipath-glossary
产品生命周期(product lifecycle)
https://docs.uipath.com/overview-guide/lang-zh_CN/docs/product-lifecycle
活动生命周期(activities lifecycle)
https://docs.uipath.com/overview-guide/lang-zh_CN/docs/activities-lifecycle
弃用 Windows 旧版兼容性
https://docs.uipath.com/studio/lang-zh_CN/docs/deprecation-of-the-windows-legacy-compatibility
UiPath Studio
输入方法
Default、SendWindowMessages、SimulateType(SimulateClick)
Default:基于系统驱动的方式,来模拟键盘和鼠标行为。是最接近真实的鼠标和键盘的方式。
SendWindowMessages:通过向应用程序发送Window Message进行模拟的。是基于应用的方式。
SimulateType(SimulateClick):通过向UI元素发送消息进行模拟的。是基于UI元素的。
类型 | 基于 | 兼容程度 | 响应速度 |
---|---|---|---|
Default | 系统驱动(最接近真实鼠标键盘的方式) | 全部 | 慢 |
SendWindowMessages | 应用 | 大部分 | 中 |
SimulateType(SimulateClick) | UI元素 | 一部分 | 快 |
类型 | 光标 | 文字 |
---|---|---|
Default | 本来在其他应用程序窗口的光标,会移动到txt文本框内。 | 文字是一个个打出的 |
SendWindowMessages | 在其他应用程序窗口的光标不会被移动 | 文字是一个个打出的 |
SimulateType | 在其他应用程序窗口的光标不会被移动 | 文字是瞬间出来的 |
https://docs.uipath.com/studio/lang-zh_CN/docs/ui-automation#section-input-methods
https://www.cnblogs.com/toseeme/p/13497944.html
UiPath Robot
如果机器人已连接到 Orchestrator ,则所有执行日志都将发送到 Orchestrator,并可以在“日志”页面中看到。
如果 Orchestrator 处于不可用状态,则在连接恢复前,系统会将日志存储在可用磁盘空间的本地数据库 (C:\Windows\SysWOW64\config\systemprofile\AppData\Local\UiPath\Logs\execution_log_data
) 中。恢复连接后,系统会按日志的生成顺序将其分批发送。
在某些特定情况下文件可能会损坏、日志无法上传成功、无法打印日志。解决方法是将此文件夹下的文件删除,计算机、UiRobot服务重启。