c# - jsom - copiar elementos de la lista de una lista a otra en sharepoint
sharepoint sdk client (11)
En Sharepoint, ¿cómo se puede copiar un elemento de la lista de una lista a otra, por ejemplo, copiar de "Lista A" a "Lista B" (ambos están en la raíz del sitio)
Quiero que esta copia se produzca cuando se agrega un nuevo elemento de lista a "Lista A"
Traté de usar el método CopyTo () de un SPListItem dentro del receptor del evento ItemAdded, pero no pude encontrar la URL a la que copiar.
Aquí está el código que uso. Pase un SPlistItem y el nombre de la lista de destinos como se ve en Sharepoint (No la URL). La única restricción es que ambas listas deben estar en el mismo sitio:
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;
}
Aquí hay un equivalente de Powershell de Sylvian que permite la copia entre sitios. Su código podría ser modificado de manera similar también ...
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();
}
Para usar, copiar y pasar a un archivo copy-listitems.ps1 y ejecutar usando la línea de comandos de Sharpoint powerhsell ...
Asegúrese de llamar al método CopyTo (url) en SPFile, no en SPListItem. por ejemplo:
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);
//...
}
Cómo copiar el campo y guardar versiones:
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;
}
}
Copiar y mover archivos, elementos y carpetas en SharePoint puede ser complicado si desea conservar todos los metadatos, las marcas de tiempo, la información del autor y el historial de versiones. Eche un vistazo a CopyMove para SharePoint , también tiene una API de servicio web.
Copie los elementos de la lista de una lista o biblioteca de SharePoint a otra lista o biblioteca de SharePoint usando el código del lado del servidor c #
// Itecollection es una colección de datos de la lista fuente
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");
}
}
}
}
De hecho, como dijo Lars, puede ser complicado mover elementos y conservar versiones y corregir la información de usuario. He hecho cosas similares con eso antes, así que si necesita algunos ejemplos de código, hágamelo saber a través de un comentario y puede proporcionarle alguna orientación.
El método CopyTo (si decides ir con eso) necesita un Uri absoluto como: http: //host/site/web/list/filename.doc
Por lo tanto, si está realizando esto en un receptor de eventos, necesita concatenar una cadena que contenga los elementos necesarios. Algo así como (tenga en cuenta que esto se puede hacer de otras maneras):
string dest=
siteCollection.Url + "/" + site.Name + list.Name + item.File.Name;
Entonces, ¿las listas tienen exactamente las mismas columnas o columnas similares? De cualquier manera, puede crear un flujo de trabajo simple que se ejecute automáticamente cuando se crea un elemento en "Lista A". Como el flujo de trabajo en cuestión es relativamente simple, recomendaría usar SharePoint Designer (que es gratis) para crearlo, ya que puede hacer coincidir fácilmente las columnas de las dos listas. El recorrido a continuación debería ser capaz de ayudarlo a comenzar.
Hay muchas herramientas en el mercado para copiar un elemento de la lista a otra lista (avepoint, metavis, etc.) pero son bastante costosas si planea hacer esto solo en una lista.
Si puede hacerlo manualmente una vez a la semana, por ejemplo, mire la siguiente herramienta: http://en.share-gate.com/sharepoint-tools/copy-move-sharepoint-list-items-with-metadata-and- historial de versiones
Yo tuve el mismo problema.
Después de experimentar un poco en lugar de
targetItem[f.InternalName] = sourceItem[f.InternalName];
Solía:
targetItem[childField.Title] = sourceItem[parentField.Title];
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();
}
}
No olvide agregar esta línea, tgtItem.Update();
De lo contrario, obtendrás un error.