最近的一个项目中,客户提出需求,希望在SharePoint进行工作计划与工作总结的填写。初看时觉得这是一个简单到不行的需求,但客户同时还提出了希望在填写工作总结时能够查看工作计划,对照着计划来写总结。这也没有什么,用数据视图也可以很好的解决。不过事情往往没那么简单......
我们先来看下客户以前的工作计划与总结的填写方式。根据客户所说,他们是每周写一次工作计划与总结,原先就是在Word中进行填写,格式如下:
客户提出的最终要求就是希望能够仍然保持这种表格式的填写方式。
无奈啊~~~
考虑再三还是用InfoPath实现起来比较简单。
好了,废话说的差不多了,开始正式的内容。
先在SharePoint中建两个表单库,并分别命名为WorkPlain与WorkSummary,留待备用。
接着我们先设计工作计划表单,这个表单比较简单,不需要什么代码。
需要注意两点:
一定要选上“仅启用浏览器功能”;
为表单进行属性提升,位置在“工具”>“表单选项”>“属性提升”, 这里是设置在SharePoint表单库中与该表单向对应的字段的地方。设置的方式很简单,不过有一个地方要注意,由于我们的表单中使用了重复表,因此在为重复表中的字段进行属性提升时,在函数一栏一定要选择合并。(切记切记,关系到未来从工作总结表读取数据的问题,如果选择第一个或最后一个,那么以后读取的数据也仅仅是第一个或最后一个)
最后将这个表单发布到我们刚才建立好的WorkPlain表单库就OK了。
在发布成功后我们就可以着手设计工作总结表单了,总结表单要比计划表单复杂很多,我将一步一步的进行说明:
第一步:设计工作总结表单布局,这步不难,与刚才我们创建的计划表单类似,不过在下方多了工作计划查询的部分。
第二步,建立数据源。
在设计好表单后,还需要建立相应的数据源,用来提交表单数据或从SharePoint中读取数据。在这张工作总结表单中我们需要建立四个数据源。
其中WorkPlain与WorkContent这两个数据源除了名字不同,其他完全相同,他们都是用来读取WorkPlain表单库中数据的。
该数据源中包含的字段要与前面上传的WorkPlain表单中进行属性提升的字段相对应,同时还应选择创建者这个字段,以用来在填写表单时来筛选出当前用户所填写的表单。
建立好WorkPlain与WorkContent两个数据连接后,还需要建立一个用于取得当前用户的数据连接。
建立新数据连接,在数据来源选项中,选择来自Web服务。
在Web服务位置处输入:http://moss服务器名称/_vti_bin/UserProfileService.asmx?WSDL
选择GetUserProfileByName操作,随后一直下一步即可。
最后还有一个作为提交数据的数据连接,因为比较简单就不详述了。
接下来,打开工作计划选择下拉框的属性设置界面
选择从外部数据源查找值,并将刚才建立的WorkPlain数据连接做为数据源,将标题字段作为该下来列表的值字段。设置好后我们还需要实现根据当前用户来对该数据源进行筛选,使下拉框中出现的仅是由当前用户所创建的工作计划的标题。
由于表单采用了与浏览器兼容模式,所以InfoPath自带的数据源筛选功能就不能用了,只能靠代码来实现这部分功能。
选择工具>编程,为表单的Loading事件编写代码。
代码部分如下:
Code
1public void FormEvents_Loading(object sender, LoadingEventArgs e)
2 {
3 //查询用户
4 string selectUserName = "";
5 string selectSourceName = "GetUserProfileByName";
6 XPathNavigator selectXPath = this.DataSources[selectSourceName].CreateNavigator();
7 string selectXPathString = "/dfs:myFields/dfs:dataFields/s0:GetUserProfileByNameResponse/s0:GetUserProfileByNameResult/s0:PropertyData/s0:Values/s0:ValueData/s0:Value[http://www.cnblogs.com/../s0:Name = 'LastName']";
8 XPathNodeIterator selectItems = selectXPath.Select(selectXPathString, this.NamespaceManager);
9 if (selectItems.Count!=0)
10 {
11 selectUserName = selectXPath.SelectSingleNode(selectXPathString, this.NamespaceManager).ToString();
12 }
13 // 根据当前用户筛选数据。
14 string dataConnectionName = "WorkPlain";
15 string dataSourceName = "WorkPlain";
16 DataConnection dc = this.DataConnections[dataConnectionName];
17 dc.Execute();
18 XPathNavigator xpn = this.DataSources[dataSourceName].CreateNavigator();
19 string xPathString = "/dfs:myFields/dfs:dataFields/dfs:工作计划[@创建者!='" + selectUserName + "']";
20 XPathNodeIterator items = xpn.Select(xPathString, this.NamespaceManager);
21 while (items.Count!=0)
22 {
23 xpn.SelectSingleNode(xPathString, this.NamespaceManager).DeleteSelf();
24 items = xpn.Select(xPathString, this.NamespaceManager);
25 }
26 }
下拉框完成后我们还需为查询按钮编写代码
Code
public void CTRL27_5_Clicked(object sender, ClickedEventArgs e)
{
DataConnection dc = this.DataConnections["WorkContent"];
dc.Execute();
XPathNavigator xpn = this.DataSources["WorkContent"].CreateNavigator();
string selectWorkName = this.MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:plainselect", this.NamespaceManager).Value;
if (selectWorkName != "")
{
string xPathString = "/dfs:myFields/dfs:dataFields/dfs:工作计划[@标题!='" + selectWorkName + "']";
XPathNodeIterator items = xpn.Select(xPathString, this.NamespaceManager);
while (items.Count != 0)
{
xpn.SelectSingleNode(xPathString, this.NamespaceManager).DeleteSelf();
items = xpn.Select(xPathString, this.NamespaceManager);
}
string workName = xpn.SelectSingleNode("/dfs:myFields/dfs:dataFields/dfs:工作计划/@工作内容", this.NamespaceManager).Value;
string[] splitWorkName = workName.Split(' ');
string workContent = xpn.SelectSingleNode("/dfs:myFields/dfs:dataFields/dfs:工作计划/@工作进度", this.NamespaceManager).Value;
string[] splitWorkContent = workContent.Split(' ');
XPathNavigator xMain = this.MainDataSource.CreateNavigator();
XPathNodeIterator groupItems = xMain.Select("/my:myFields/my:group8/my:group9", this.NamespaceManager);
if (groupItems.Count > 1)
{
XPathNavigator first = xMain.SelectSingleNode("/my:myFields/my:group8/my:group9[1]", this.NamespaceManager);
XPathNavigator last = xMain.SelectSingleNode("my:myFields/my:group8/my:group9[" + (groupItems.Count - 1) + "]", this.NamespaceManager);
xMain.MoveTo(first);
xMain.DeleteRange(last);
}
XPathNavigator group = xMain.SelectSingleNode("/my:myFields/my:group8/my:group9", this.NamespaceManager);
for (int i = 0; i < splitWorkContent.Length; i++)
{
if (i == 0)
{
xMain.SelectSingleNode("/my:myFields/my:group8/my:group9/my:plainname", this.NamespaceManager).SetValue(splitWorkName[i]);
xMain.SelectSingleNode("/my:myFields/my:group8/my:group9/my:plaincontent", this.NamespaceManager).SetValue(splitWorkContent[i]);
xMain.SelectSingleNode("/my:myFields/my:group8/my:group9/my:id", this.NamespaceManager).SetValue(i.ToString());
}
else
{
XPathNavigator newRow = group.Clone();
newRow.InsertBefore(group);
newRow.SelectSingleNode("my:plainname", this.NamespaceManager).SetValue(splitWorkName[i]);
newRow.SelectSingleNode("my:plaincontent", this.NamespaceManager).SetValue(splitWorkContent[i]);
newRow.SelectSingleNode("my:id", this.NamespaceManager).SetValue(i.ToString());
}
}
}
}
最后一步就是发布了,由于在表单中编写了代码,所以还需要修改下表单的安全性设置。
选择工具>表单选项>安全和信任,将安全级别选为完全信任
在发布位置中选择网络位置,然后进入SharePoint管理中心上传表单。