6

I have created an event receiver that runs when item is added. The code copies list item from list A to list B;

It is working wonderful but I have a problem, if list A has 10 items, all of those 10 items are being copied to list B. Now if I add an item to List A (which means that now list A has 11 items) in List B are going to be copied again all 11 items (which means that now list B has 21 items)

How Can I check if in List B already exists items that are in List A

Here is my code:

  public override void ItemAdded(SPItemEventProperties properties)
    {
        base.ItemAdded(properties);

        using (SPSite site = new SPSite("http://MyWeb/sites/mysite/"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPList sourceList = web.Lists.TryGetList("A");
                foreach (SPListItem sourceItem in sourceList.Items)
                {
                    SPList desList = web.Lists.TryGetList("B");
                    if (desList != null)
                    {
                        SPListItem desItem = desList.Items.Add();
                        foreach (SPField field in sourceItem.Fields)
                        {
                            if (!field.ReadOnlyField && !field.Hidden && field.InternalName != "Attachments")
                            {
                                if (desItem.Fields.ContainsField(field.InternalName))
                                {
                                    desItem[field.InternalName] = sourceItem[field.InternalName];

                                }

                            }
                        }
                        desItem.Update();
                    }

                }
            }
        }

    }
  • You can check for each item before coping the items in the list B using CAML query or Linq. – Dikesh Gandhi Nov 25 '16 at 9:27
  • @DikeshGandhi Can you show me the code please? – Nderon Hyseni Nov 25 '16 at 9:30
  • What is the unique information in list A? Based on that write your CAML query – Atish Dipongkor - MVP Nov 25 '16 at 9:32
  • List A has unique ID in List B there is a filed called listA:ID now I have to check if (listA:ID != with the Unique ID in list A) – Nderon Hyseni Nov 25 '16 at 9:36
  • Yes you can do that. Then CAML is not needed. – Atish Dipongkor - MVP Nov 25 '16 at 9:40
5

Put this below code in List A event receiver. This method will copy only current item to List B that you add in the List A.

Code:

public override void ItemAdded(SPItemEventProperties properties)
{
    base.ItemAdded(properties);

    using (SPSite site = new SPSite("http://MyWeb/sites/mysite/"))
    {
        using (SPWeb web = site.OpenWeb())
        {                
            SPList desList = web.Lists.TryGetList("B");
            if (desList != null)
            {
                SPListItem desItem = desList.Items.Add();
                foreach (SPField field in properties.ListItem.Fields)
                {
                    if (!field.ReadOnlyField && !field.Hidden && field.InternalName != "Attachments")
                    {
                        if (desItem.Fields.ContainsField(field.InternalName))
                        {
                            desItem[field.InternalName] = properties.ListItem[field.InternalName];

                        }

                    }
                }
                desItem.Update();
            }
        }
    }

}

This method will copy the list item from List A to List B after you add list item to List A.

Hope this will help you!

  • this is the code I posted the question I already have this code – Nderon Hyseni Nov 25 '16 at 9:43
  • Please check it carefully, before minus marking it. Your code is coping all data every time you enter item in the list. My edited code copy only that data that you add in list A and it will copy only that 1 item to the list B – Dikesh Gandhi Nov 25 '16 at 9:49
  • sourceItem does not exist in current context says the error – Nderon Hyseni Nov 25 '16 at 9:54
  • I have updated the code – Dikesh Gandhi Nov 25 '16 at 9:55
  • Now It is not coping the list items anymore, why? – Nderon Hyseni Nov 25 '16 at 10:04
2

Assuming field listA:ID is a number field, then you could add a method to check the existence of list items using CAML Query.

public override void ItemAdded(SPItemEventProperties properties)
{
    base.ItemAdded(properties);

    using (SPSite site = new SPSite("http://MyWeb/sites/mysite/"))
    {
        using (SPWeb web = site.OpenWeb())
        {
            SPList sourceList = web.Lists.TryGetList("A");
            foreach (SPListItem sourceItem in sourceList.Items)
            {
                SPList desList = web.Lists.TryGetList("B");
                if (desList != null)
                {
                    if(!ItemExists(sourceItem, "B"))
                    {
                    SPListItem desItem = desList.Items.Add();
                    foreach (SPField field in sourceItem.Fields)
                    {
                        if (!field.ReadOnlyField && !field.Hidden && field.InternalName != "Attachments")
                        {
                            if (desItem.Fields.ContainsField(field.InternalName))
                            {
                                desItem[field.InternalName] = sourceItem[field.InternalName];

                            }

                        }
                    }
                    desItem.Update();
                    }
                }

            }
        }
    }

}

private bool ItemExists(SPListItem sourceItem, string destListName)
{
    bool itemExists = false;
    using (SPSite site = new SPSite(SPContext.Current.Web.Url))
    {
        using (SPWeb web = site.OpenWeb())
        {
            SPList destList = web.Lists[destListName];
            SPQuery query = new SPQuery();
            query.Query = @"<Where><Eq><FieldRef Name='listA:ID' /><Value Type='Number'>"+ sourceItem.ID +@"</Value></Eq></Where>";
            SPListItemCollection destListItems = destList.GetItems(query);

            if (destListItems.Count > 0)
                itemExists = true;
        }
    }
    return itemExists;
}
2

You need to have a Column which will have unique values. You can use this column to compare before inserting data in List B. Below is pseudo code based on your code...

public override void ItemAdded(SPItemEventProperties properties)
        {
            base.ItemAdded(properties);

            using (SPSite site = new SPSite("http://MyWeb/sites/mysite/"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPList sourceList = web.Lists.TryGetList("A");
                    SPList desList = web.Lists.TryGetList("B"); // MODIFIED THIS. you dont need to call destlist for each item in source list
                    foreach (SPListItem sourceItem in sourceList.Items)
                    {
                        if(!DoesItemExist(desList,sourceItem["ID"])){
                        if (desList != null)
                        {
                            SPListItem desItem = desList.Items.Add();
                            foreach (SPField field in sourceItem.Fields)
                            {
                                if (!field.ReadOnlyField && !field.Hidden && field.InternalName != "Attachments")
                                {
                                    if (desItem.Fields.ContainsField(field.InternalName))
                                    {
                                        desItem[field.InternalName] = sourceItem[field.InternalName];

                                    }

                                }
                            }
                            desItem.Update();
                        }
                        }
                    }
                }
            }

        }

public bool DoesItemExist(SPList desList, string valueToCompare){

foreach (SPListItem item in desListItems)
{
    if(item["listA:ID"] == valueToCompare)
    {
        return true;
    }

}  
}
  • OP will need a JavaScript compiler to execute your code!!! :) :) Edit your answer – Atish Dipongkor - MVP Nov 25 '16 at 9:54
  • DoesItemExist does not exist in current context – Nderon Hyseni Nov 25 '16 at 10:06
  • @AtishDipongkor... :) habit of writing client side code :P – Siddharth Vaghasia Nov 25 '16 at 10:20
  • Yup!! I guessed so. – Atish Dipongkor - MVP Nov 25 '16 at 10:21
  • @NderonHyseni...edited, though please make sure from your side that it syntax wise correct....I have given rough idea.... – Siddharth Vaghasia Nov 25 '16 at 10:21
2

NOW IT IS WORKING PERFECT, HOWEVER THANKS TO ALL OF YOU, YOU ALL HELP ME TO COME WITH THIS CODE

using (SPSite site = new SPSite("http://myweb/sites/mysite/"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPList sourceList = web.Lists.TryGetList("A");
                SPList desList = web.Lists.TryGetList("B");

                foreach (SPListItem sourceItem in sourceList.Items)
                {

                    if (desList != null)
                    {
                        SPQuery query = new SPQuery();
                        query.Query = @"
                                    <Where><Eq>
                                                <FieldRef Name='formID' />
                                                <Value Type='Number'>" + sourceItem["ID"] + @"</Value>
                                    </Eq></Where>";

                        SPListItemCollection items = desList.GetItems(query);

                        if (items.Count <= 0)
                        {

                            SPListItem desItem = desList.Items.Add();

                            foreach (SPField field in sourceItem.Fields)
                            {
                                if (!field.ReadOnlyField && !field.Hidden && field.InternalName != "Attachments")
                                {

                                    if (desItem.Fields.ContainsField(field.InternalName))
                                    {

                                        desItem[field.InternalName] = sourceItem[field.InternalName];
                                        desItem["formID"] = sourceItem["ID"];

                                    }

                                }


                            }
                            desItem.Update();
                        }



                    }
                }
            }
        }
  • Hi Nderson, though it will work correctly, but also check performance of your code. you are executing query for each item in your source list. – Siddharth Vaghasia Nov 25 '16 at 10:24
2

You should have a unique key to identify your item. Ideally this would be a number or something like that, so you can identify the item in the second list. In your example, you don't have an ID. So you could add one or you could just compare the item with the text (I suppose it will be the title field)

When the item is being added in the list you can then in the "ItemAdding" check with an SPQuery if the item already exists in the list (enough examples to find online). If query returns 0 items, you can just let SharePoint do it's work as it normally should.

Now you can get the items collection of the sourcelist by using caml query and then need to check against the destination list by looping against it.

  public override void ItemAdding(SPItemEventProperties properties)
     {
                    SPWeb web = properties.Web;
                    SPList list = properties.List;
                    string title = properties.AfterProperties["Title"].ToString();
                    string strQuery = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + title  + "</Value></Eq></Where>";
                    SPQuery query = new SPQuery();
                    query.Query = strQuery;
                    SPListItemCollection listItem = list.GetItems(query);
                    if (listItem.Count > 0)
                    {
                         properties.Cancel = true;
                         properties.ErrorMessage = "The item exsists already in list!";
                    }
     }

To avoid that the item is being added when it already is in the list you can use following code.

properties.Cancel = true;
properties.Status = SPEventReceiverStatus.CancelNoError

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.