Forum Discussion

Will-Painter's avatar
Will-Painter
Copper Contributor
Nov 10, 2024

How to extract the value of RBS in Enterprise Resource in Project Server 2019?

I try to retrieve the value of RBS in Enterprise Resource in Project Server by using C#/ CSOM. Unfortunately, I just got the Resource Name, as for the value of RBS, I always cannot extract any value from this field. Sometimes, the value of RBS is wrong or the same. I shared the code for you to look at and hope the seasoned people can help me to address it or sharing some idea in this. I appreciate your help. Thanks.

Explanation:

  1. The Enterprise Resources will be extracted by ID.
  2. "projectContext" will load specificRes with all Custom Fields.
  3. I'm going to retrieve the value of a specific field (RBS)
  4. Finally, When I specify to retrieve the value of "RBS", no matter how I change the Resource Id, the value of RBS is the same

Is there any idea on this issue? Thanks for everyone's help.

 

var specificRes = projectContext.EnterpriseResources.GetById(new Guid("46914ae8-3c55-488d-a045-4d1a5aaf1e74").ToString());

projectContext.Load(specificRes, r => r.Name, r => r.CustomFields, r => r.CustomFields.IncludeWithDefaultProperties( lu => lu.LookupTable, lu => lu.LookupEntries));

projectContext.ExecuteQuery();

var cusField = specificRes.CustomFields.FirstOrDefault(cf => cf.InternalName == "Custom_000039b78bbe4ceb82c4fa8c0c400284");

 projectContext.Load(cusField); projectContext.ExecuteQuery();

Console.WriteLine(cusField.LookupEntries.First().FullValue);

  • Mks_1973's avatar
    Mks_1973
    Iron Contributor

    Custom_000039b78bbe4ceb82c4fa8c0c400284 is indeed the correct internal name for the RBS field. You can verify the exact internal name in the Project Server's Enterprise Custom Fields section.

    RBS is typically a hierarchical field with lookup table values, ensure that you're correctly fetching and parsing these values.

    There might be cases where the custom field has no value. Add checks to handle such cases.

    Revised code for improve reliability:

    // Retrieve the Enterprise Resource by ID
    var specificRes = projectContext.EnterpriseResources.GetById(new Guid("46914ae8-3c55-488d-a045-4d1a5aaf1e74"));

    // Load relevant properties
    projectContext.Load(specificRes, r => r.Name, r => r.CustomFields, r => r.CustomFields.IncludeWithDefaultProperties(cf => cf.LookupTable, cf => cf.LookupEntries));
    projectContext.ExecuteQuery();

    // Locate the RBS custom field by its internal name
    var rbsField = specificRes.CustomFields.FirstOrDefault(cf => cf.InternalName == "Custom_000039b78bbe4ceb82c4fa8c0c400284");

    // Ensure the field exists and contains lookup entries
    if (rbsField != null && rbsField.LookupEntries.Any())
    {
        // Retrieve the full hierarchical path for RBS
        var rbsValue = string.Join(" > ", rbsField.LookupEntries.Select(le => le.FullValue));
        Console.WriteLine($"RBS for Resource '{specificRes.Name}': {rbsValue}");
    }
    else
    {
        Console.WriteLine($"RBS field is not set or has no lookup entries for Resource '{specificRes.Name}'.");
    }


    =========================

    string.Join = This code concatenates all LookupEntries to show the hierarchical path if there are multiple levels in RBS. Each LookupEntry represents a level in the RBS hierarchy, and FullValue provides the hierarchical value for that level.

    the code check if rbsField is null and if LookupEntries contains any data before attempting to retrieve and display it

    ExecuteQuery  = is called after loading the resource data, and not again after loading cusField. This reduces the chance of unnecessary network calls and potential misalignments in data fetching



    Also ensure that the user or application context has the correct permissions to access custom fields, especially hierarchical fields like RBS.

    Test your code with resources where you know the expected RBS values to verify if they are being retrieved correctly.


    I hope this will fix your issue, but if the RBS field still returns unexpected values, verify that there are no issues with the lookup table configuration on the server side.

    • Wei-Painter's avatar
      Wei-Painter
      Copper Contributor

      Hi Mks_1973,

      // Retrieve the full hierarchical path for RBS
          var rbsValue = string.Join(" > ", rbsField.LookupEntries.Select(le => le.FullValue));

      I just tried it, and I can indeed get all hierarchical path for RBS. Is there a way to retrieve the RBS information related to a specific user?

      Thanks - I am new player so I have a lot of questions

      • Mks_1973's avatar
        Mks_1973
        Iron Contributor

        Yes, you can retrieve the RBS (Resource Breakdown Structure) information specific to a user by filtering based on the user’s resource ID or their specific criteria in the query. 


        Here's how you can get the RBS value for a specific user:

        // Assuming you have the context and have authenticated
        var projectContext = new ProjectContext("https://your-project-server-url/");

        // Replace with the user's resource ID
        Guid resourceId = new Guid("your-specific-resource-id");

        // Retrieve the specific resource by ID
        EnterpriseResource specificResource = projectContext.EnterpriseResources.GetById(resourceId);

        // Load the resource with custom fields (including RBS)
        projectContext.Load(specificResource, 
            r => r.CustomFields.Include(cf => cf.InternalName, cf => cf.LookupEntries, cf => cf.Value));
        projectContext.ExecuteQuery();

        // Now, retrieve the RBS field
        var rbsField = specificResource.CustomFields.FirstOrDefault(cf => cf.InternalName == "Custom_RBS_Field_Internal_Name");

        // If the RBS field exists, retrieve its full hierarchical path
        if (rbsField != null && rbsField.LookupEntries != null)
        {
            string rbsValue = string.Join(" > ", rbsField.LookupEntries.Select(le => le.FullValue));
            Console.WriteLine("RBS for the specified user: " + rbsValue);
        }
        else
        {
            Console.WriteLine("RBS information not found for the specified user.");
        }

        ======================

        Replace "your-specific-resource-id" with the actual resource ID for the user you're interested in.
        Replace "Custom_RBS_Field_Internal_Name" with the actual internal name for the RBS custom field in your Project Server instance.


        Check if the resource has an RBS assigned. If rbsField.LookupEntries is null or empty, the user might not have an RBS assigned.

Resources