我希望在向“List A”添加新列表项时进行复制。
我尝试在ItemAdded事件接收器中使用SPListItem的CopyTo()方法,但无法弄清要复制到哪个URL。
这是我使用的代码。将SPlistItem和目标列表的名称作为Sharepoint中可见的名称(而不是URL)传递给它。唯一的限制是两个列表必须在同一个站点中:
private SPListItem CopyItem(SPListItem sourceItem, string destinationListName) {
//Copy sourceItem to destinationList
SPList destinationList = sourceItem.Web.Lists[destinationListName];
SPListItem targetItem = destinationList.Items.Add();
foreach (SPField f in sourceItem.Fields) {
//Copy all except attachments.
if (!f.ReadOnlyField && f.InternalName != "Attachments"
&& null != sourceItem[f.InternalName])
{
targetItem[f.InternalName] = sourceItem[f.InternalName];
}
}
//Copy attachments
foreach (string fileName in sourceItem.Attachments) {
SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName);
byte[] imageData = file.OpenBinary();
targetItem.Attachments.Add(fileName, imageData);
}
return targetItem;
}
正如Lars所说,移动项目并保留版本和正确的用户信息可能有些棘手。我以前也做过类似的事情,如果您需要一些代码示例,请通过评论告诉我,我可以为您提供一些指导。
CopyTo方法(如果您决定使用该方法)需要一个绝对Uri,例如:http://host/site/web/list/filename.doc
因此,如果您在事件接收器中执行此操作,则需要连接包含所需元素的字符串。类似以下内容(请注意,还可以通过其他方式完成):
string dest=
siteCollection.Url + "/" + site.Name + list.Name + item.File.Name;
请确保在SPFile上调用CopyTo(url)方法,而不是在SPListItem上调用。 例如:
ItemUpdated(SPItemEventProperties properties)
{
//...
string url = properties.Web.Site.Url + "/" + properties.Web.Name + "Lists/ListName/" + properties.ListItem.File.Name;
//properties.ListItem.File.MoveTo(url);
properties.ListItem.File.CopyTo(url);
//...
}
private void CopyAttachmentsToList(SPListItem srcItem, SPListItem tgtItem)
{
try
{
//get source item attachments from the folder
SPFolder srcAttachmentsFolder =
srcItem.Web.Folders["Lists"].SubFolders[srcItem.ParentList.Title].SubFolders["Attachments"].SubFolders[srcItem.ID.ToString()];
//Add items to the target item
foreach (SPFile file in srcAttachmentsFolder.Files)
{
byte[] binFile = file.OpenBinary();
tgtItem.Update();
tgtItem.Attachments.AddNow(file.Name, binFile);
tgtItem.Update();
}
}
catch
{
//exception message goes here
}
finally
{
srcItem.Web.Dispose();
}
}
tgtItem.Update();
,否则会出现错误。市面上有许多工具可将一个列表项复制到另一个列表中(如avepoint、metavis等),但如果您只打算在一个列表上执行此操作,则它们的价格相当昂贵。
如果您可以每周手动执行此操作一次,请查看以下工具:http://en.share-gate.com/sharepoint-tools/copy-move-sharepoint-list-items-with-metadata-and-version-history
param([string]$sourceWebUrl, [string]$sourceListName, [string]$destWebUrl, [string]$destListName)
$sourceWeb = get-spweb $sourceWebUrl;
$sourceList = $sourceWeb.Lists[$sourceListName];
$destWeb = get-spweb $destWebUrl;
$destList = $destWeb.Lists[$destListName];
$sourceList.Items |%{
$destItem = $destList.Items.Add();
$sourceItem = $_;
$sourceItem.Fields |%{
$f = $_;
if($f.ReadOnlyField -eq $false -and $f.InternalName -ne "Attachments" -and $sourceItem[$f.InternalName] -ne $null){
$destItem[$f.InternalName] = $sourceItem[$f.InternalName];
}
}
$destItem.Update();
}
使用时,复制并粘贴到一个文件 copy-listitems.ps1 中,并使用Sharepoint PowerShell命令行运行...
使用C#服务器端代码将一个SharePoint列表或库中的列表项复制到另一个SharePoint列表或库中
//Itecollection是来自源列表的数据集合
public void CopyItemsFromOneListToAnotherList(SPListItemCollection itemCollection)
{
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.OpenWeb())
{
//Get destination list/library
//destListName - Destination list/library name
SPList destList = web.Lists.TryGetList(destListName);
foreach (SPListItem sourceItem in itemCollection)
{
//Add new Item to list
SPListItem destItem = destList.Items.Add();
foreach (SPField field in sourceItem.Fields)
{
if (!field.ReadOnlyField && !field.Hidden && field.InternalName != "Attachments")
{
if (destItem.Fields.ContainsField(field.InternalName))
{
//Copy item to destination library
destItem[field.InternalName] = sourceItem[field.InternalName];
}
}
}
//Update item in destination library or list
destItem.Update();
Console.WriteLine("Copied " + sourceItem["ID"] + "to destination list/library");
}
}
}
}
public static SPListItem CopyItem(SPListItem sourceItem, SPList destinationList)
{
SPListItem targetItem = destinationList.AddItem();
//loop over the soureitem, restore it
for (int i = sourceItem.Versions.Count - 1; i >= 0; i--)
{
//set the values into the archive
foreach (SPField sourceField in sourceItem.Fields)
{
SPListItemVersion version = sourceItem.Versions[i];
if ((!sourceField.ReadOnlyField) && (sourceField.InternalName != "Attachments"))
{
SetFields(targetItem, sourceField, version);
}
}
//update the archive item and
//loop over the the next version
targetItem.Update();
}
foreach (string fileName in sourceItem.Attachments)
{
SPFile file = sourceItem.ParentList.ParentWeb.GetFile(sourceItem.Attachments.UrlPrefix + fileName);
targetItem.Attachments.Add(fileName, file.OpenBinary());
}
targetItem.SystemUpdate();
return targetItem;
}
private static bool SetFields(SPListItem targetItem, SPField sourceField, SPListItemVersion version)
{
try
{
targetItem[sourceField.InternalName] = version.ListItem[sourceField.InternalName];
return true;
}
catch (System.ArgumentException)//field not filled
{
return false;
}
catch (SPException)//field not filled
{
return false;
}
}
所以,这些列表具有完全相同或类似的列吗?无论哪种方式,您都可以创建一个简单的工作流,在“列表A”中创建项目时自动运行。由于所涉及的工作流相对简单,我建议使用免费的SharePoint Designer来创建它,因为您可以轻松地将两个列表的列匹配起来。下面的步骤应该能帮助您入门。