0

So I wish to create a "Master list" that collates all the items of 5 other lists on my list.

My reason to do so is that I require people from different business units across the company to enter their data in a permission-secure list individually.

Each list would then feed their data into my "Masterl ist," every time a new item is entered - so I can get a high level view of the answered from each business unit.

I feel like this is easily possible through workflows - however due to my companys security rules, we have both sharepoint designer and workflows disabled. Along with the ability to edit java and html.

Thanks

3
  • Would you mind explaining a little as to why the 5 lists are separate? Mar 9, 2016 at 11:08
  • Each list requires seperate viewership permissions, so people from one business unit shouldn't be able to see submitted info from another business unit. As far as I know, I can't give seperate list views different permissions, so this would be my only solution
    – Michael
    Mar 9, 2016 at 11:12
  • There is no straightforward way but you can have permission based views. The solution is to use audience targeting feature. Take a look at this - social.technet.microsoft.com/Forums/office/en-US/… Mar 9, 2016 at 11:24

2 Answers 2

0

You could certainly create a workflow or an ItemAdded event receiver to copy your items from one list to another. But bear in mind that these would only take the items as they were at the time of creation, if anyone were to go back and make a subsequent edit, these changes would not be copied across. Unless of course you develop a workflow/ItemUpdate event receiver to cover this behaviour also.

0

I had the same requirement a while ago. Your best bet would be event receivers. Two in fact - ItemAdded and ItemUpdated. Define your list template in Visual Studio, add two event receivers:

<Receiver>
    <Name>ListItemAdded</Name>
    <Type>ItemAdded</Type>
    <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
    <Class>ListERClass</Class>
    <SequenceNumber>10000</SequenceNumber>
  </Receiver>
<Receiver>
  <Name>ListtemUpdated</Name>
  <Type>ItemUpdated</Type>
  <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
  <Class>ListERClass</Class>
  <SequenceNumber>10000</SequenceNumber>
</Receiver>

In your event receiver classes (or a single class), handle two events - ItemAdded and ItemUpdated. In an event when an item is added to the child list, you add a new item to your master list and when an item is updated in your child list, you update the master list item as well. What you would need to do, is a way to identify items when updating. In the master list I had a UniqueId column and I stored the master item ID in the child items's properties, that way it was easy to identify the item which needed to be updated.

Your ItemAdded should look something like this:

var masterList = web.GetList("MASTER_LIST_URL")
var masterItem = masterList.AddItem();
foreach (SPField f in masterList.Fields)
{
    CopyFieldValue(f, currentChildList, currentChildItem, masterList, masterItem);
}
masterItem ["WSGUID"] = currentItem.UniqueId; //to identify the item in case needs updating
masterItem.SystemUpdate(false);
base.EventFiringEnabled = false;
currentItem.Properties.Add("GlobalID", masterItem.ID); //save id of master item in child item's properties
currentItem.SystemUpdate(false);
base.EventFiringEnabled = true;

CopyFieldValue function:

private void CopyFieldValue(SPField f, SPList currentList, SPListItem currentItem, SPList globalList, SPListItem globalItem)
{
    try
    {
        if ((!f.ReadOnlyField
            && f.TypeAsString != "LookupMulti"
            && f.InternalName != "Attachments"
            && globalList.Fields.ContainsFieldWithStaticName(f.InternalName)))
            {
                if (!String.IsNullOrEmpty(currentItem[f.InternalName].ToStringIfNotNull()))
                {
                    globalItem[f.InternalName] = currentItem[f.InternalName];
                }
        }
    }
    catch (Exception ex)
    {
        //your exception handling goes here
    }
}

Your ItemUpdated should be something like this:

var masterList = web.GetList("MASTER_LIST_URL")
int masterItemID = Convert.ToInt32(currentItem.Properties["GlobalID"]);
var materItem = masterList.GetItemById(masterItemID);
foreach (SPField f in materItem .Fields)
{
    CopyFieldValue(f, currentList, currentItem, masterList , materItem );
}
materItem.SystemUpdate(false); //or .Update()

If you implement that, your master list will have all the items from child lists and your items will always be updated with the latest metadata. You can handle ItemDeleted event as well. Then you give users read only access to the master list OR do a two way synchronization.

As for the views, what I would suggest is to have a library with the .aspx files and custom item permissions where you would allow one group of people to access one kind of views (with the price column) and another group of people (who are not price-worthy) would have access to view files without the column in them. And then have a page where users would click on the view links. Other people achieve this by using audience targeting feature:

  1. Create view A, B, C for list TestList
  2. Create user group X, Y, Z
  3. Open the TestList, bu default all items will display in AllItems.aspx page
  4. Edit the page by using Site Action
  5. Click on the Modify Shared Web Part link of TestList . Now select the View A from selected dropdown
  6. Go to Advanced section and select user group in the target audience. Apply the changes
  7. Add the TestList web part again to the same AllItems.aspx page.
  8. Repeat the step 5 and 6 for other two views and set the target audience respectively.
  9. Now the AllItems.aspx page will have three web part for one list i.e TestList

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.