5

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();
                    }

                }
            }
        }

    }
7
  • You can check for each item before coping the items in the list B using CAML query or Linq. Commented Nov 25, 2016 at 9:27
  • @DikeshGandhi Can you show me the code please? Commented Nov 25, 2016 at 9:30
  • What is the unique information in list A? Based on that write your CAML query Commented Nov 25, 2016 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) Commented Nov 25, 2016 at 9:36
  • Yes you can do that. Then CAML is not needed. Commented Nov 25, 2016 at 9:40

5 Answers 5

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!

7
  • this is the code I posted the question I already have this code Commented Nov 25, 2016 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 Commented Nov 25, 2016 at 9:49
  • sourceItem does not exist in current context says the error Commented Nov 25, 2016 at 9:54
  • I have updated the code Commented Nov 25, 2016 at 9:55
  • Now It is not coping the list items anymore, why? Commented Nov 25, 2016 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;
    }

}  
}
5
  • OP will need a JavaScript compiler to execute your code!!! :) :) Edit your answer Commented Nov 25, 2016 at 9:54
  • DoesItemExist does not exist in current context Commented Nov 25, 2016 at 10:06
  • @AtishDipongkor... :) habit of writing client side code :P Commented Nov 25, 2016 at 10:20
  • Yup!! I guessed so. Commented Nov 25, 2016 at 10:21
  • @NderonHyseni...edited, though please make sure from your side that it syntax wise correct....I have given rough idea.... Commented Nov 25, 2016 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();
                        }



                    }
                }
            }
        }
1
  • 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. Commented Nov 25, 2016 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 and acknowledge you have read our privacy policy.

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