提取特殊列数据

一般用户可以跳过本节的内容。

绑定带来的第二个麻烦,是有两列的数据为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

我本人更喜欢自己写代码输出数据,而不是用绑定,这样更灵活,也不会有数据冗余,更不会有上述麻烦。


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