Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden
+49 (0) 351/8 33 82-0

Sharepoint Listenelement (SPListItem) in eine andere Liste kopieren

Dafür gibt es (theoretisch) eine denkbar einfache Lösung: SPListItem bietet eine Methode CopyTo(destinationUrl) an (http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.splistitem.copyto.aspx) – leider scheint diese aber nicht (in jedem Fall?) zu funktionieren. Zumindest in meinem Fall (benutzerdefinierte Liste mit benutzerdefiniertem Inhaltstyp UND Attachments – vielleicht erwarte ich einfach auch zu viel von Sharepoint…) tat sie es nicht. Stattdessen erhielt ich folgende Exception: „Source item cannot be found. Verify that the item exist and that you have permission to read it.“ Eine rasche Recherche bei Google brachte mir die Erkenntnis, dass andere Leute das gleiche Problem auch schon hatten – leider ohne verwertbare Lösungsvorschläge…

Also erstellen wir uns eben selbst eine kleine statische Methode, die das gewünschte tut:

Die Methodensignatur erwartet ein Quellelement und einen Listenname und gibt das kopierte Zielelement zurück:

image

Zuerst erstellen wir das Zielelement in der angegebenen Liste. Dann gehen wir Schritt für Schritt alle Fields des Quellelementes durch und kopieren diese zum Zielelement:

image

Achtung! Wir sollten nicht versuchen, readonly Fields zu kopieren und auch die Attachments lassen sich nicht auf diese Weise „abfertigen“. Diese behandeln wir folgendermaßen:

image

Nun noch schnell das Zielelement gespeichert und zurückgegeben – fertig 🙂

image

So könnte z.B. der Aufruf der Methode aussehen:

image

Zum besseren Kopieren hier das Ganze nochmal als Text:

public static 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)
{
if (!f.ReadOnlyField && f.InternalName != „Attachments“)
{
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);
}
targetItem.Update();
return targetItem;
}

Hi Dorrit,
möchte „Danke“ sagen.
Das kann ich demnächst sehr gut gebrauchen 🙂
Liebe Grüsse
aus Köln
Manfred

Hallo Dorrit,

vielen Dank für diesen SEHR hilfreichen Beitrag.
Hat mir aktuell sehr geholfen 😉

LG Tom

Hi Dorrit,
The solution works fine. But it does not copy the „Created By“ field i.e. when a listitem is copied to another list, the „created by“ is set to the system account and not the „created by“ column from the source list. I have a requirement where i want to replicate the „Created by“ field too.

Dorrit Riemenschneider

Hi pankaj, you should be able to solve your problem by using the SPUserToken object. Here you can find a similiar (not just the same but I think you can adapt this) solution: http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/41d34a5e-e53b-4d27-bc0a-4a4bb2107e6a
Cheers, Dorrit

Hallo!

Danke für den hilfreichen Post! Wollte nur noch anmerken, dass beim kopieren ein „Assigned To“ Field nicht mitkopiert wird, da (unter Umständen) der User in einer anderen Site Collection eine andere Userid haben kann 😉 )
Ansonsten funktioniert das aber super!

viele Grüße aus München
Johannes

thank you, it was very helpful for me.

OMG….you are a GENIUS ! Thank you so much for covering this problem, your solution save my day ! I really2 appreciate your effort for this ! 😀

Hello

I am having trouble implementing the code above. I have two sitecollections and want to copy a list item from one site collection list to another site collection list.

Sitecollection 1name: mySiteCollection1

Sitecollection 2 name: mySiteCollection2

This is my code which is run in Site Collection 1. I have created the event handler and have added it to the GAC and implemented the Feature.

public override void ItemAdded(SPItemEventProperties properties) {
SPListItem approvedItem = CopyItem(properties.ListItem, „http://localhost/mysitecollection2/mysubsite/Contacts/AllItems.aspx“);
}

public static 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)
{
if (!f.ReadOnlyField && f.InternalName != „Contacts“)
{
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);
}

targetItem.Update();
return targetItem;
}

Thank you

Yoshi

Dorrit Riemenschneider

Hello Yoshi, the code is meant for copying items between two lists in the same site. The code line „SPList destinationList = sourceItem.Web.Lists[destinationListName];“ won’t work between site collections.

Hello

Will it work for two lists in two subsites of the same site collection?

Example:

Subsite A – List 1

To

Subsite B – List 2

Thank you

Yoshi

Dorrit Riemenschneider

Hello Yoshi, same problem regarding code line „SPList destinationList = sourceItem.Web.Lists[destinationListName];“. Of course you can adapt it in order to bring it to work between different sites.

Hi Dorrit

Thank you for sharing the code above. I have managed to get this to work with 2 identical custom lists in the same site. However, when I add a new list item to List A, it will create approximately 10 identical items in List B. Any clues on how to solve this?

Thank you.

Yoshi

Dorrit Riemenschneider

Hello Yoshi, as funny as it sounds: I think you must have done something wrong.

Hello. That is a nce solution, however I can’t get it working with External Data column (that contains a reference to external content type). The text comun content is being copied, the external data column stays empty. Do you know if it is possible at all? Cheers.

Dorrit Riemenschneider

For External Data columns it has to possible, too. I think you had to verify whether it concerns an External Data column and if so, then put some code there referencing the external content type.

Danke!!!

Kommentar hinterlassen