PROJECT SERVER 2007. EL TRABAJO DE REPORTING (PROJECT PUBLISH) NO TERMINA CORRECTAMENTE, Y APARECE UN ERROR EN LA COLA.

Buenas,

Como “no hay dos sin tres”, este mes tendremos otra traducción (la tercera del mes de Mayo) de otro excelente post que ha escrito Brian Smith en su blog, y nos ha parecido necesario traducir el idioma principal de este blog. El artículo original se puede encontrar aquí:

https://blogs.msdn.com/b/brismith/archive/2012/05/23/project-server-2007-reporting-project-publish-queue-job-fails-to-complete.aspx

La traducción es la siguiente:

“Estamos ante un problema que alguno de mis lectores nos hicieron llegar, respondiendo al post que hablaba de las bases línea huérfanas, de hace un par de semanas, y sabemos que se trata de algo que cada vez más clientes se están encontrando. El problema fue introducido con la actualización acumulativa de Febrero de 2007 para Project Server 2007, y también estaba presente en la de Abril, así que si habéis instalado cualquiera de ellas, y habéis empezado a ver este tipo de trabajos (Reporting (Project Publish)) fallando en la cola, este post os puede resultar interesante…

Los síntomas indican que un proyecto pueda ser guardado y publicado correctamente, pero el trabajo asociado al publicación del proyecto (Reporting (Project Publish)) no acaba de terminar correctamente, y nos aparecerá un error parecido a este (la información posterior está truncada, pero la parte ReportingProjectChangeMessageFailed aparecerá repetida, dependiendo en el valor configurado en la cola, relativo al límite de repeticiones):

Error summary/areas:
Reporting message processor failed
ReportingProjectChangeMessageFailed
Queue
GeneralQueueJobFailed
Error details:

<?xml version="1.0" encoding="utf-16"?>
<errinfo>
<general>
<class name="Reporting message processor failed">
<error id="24006" name="ReportingProjectChangeMessageFailed" uid="d120becb-26a3-4fbe-8341-38a5c273453d" QueueMessageBody="Project UID='0b9e52ec-6bb6-4ca3-823b-d7561d821d1c'. PublishType='ProjectPublish'" Error="Object reference not set to an instance of an object." />
</class>
<class name="Queue">
<error id="26000" name="GeneralQueueJobFailed" uid="4c6270ce-0735-44b3-ac1c-59bb0ff69efc" JobUID="a4a1f651-0997-4770-8099-efe02340967a" ComputerName="BRISMITH2007" GroupType="ReportingProjectPublish" MessageType="ReportProjectPublishMessageEx" MessageId="1" Stage="" />
</class>
</general>
</errinfo>

El problema ocurre porque no encontramos una verificación de un NULL al acceder el costo de una tarea en la línea base, de tal manera que si es NULL nos encontramos con mensaje “Object reference not set to an instance of an object”. Estamos trabajando en un hotfix que corrija este comportamiento, pero también tenemos una manera de solucionar esto, que pueda darnos al menos, un poco de alivio. Se trata de una macro que pueda ser ejecutada en un proyecto afectado, la cual pondrá un cero (NO NULO) en un costo fijo en la asignación de la línea base, en lugar del NULL que nos está poniendo la zancadilla. Más abajo está el código de la macro que será necesario añadir al cliente de Project, en el editor de macros, y ejecutarla en el proyecto.

 

DESCARGA DE RESPONSABILIDAD:

Como con cualquier código de macros, debieras revisar y entender  exactamente qué es lo que hace ésta, y estar seguro de ejecutarla en tus proyectos (y leer el descargo de responsabilidad.) También debieras realizar esto primero en un entorno de pruebas. Sería altamente recomendable que realizaras una copia de seguridad administativa en tu sistema de producción, además de las copias de seguridad de las bases de datos. También es recomendable mencionar en este punto que debieras tener configurado el número de copias de seguridad administrativa de proyectos, que te den varias versiones de tu proyecto, en Configuración del servidor \ Administración de bases de datos \ Copia de seguridad programada.

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

'DISCLAIMER OF WARRANTY
'
'THIS FIX CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
'MICROSOFT FURTHER DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING WITHOUT
'LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS
'FOR A PARTICULAR PURPOSE. THE ENTIRE RISK ARISING OUT OF THE USE OR
'PERFORMANCE OF THE CODE REMAINS WITH YOU.
'
'IN NO EVENT SHALL MICROSOFT OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES
'WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF
'BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION,
'OR OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE
'THIS MACRO, EVEN IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF
'SUCH DAMAGES. BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR
'LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE
'ABOVE LIMITATION MAY NOT APPLY TO YOU.

 

'This macro attempts to work around the reporting publish failure that occurs when there are tasks
'with baselines and where the BaselineCost contour is NULL. The symptoms that you see in the queue
'for the "Reporting (Project Publish)" job has details similar to:
'
'<class name="Reporting message processor failed">
'<error id="24006" name="ReportingProjectChangeMessageFailed"
'uid="c72e20a7-9b7f-487b-9da2-19460b2e6c32"
'QueueMessageBody="Project UID='8e074f24-1064-47dd-bce5-c2dad8d556c8'.
'PublishType='ProjectPublish'" Error="Object reference not set to an instance of an object." />

'This code simply walks through the tasks in the tasks in the project and if there are
'baseline(s) set, then the code sets a time scaled baseline cost = 0 on the day prior to
'where the baseline start is scheduled.  This sets the baseline contour so that the
'"Object reference not set to an instance of an object" problem can be overcome during the
'reporting publish job.

Sub FixPublish()

Dim t As Tasks
Dim tsv As TimeScaleValues
Dim i As Long
Dim bCalc As Boolean

On Error Resume Next

'get the current application calculation state
bCalc = Application.Calculation
'set calculation to manual (helps with performance while the code runs)
Application.Calculation = pjManual

Set t = ActiveProject.Tasks

'walk through the tasks in the project. If a task as a baseline(s) then set a timescaled baselinecost = 0
For i = 1 To t.Count
    If Not t(i) Is Nothing Then
        If t(i).BaselineStart <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).BaselineStart - 1, t(i).BaselineStart - 1, pjTaskTimescaledBaselineCost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline1Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline1Start - 1, t(i).Baseline1Start - 1, pjTaskTimescaledBaseline1Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline2Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline2Start - 1, t(i).Baseline2Start - 1, pjTaskTimescaledBaseline2Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline3Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline3Start - 1, t(i).Baseline3Start - 1, pjTaskTimescaledBaseline3Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline4Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline4Start - 1, t(i).Baseline4Start - 1, pjTaskTimescaledBaseline4Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline5Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline5Start - 1, t(i).Baseline5Start - 1, pjTaskTimescaledBaseline5Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline6Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline6Start - 1, t(i).Baseline6Start - 1, pjTaskTimescaledBaseline6Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline7Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline7Start - 1, t(i).Baseline7Start - 1, pjTaskTimescaledBaseline7Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline8Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline8Start - 1, t(i).Baseline8Start - 1, pjTaskTimescaledBaseline8Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline9Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline9Start - 1, t(i).Baseline9Start - 1, pjTaskTimescaledBaseline9Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
        If t(i).Baseline10Start <> "NA" Then
            Set tsv = t(i).TimeScaleData(t(i).Baseline10Start - 1, t(i).Baseline10Start - 1, pjTaskTimescaledBaseline10Cost, pjTimescaleDays)
            If tsv(1).Value = "" Then
                tsv(1).Value = 0
            End If
        End If
    End If
Next

'fix the project summary task
With ActiveProject.ProjectSummaryTask
    If .BaselineStart <> "NA" Then
        Set tsv = .TimeScaleData(.BaselineStart - 1, .BaselineStart - 1, pjTaskTimescaledBaselineCost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline1Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline1Start - 1, .Baseline1Start - 1, pjTaskTimescaledBaseline1Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline2Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline2Start - 1, .Baseline2Start - 1, pjTaskTimescaledBaseline2Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline3Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline3Start - 1, .Baseline3Start - 1, pjTaskTimescaledBaseline3Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline4Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline4Start - 1, .Baseline4Start - 1, pjTaskTimescaledBaseline4Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline5Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline5Start - 1, .Baseline5Start - 1, pjTaskTimescaledBaseline5Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline6Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline6Start - 1, .Baseline6Start - 1, pjTaskTimescaledBaseline6Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline7Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline7Start - 1, .Baseline7Start - 1, pjTaskTimescaledBaseline7Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline8Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline8Start - 1, .Baseline8Start - 1, pjTaskTimescaledBaseline8Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline9Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline9Start - 1, .Baseline9Start - 1, pjTaskTimescaledBaseline9Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
    If .Baseline10Start <> "NA" Then
        Set tsv = .TimeScaleData(.Baseline10Start - 1, .Baseline10Start - 1, pjTaskTimescaledBaseline10Cost, pjTimescaleDays)
        If tsv(1).Value = "" Then
            tsv(1).Value = 0
        End If
    End If
End With
           
'set the application calculation state back the way it was
Application.Calculation = bCalc
           
End Sub

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Para usar esta macro debemos seguir los pasos siguientes:

01.- Abrir Project Professional 2007, y conectar contra el PWA donde estamos teniendo los problemas

02.- Ir a Herramientas \ Macro \ Seguridad

03.- Atención al Nivel de Seguridad

04.- Debemos configurar el Nivel de Seguridad como Bajo o Medio, de tal manera que permitirá a la macro ejecutarse

05.- Vamos a Herramientas \ Macro \ Editor de Visual Basic (o desde Alt + F11)

06.- Copiamos el texto anterior, desde la primera línea de la descarga de responsabilidad hasta la última que dice “End sub”

07.- Hacemos doble click sobre ThisProject en el editor de Visual Basic, y copiamos la macro en la ventana que se abra (posiblemente sea llamada “Project1 – This Project(Code)”

08.-  Guardamos este proyecto como un fichero, si necesitamos usarlo otra vez, con el nombre FixPublishError.mpp, y volvemos a la vista normal de Project (Alt+F11)

09.- Abrimos el plan de proyecto en el cual falla el trabajo de (Project Publish)

10.- Vamos a Herramientas \ Macro \ Macros…

11.- Seleccionamos la macro llamada FixPublishError.mpp!FixPublish

12.- Pinchamos sobre Ejecutar. Debemos esperar varios segundos, o incluso un minuto, para que se ejecute la macro

13.- Guardamos y publicamos el proyecto.

14.- Debemos monitorizar la cola, y confirmar que el trabajo relacionado con la publicación de este proyecto termina correctamente

15.- Podemos volver a poner el valor de Nivel de Seguridad como estaba anteriormente

 

Hay una condición que no se resuelve por la macro, y está relacionada con llegar al valor NULL en alguna tarea fantasma que podamos tener en proyecto (éstas pueden existir si hubieran dependencias con tareas de otros proyectos.) Es posible que esto se resuelva si el proyecto padre ha sido ya arreglado, pero seguimos mirando esto.

Hay que agradecer a Adrian por la macro, a Sriram por ayudar con este post, y a DFS y Christoph por los posts en mi blog, acerca del problema.

Os queremos pedir disculpas por las inconveniencias que esto os haya podido causar, e iremos actualiazndo este post, según vayamos teniendo más información al respecto.

Para terminar, aquí tenemos  unas cuantas líneas de los logs ULS relacionadas con este problema, y así asegurar que los motores de búsqueda tienen algo que digerir, y ayudan a las búsquedas de estos términos:

05/23/2012 10:38:09.29 Microsoft.Office.Project.Server (0x0AE4) 0x0EE8 Project Server Project Server Reporting 9e09 High PWA:https://servername/PWA, SSP:SharedServices1, User: DOMAIN\User, PSI: [RDS] ReportProjectPublishMessage for project 0b9e52ec-6bb6-4ca3-823b-d7561d821d1c failed. Error: System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Office.Project.DataEdit.Reporting.ReportingData.GetTaskBaselineCoreTimephasedDataSet(BaselineEntity[] baselineEntityArray, Int32 nIntervalLengthMinutes) at Microsoft.Office.Project.Server.DataAccessLayer.ReportingProjectDal.TransferTimephasedData[T](Guid projectUID, TimephasedTransferInfo transferInfo, ReportingData timephasedReportingData, ProcessSourceData`1 processSourceData, GenerateTimephasedDataSet`1 generateTimephasedData, Int32 pageSize, LogStatsMethod logStats) at Microsoft.Office.Project.Server.DataAccessLayer.ReportingProjectDal.UpdateTasksTimephasedData(Guid projectUID, ReportingProjectData projectData, ReportingData timephasedReportingData, Int32 pageSize, String& transferPhase, LogStatsMethod logProjStats) at Microsoft.Office.Project.Server.BusinessLayer.ReportingLayer.ProjectPublishMessageProcessor.SaveProjectTimephaseData(String& transferPhase) at Microsoft.Office.Project.Server.BusinessLayer.ReportingLayer.ProjectPublishMessageProcessor.runRDSTransformation(ReportProjectPublishMessageEx projectChangeMessage). Phase: SetAssignmentBaselineTimephasedFixedCost 3ff34f2c-815e-4f95-9798-7f17dc5737db

05/23/2012 10:38:09.29 Microsoft.Office.Project.Server (0x0AE4) 0x0EE8 Project Server Project Server Reporting 9e05 Critical Standard Information:PSI Entry Point: Project User: Domain\User Correlation Id: 3ff34f2c-815e-4f95-9798-7f17dc5737db PWA Site URL: https://servername/PWA SSP Name: SharedServices1 PSError: ReportingProjectChangeMessageFailed (24006) RDS: The request to synchronize change(s) to project Project UID='0b9e52ec-6bb6-4ca3-823b-d7561d821d1c'. PublishType='ProjectPublish' failed. Message: 'ReportingProjectChangeMessageFailed' Error:Object reference not set to an instance of an object. 3ff34f2c-815e-4f95-9798-7f17dc5737db

05/23/2012 10:38:10.30 Microsoft.Office.Project.Server (0x0AE4) 0x0D18 Project Server Project Server Queue 7h5x Medium PWA:https://servername/PWA, SSP:SharedServices1, User: DOMAIN\SSPAdmin, PSI: [QUEUE] ProjectQ: Group d4364343-3402-45ef-afd0-f84c8834e5d3 type = ReportingProjectPublish aborted at Message 1 e45e8c63-38fa-49d8-9555-710851b22c90

 

Esperamos os resulte de interés, un saludo

 

Jorge Puig