高效读写数据

尽管Foxtable为WebViewer扩展了内置DOM,提升了混合编码的便利性,但在批量处理元素取值/赋值时,内置DOM写法仍存在大量冗余。

测试页面准备

假定我们的测试页面包含以下输入框(用于演示取值 / 赋值功能):


'''Async
Dim
wv As WebViewer = e.Form.Controls("WebViewer1").WebViewer
Await
wv.EnsureCoreWebView2Async(Nothing) '初始化浏览器
'
定义测试页面(每个输入框新增初始值)
Dim
html As String = <![CDATA[
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>
批量取值赋值测试</title>
    <style>
        *{font-size:15px; margin:5px;}
        label{display:inline-block; width:70px; text-align:right;}
        input{padding:6px 8px; width:200px; border:1px solid #ccc; border-radius:4px;}
    </style>
</head>
<body>
    <h3>
批量取值赋值测试</h3>
    <div>
        <label>
产品:</label><input type="text" id="product" value="PD001"/><br>
        <label>
客户:</label><input type="text" id="customer" value="CS001"/><br>
        <label>
雇员:</label><input type="text" id="employee" value="EP001"/><br>
        <label>
单价:</label><input type="number" id="price" step="0.01" min="0" value="59.99"/><br>
        <label>
折扣:</label><input type="number" id="discount" step="0.01" min="0" max="1" value="0.1"/><br>
        <label>
数量:</label><input type="number" id="qty" step="1" min="1" value="100"/><br>
        <label>
日期:</label><input type="date" id="date" value="2026-01-01"/><br>
    </div>
</body>
</html>
]]>
.Value
wv.NavigateToString(html)

内置DOM的痛点

若使用内置DOM读取上述输入框的值,代码会极其繁琐:

'''Async
Dim
wv As WebViewer = e.Form.Controls("WebViewer1").WebViewer 

' 1. 产品(字符串类型)
Dim
productEle = wv.getElementById("product")
Dim
productRlt As String = Await productEle.value
Dim
product As String = productRlt.Trim(""""

' 2. 客户(字符串类型)
Dim
customerEle = wv.getElementById("customer")
Dim
customerRlt As String = Await customerEle.value
Dim
customer As String = customerRlt.Trim(""""

' 3. 雇员(字符串类型)
Dim
employeeEle = wv.getElementById("employee")
Dim
employeeRlt As String = Await employeeEle.value
Dim
employee As String = employeeRlt.Trim(""""

' 4. 单价(数值类型)
Dim
priceEle = wv.getElementById("price")
Dim
priceRlt As String = Await priceEle.value
Dim
priceStr As String = priceRlt.Trim("""")
Dim
price As Double = If(priceStr = "", 0.0, CDbl(priceStr)) 

' 5. 折扣(数值类型)
Dim
discountEle = wv.getElementById("discount")
Dim
discountRlt As String = Await discountEle.value
Dim
discountStr As String = discountRlt.Trim("""")
Dim
discount As Double = If(discountStr = "", 0.0, CDbl(discountStr)) 

' 6. 数量(整数类型)
Dim
qtyEle = wv.getElementById("qty")
Dim
qtyRlt As String = Await qtyEle.value
Dim
qtyStr As String = qtyRlt.Trim("""")
Dim
qty As Integer = If(qtyStr = "", 1, CInt(qtyStr)) 

' 7. 日期(日期类型)
Dim
dateEle = wv.getElementById("date")
Dim
dateRlt As String = Await dateEle.value
Dim
dateStr As String = dateRlt.Trim("""")
Dim
dtm As Date = If(dateStr = "", Date.MinValue, CDate(dateStr))

原因是:无论输入框类型如何,内置DOM返回的都是带双引号的字符串,我们不仅要手动去掉双引号,还要进行数据类型转换,才能获得最终的结果。

WebViewer扩展方法(高效方案)

为了让大家更方便地赋值和取值,Foxtable给WebViewer另外扩展了几个方法:

GetValuesByID

用于一次性获取多个元素的值(存储在ExpandoObject对象中)。

GetValuesByID会自动处理双引号和类型转换,不需要额外编码,参数为元素ID的数组或集合。

例如要获取上述页面所有输入框的值,代码如下:

'''Async
Dim
wv As WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
ids As String() = {"product", "customer", "employee", "price", "discount", "qty", "date"}
Dim
result As Object = Await wv.GetValuesByID(ids)
Dim
product As String = result.product
Dim
customer As String = result.customer
Dim
employee As String = result.employee
Dim
price As Double = result.price
Dim
discount As Double = result.discount
Dim
qty As Integer = result.qty
Dim
dtm As Date = result.date

由于
GetValuesByID自动完成了类型转换,可以直接使用返回的值:

'''Async
Dim
wv As WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
ids As String() = {"product", "customer", "employee", "price", "discount", "qty", "date"}
Dim
result As Object = Await wv.GetValuesByID(ids)
Dim Year As Integer = result.date.Year '返回的值已经进行了正确的类型转化,可以直接用
MessageBoxA.Show(Year)

如果元素没有输入值,则返回Nothing,所以使用GetValuesByID取值时做空值判断 是非常方便的:

'''Async
Dim
wv As WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
ids As String() = {"product", "customer", "employee", "price", "discount", "qty", "date"}
Dim
result As Object = Await wv.GetValuesByID(ids)
If
result.date Is Nothing Then
    MessageBoxA.Show(
"请输入日期")
Else

   
Dim Year As Integer = result.date.year
End
If

GetValueByID

用于获取单个元素的值,会自动去双引号和类型转换,不需要额外编码,功能和
GetValuesByID完全一样。

例如取产品和数量两个元素的值:

Dim product As String = Await wv.GetValueByID("product")
Dim qty As Integer = Await wv.GetValueByID("qty")

提示:可以用多个GetValueByID代替GetValuesByID,前者编码方便,后者效率更高(一次性取回所有值),当然这种效率差距我们很难感受得到。

SetValuesByID

用于一次性设置多个元素的值,有两个参数,参数1为元素ID的数组/集合,参数2为对应值的数组/集合。

例如一次性设置上述输入框的值:

Dim wv As WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
ids As String() = {"product", "customer", "employee", "price", "discount", "qty", "date"}
Dim
vals As Object() = {"PD99", "CS88", "EP77", 99.99, 0.15, 888, "2026-12-31"}
wv.SetValuesByID(ids, vals)

SetValueByID

用于设置单个元素的值,有两个参数,分别用于指定元素ID和值。

例如设置数量值:

wv.SetValueByID("qty", 200)

提示:可以用多个SetValueByID代替SetValuesByID,前者编码方便,后者效率更高(一次性设置所有值),当然这种效率差距我们很难感受得到。


本页地址:http://www.foxtable.com/webhelp/topics/6276.htm