提取特殊列数据
一般用户可以跳过本节的内容。
绑定带来的第二个麻烦,是有两列的数据为XML格式,不能直接使用,需要转换后才能使用。
提取Resources列数据
Tasks表中有个Resources列,用于存储某个任务使用到的资源,因为一个任务可能用到多个资源,所以Resources列的数据是XML格式,例如:
<?xml version="1.0" encoding="utf-16"?>
<Resources>
<resourceRef resourceID="1284159754" amount="50" />
<resourceRef resourceID="976956852" amount="2" />
</Resources>
上述XML内容表示这个任务使用了两个资源,资源ID(resourceID)分别是1284159754和976956852,使用数量(amount)分别是50和2。
这种XML数据没有办法直接使用,需要通过代码提取出来。
首先新建一个表,结构如下,至少包括三列,分别为:
TaskID | 整数,任务ID |
ResourceID | 整数 ,资源ID |
Amount | 双精度小数,资源用量 |
假定你新建的这个表的名称是"Task_Resources"",你可以通过下面的代码将所有任务用到的资源提取到这个表中:
DataTables("Task_Resources").DataRows.Clear()
For
Each
dr
As
DataRow
In
DataTables("Tasks").DataRows
If
dr.IsNull("Resources")
Then
Continue
For
Dim
xo
As
XObject = XObject.Parse(dr("Resources"))
For
Each
jt
As
JToken
In
xo("resourceRef")
Dim
tr
As
DataRow = DataTables("Task_Resources").AddNew()
tr("TaskID")
= dr("TaskID")
tr("ResourceID")
= jt("@resourceID")
'注意"@resourceID"区分大小写
tr("Amount")
= jt("@amount")
'注意"@resourceID"区分大小写
Next
Next
你可以通过TaskID将这个表和Tasks表关联起来,通过ResourceID将这个表和Resources表关联起来,这样就可以通过表达式列获得任务名称、资源名称、资源的计量单位和单位成本等。
提取Predecessors列数据
Tasks表中的Predecessors列用于存储每个任务的前驱任务,因为一个任务可能有多个前驱任务,所以这一列同样是XML格式,例如:
<?xml version="1.0" encoding="utf-16"?>
<Predecessors>
<predecessor predecessorTaskID="957257307" lag="5" />
<predecessor predecessorTaskID="1430471703"
predecessorType="StartToStart" />
</Predecessors>
表示这个任务有两个前驱任务:
1、
第一个前驱任务的TaskID为957257307,PredecessorType没有设置,所以为默认的FinishToStart,lag(延迟)属性为5,也就是这个前驱任务完成5天后才能开始本任务。
2、
第二个前驱任务的TaskID为1430471703,PredecessorType为StartToStart,也就是这个前驱任务开始之后才能开始本任务。
如果你需要有个单独的表来存储前驱任务数据,可以先设计一个表,结构如下:
TaskID | 整数,任务ID |
PredecessorTaskID | 整数,前驱任务ID |
PredecessorType | 字符型,前驱任务类型,默认为FinishToStart |
lag | 整数型,延迟天数 |
假定这个表的名称为Task_Predecessors,你可以通过下面的代码将所有前驱任务数据提取到这个表中:
DataTables("Task_Predecessors").DataRows.Clear()
For
Each
dr
As
DataRow
In
DataTables("Tasks").DataRows
If
dr.IsNull("Predecessors")
Then
Continue
For
Dim
xo
As
XObject = XObject.Parse(dr("Predecessors"))
For
Each
jt
As
JToken
In
xo("predecessor")
Dim
tr
As
DataRow = DataTables("Task_Predecessors").AddNew()
tr("TaskID")
= dr("TaskID")
If
TypeOf
jt
Is
jobject
Then
tr("PredecessorTaskID")
= jt("@predecessorTaskID")
Dim
jo
As
JToken =
CType(jt,
jobject)
For
Each
jp
As
JProperty
In
jo.Children()
If
jp.Name =
"@predecessorType"
Then
tr("PredecessorType")
= jp.Value
ElseIf
jp.Name =
"@predecessorType"
Then
tr("PredecessorType")
= jp.Value
ElseIf
jp.Name =
"@lag"
Then
tr("lag")
= jp.Value
End
If
Next
Else
tr("PredecessorTaskID")
=
CType(jt,
JProperty).value
End
If
Next
Next
我本人更喜欢自己写代码输出数据,而不是用绑定,这样更灵活,也不会有数据冗余,更不会有上述麻烦。