none
Forcing Project in/out of Portfolio Analysis through PSI RRS feed

  • Question

  • Hello,

    I haven't had a chance to test this out myself yet, so I was wondering if anyone else has dealt with this before, namely forcing project out or in of portfolio analysis by using PA web service methods.  Questions I have are:

    1. Would setting Force_Status property to either 0 or 1 do the trick?  The property is public, so one should be able to modify it, although I'm not sure if it actually changes the value in the DB.  Possibly calling QueueUpdateAnalysis method after changing the property would help?
    2. If the above property cannot be changed from the outside code, would setting the Status column to Null do the trick?  There is a setSTATUSNull() method or something similar sounding.
    3. An alternative would be removing projectsSolutions row, but that's not really forcing a project out, it's completely removing it from the analysis.  Also, I was wondering, is it enough to just call this method?  Will it remove all the necessary associations in other analysis tables?
    4. What about forcing project out of the resource planner?  Same as above?  Or forcing/removing the project from cost analysis would automatically force/remove it from planner?
    5. Is QueueUpdateAnalysis call required with any of the above modifications?

    Will probably be testing this next week, however, wanted to see if anyone knows what the correct process is.

    Thanks,
    Ilya

    Friday, October 21, 2011 6:19 PM

Answers

  • Had it figured out for a while, but no time to post.  It is, after all, possible, but I would not recommend doing this unless you absolutely have to.  Here are some potenital problems with doing this:

    1. When forcing out a project, you probably want it forced out from the last commited solution (forcing it out from all solutions that contain it is not a problem).  The reason is that there are no methods that will tell you whether the solution you are working with is a committed one or not.  The table that holds this information is called MSP_PROJECT_ANALYSES_RESULTS and there is also a reporting view called MSP_EpmProjectCommit, however no PSI methods (at least I haven't found any) give you access to this information.  So you are going to have to query the DB directly, which I like to avoid doing when I can.  Note: project server will delete any previously committed rows from this table/view; only the most current ones are kept.  So you can be sure that the SolutionUid that you get from this table/view points to the last committed solution.
    2. Forcing a project out means creating a new optimizer solution.  If you had 20 projects in a given solution governed by 20 workflows, and, say, 15 of those workflows would instruct to force its corresponding project out, then 15 new solutions are going to have to be created within a given analysis, unless somehow you can obtain the list of projects that need to be forced out and a check if they haven't been already forced out, which is almost impossible to have, given the sequential nature of workflows.  So you would end up with lots of solution "clutter" in this case.
    3. When creating a new optimizer solution, you have to make sure that you are not losing any information contained in previously committed solution, which essentially means copying all solution-related tables into your new solution data set.  Also you have to be cautious that you are copying over the right solution, i.e: if you had 10 solutions and were creating an 11th one, and the committed solution is Solution 7, then you probably wouldn't want Solution 2's cost constraint and strategic alignment data to go into the new data set.  Properly designed loops should be able to control this, or, if you are querying a DB directly for one single committed solution UID, then you don't have to worry about this.

    With this said, here is the procedure for forcing the project out:

    1. Determine how you are going to get your optimizer solution UIDs: querying the DB directly or using ReadOptimizerSolutionList(analysisUid) method.  In the second case you may want to check if the project you are looking at is even a part of a given analysis, otherwise you don't need to iterate through all the solutions and skip to the next analysis.
    2. Read the solution by using ReadOptimizerSolution(solutionUid)
    3. Locate the proper row in the solutionDataSet.SolutionProjects table, by using FindBySolution_UIDPROJ_UID method
    4. Set Force_Status to "Force Out" (use (byte)Optimizer.ForceStatus.ForceOut)
    5. Create a new optimizer solution.  Note: you MUST create a new solution with new solution GUID and manually copy over the table data from the old data set by using NewSolutionRow(), AddSolutionRow, and other appropriate methods for the other tables inside the data set.  The minimum tables you need to have are: Solution, SolutionProjects, SolutionConstraints, SolutionConstraintsValues.
    6. After a new solution is created, it is up to you whether to commit the new solution or not (use CommitOptmizerSolution to achieve that)

    Hope this helps someone!

    Ilya

    • Marked as answer by Rockmus Monday, November 14, 2011 7:33 PM
    Monday, November 14, 2011 7:33 PM

All replies

  • Well, I've tried everything I could think of and nothing worked unfortunately.

    1. Seems like QueueUpdateAnalysis is irrelevant in this case because, as I understand, it updates changes on a higher (analysis) level and not at the SolutionProject level.  The only table available in AnalysisDataSet object that relates to the Optimizer is AnalysisOptimizerSolutions which is also a higher-level table, changes to which won't affect projects within a given solution (scenario).
    2. Tried to remove a corresponding row in AnalysisProjects table within the AnalysisDataSet, ran QueueUpdateAnalysis, job comleted successfully, but the project is still part of the scenario.  I know you can't add/delete projects (even manually) when you have scenarios in your analysis, but I tried doing it without any scenarios and it still didn't update anything.  Looks like QueueUpdateAnalysis omits this table when updating.
    3. Unfortunately there's no QueueUpdateOptimizerSolution method, so here's what I tried instead:

      -- For a given analysis
          -- Get all the solutions/scenarios within the analysis (used ReadOptimizerSolution method)
              -- Iterate through SolutionProjects table for a given Solution
                 -- If the desired project is found within a Solution, then set FORCE_STATUS to 1 on that SolutionProjects row
                 -- row.AcceptChanges()
                 -- Delete entire optimizer solution
                 -- Create a new optimizer solution with exact same solution Data Set which was just deleted and in which I've changed FORCE_STATUS

      Outcome: if row.AcceptChanges() is present than the error is CannotCalculateStrategicAlignment, otherwise it's GeneralOnlyInsertsAllowed.

      Beats me why you can't create a brand new solution with a data set that you've just read.  The only difference between the two is the changed FORCE_STATUS on a project.

      COME ON, MICROSOFT GUYS, TELL ME WHAT YOUR CODE DOES AND DOESN'T DO!!!  

      Not like you use different set of methods to accomplish forcing in/out when done manually.  What happens when the user manually forces the project in/out?  Event raised?  Which methods called to handle and in what sequence?  One of you, moderators, must know this.  Or tell me it can only be done manually and my mind will rest.

      Respectfully,
      Ilya
                

     

     

    Wednesday, October 26, 2011 5:52 PM
  • Had it figured out for a while, but no time to post.  It is, after all, possible, but I would not recommend doing this unless you absolutely have to.  Here are some potenital problems with doing this:

    1. When forcing out a project, you probably want it forced out from the last commited solution (forcing it out from all solutions that contain it is not a problem).  The reason is that there are no methods that will tell you whether the solution you are working with is a committed one or not.  The table that holds this information is called MSP_PROJECT_ANALYSES_RESULTS and there is also a reporting view called MSP_EpmProjectCommit, however no PSI methods (at least I haven't found any) give you access to this information.  So you are going to have to query the DB directly, which I like to avoid doing when I can.  Note: project server will delete any previously committed rows from this table/view; only the most current ones are kept.  So you can be sure that the SolutionUid that you get from this table/view points to the last committed solution.
    2. Forcing a project out means creating a new optimizer solution.  If you had 20 projects in a given solution governed by 20 workflows, and, say, 15 of those workflows would instruct to force its corresponding project out, then 15 new solutions are going to have to be created within a given analysis, unless somehow you can obtain the list of projects that need to be forced out and a check if they haven't been already forced out, which is almost impossible to have, given the sequential nature of workflows.  So you would end up with lots of solution "clutter" in this case.
    3. When creating a new optimizer solution, you have to make sure that you are not losing any information contained in previously committed solution, which essentially means copying all solution-related tables into your new solution data set.  Also you have to be cautious that you are copying over the right solution, i.e: if you had 10 solutions and were creating an 11th one, and the committed solution is Solution 7, then you probably wouldn't want Solution 2's cost constraint and strategic alignment data to go into the new data set.  Properly designed loops should be able to control this, or, if you are querying a DB directly for one single committed solution UID, then you don't have to worry about this.

    With this said, here is the procedure for forcing the project out:

    1. Determine how you are going to get your optimizer solution UIDs: querying the DB directly or using ReadOptimizerSolutionList(analysisUid) method.  In the second case you may want to check if the project you are looking at is even a part of a given analysis, otherwise you don't need to iterate through all the solutions and skip to the next analysis.
    2. Read the solution by using ReadOptimizerSolution(solutionUid)
    3. Locate the proper row in the solutionDataSet.SolutionProjects table, by using FindBySolution_UIDPROJ_UID method
    4. Set Force_Status to "Force Out" (use (byte)Optimizer.ForceStatus.ForceOut)
    5. Create a new optimizer solution.  Note: you MUST create a new solution with new solution GUID and manually copy over the table data from the old data set by using NewSolutionRow(), AddSolutionRow, and other appropriate methods for the other tables inside the data set.  The minimum tables you need to have are: Solution, SolutionProjects, SolutionConstraints, SolutionConstraintsValues.
    6. After a new solution is created, it is up to you whether to commit the new solution or not (use CommitOptmizerSolution to achieve that)

    Hope this helps someone!

    Ilya

    • Marked as answer by Rockmus Monday, November 14, 2011 7:33 PM
    Monday, November 14, 2011 7:33 PM