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í:
http://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>
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:http://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: http://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:http://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
Nos hacemos eco en este post del que escribió Brian Smith ayer:
http://blogs.msdn.com/b/brismith/archive/2012/05/16/project-2010-problems-since-the-february-cu-if-you-have-a-semi-colon-as-your-list-separator.aspx
el cual nos ha parecido relevante haceros llegar, ya que se trata de una regresión introducida por dicha actualización acumulativa. Sin más preámbulos, pasamos a traducir su excelente artículo:
En la actualización acumulativa de Febrero de 2012 arreglamos un problema que se definía como:
Tiene un archivo MPP guardado en un servidor de Project mediante el uso del comando Guardar para uso compartido. Cuando intenta volver a guardar el archivo .mpp en Project Server 2010, en el proceso de almacenamiento se produce un error, y recibirá el mensaje de error siguiente:
Project Server no pudo encontrar el recurso especificado. Si el problema persiste, póngase en contacto con el administrador del servidor.
Este problema se produce cuando el carácter de separador de lista que figura en los nombres de recursos del archivo .mpp del cliente es diferente para el carácter separador de lista en el servidor.
Nos estamos dando cuenta ahora que, al arreglar esto, rompimos otras cosas, las consecuencias aparecerán si usamos un separador de listas que sea un punto y coma (;). Esto ocurre sobre todo en Europa y Canadá, aunque estamos seguros habrá otros muchos sitios donde nos ocurra. Todos estos problemas están relacionados , y estamos trabajando para arreglarlos, pero hemos pensado sería conveniente haceros llegar una manera de evitar esto, por si nos estuviera sucediendo.
El primer ejemplo asume que tenemos punto y coma como separador de lista, y también está siendo usado en los nombres de tus recursos, como separador entre nombre y apellido/s. De esta manera tenemos una tarea que está asignada a Smith; Brian y Jenkins; Adrian (nuestros gurús favoritos .) Además queremos añadir a Fiessinger; Christophe. Inicialmente, el cuadro de diálogo de la Información de la Tarea mostraría algo así:
A continuación añadimos a Fiessinger; Christophe – pulsamos sobre OK – y veremos lo siguiente:
Lo cual no parece muy correcto, ¿verdad?
Abriendo el cuadro de diálogo de la Información de la Tarea, vemos que:
Ha dividido cada nombre en dos, creado 6 recursos locales, y los ha asignado a la tarea. Tengamos en cuenta un par de cosas – no se perderá trabajo actual – ninguna asignación que tuviera trabajo estará bien – y no aparecerá como no asignada – pero los recursos locales extra seguirán siendo creados. “Deshacer” hará que todo quede bien. Lo mismo puede ocurrir incluso si eliminas un recurso usando este mismo cuadro de diálogo. Si quitamos a Jenkins; Adrian, crearía a Smith y a Brian como dos recursos locales. La manera de solventar esto aquí es usando la columna “Nombre de recursos” en una de las vistas, como la de Gantt, y seleccionar, etc, desde ahí.
El segundo problema trata con el cuadro de diálogo de Asignación de recursos (por el cual no se trata de una buena práctica a la hora de solventar el primer problema) y tiene varios escenarios diferentes, dependiendo del separador de lista usado en los nombres de los recursos. Si estuviéramos usando el separador (como en el ejemplo anterior) no podríamos asignar desde este cuadro de diálogo – el botón asignar está deshabilitado – como se muestra a continuación:
Independientemente, si elijo un recurso sin separador de lista en el nombre, el botón Asignar está activo:
El siguiente problema con la asignación de recursos aparece cuando hacemos una selección múltiple que no contienen el separador de lista, como en este ejemplo:
Cuando pulso sobre Asignar – vemos que tenemosun recurso extra en la lista, con un nombre bastante curioso “adrian jenkins;brian smith;christophe fiessinger”, y esta entidad ha sido asignada a la tarea
Si echamos un vistazo a la hoja de recursos, veremos que “adrian jenkins;brian smith;christophe fiessinger” ha sido añadido como un nuevo recurso local. La manera de solventar esto es. asumiendo que no tenemos el separador de lista en el nombre, asignar uno a uno, o, por supuesto, usar la columna de “Nombres de Recursos” del ejemplo anterior, en el diagrama de Gantt.
El último escenario tiene que ver otra vez con el cuadro de diálogo de Información de la Tarea, pero esta vez estamos mirando a la pestaña de Predecesoras. Tenemos 3 tareas, T1, T2, y T3. Abrimos el cuadro de diálogo para T3, e introducimos cualquiera de los IDs de las dos tareas primeras, o las seleccionamos como en esta captura de pantalla:
si pinchamos sobre OK, tendremos el siguiente mensaje de error. Hay un problema con la información de la tarea predecesora:
La manera de solventar esto es ir a una vista, como la de Gantt, usar la columna de Predecesoras, e introducir 1,2.
Para cada uno de estos problemas, también podríamos evitarlos no usando elpunto y coma – pero entendemos que podáis encontraros otros problemas en algún otro lugar – ya que se trata de una configuración global de vuestro PC. Si queréis probar esto, podemos ir a Panel de Control \Reloj, Lenguaje y Región \ cambiar la fecha o formato de número, y seleccionar “Configuración Adicional” para cambiar el separador de lista de un punto y coma, a una coma, por ejemplo.
Os pedimos disculpas por las molestias que esto os pueda generar (o haya generado) y esperamo actualizar este post una vez tengamos claro que vayamos a tener arreglado esto (y puede que mencionemos otros escenarios que nos hagan llegar, donde este problema aparezca.) Queremos agradecer desde aquí a los clientes que nos han hecho llegar este problema.
En este post queríamos haceros llegar la siguiente información, que publicó Brian Smith recientemente en su blog:
http://blogs.msdn.com/b/brismith/archive/2012/05/01/project-server-2010-orphan-baselines-breaking-the-reporting-publish.aspx
Creemos que se trata de un artículo muy bien explicado, y que nos puede pasar en nuestros entornos, así que, aparte de agradecer públicamente a Brian por su excelente artículo, procedemos a traducirlo para la comunidad de Project hispano parlante. Esperamos sinceramente os resulte de utilidad:
“Este problema lleva ocurriendo un tiempo ya, incluso hubo clientes que lo empezaron a sufrir según se lanzó esta versión (Project Server 2010), pero no habíamos sido capaces de conseguir reproducirlo, y entender exactamente qué lo estaba causando. Hemos sido capaces de entenderlo ahora, y tenemos una actualización que lo debe arreglar (saldrá, salvo problemas de última hora, en la actualización acumulativa de Junio de 2012.) Hay varias maneras de trabajar para limitar las probabilidades de que nos ocurra esto, así que hemos decidido compartirlas con vosotros, hasta que se libere la actualización.
Vamos a echar un vistazo primero a los síntomas. El indicador más común de este problema, como el título sugiere, está relacionado con valores de línea base huérfanos, los cuales nos causan el error cuando publicamos un proyecto (Failed but Not blocking Correlation) en el trabajo de “Reporting (Project Publish)” que se genera después de publicar correctamente un proyecto en nuestro sitio PWA. Se nos mostrarán los siguientes errores, si pinchamos en los detalles de cada trabajo fallido en la cola:
ReportingProjectChangeMessageFailed (24006) - The INSERT statement conflicted with the FOREIGN KEY constraint "FK_MSP_EpmTaskBaseline_ProjectUID_TaskUID". The conflict occurred in database "ProjectServer_Reporting", table "dbo.MSP_EpmTask". The statement has been terminated.. GeneralQueueJobFailed (26000) - ReportingProjectPublish.ReportProjectPublishMessageEx
ReportingProjectChangeMessageFailed (24006) - The INSERT statement conflicted with the FOREIGN KEY constraint "FK_MSP_EpmTaskBaseline_ProjectUID_TaskUID". The conflict occurred in database "ProjectServer_Reporting", table "dbo.MSP_EpmTask". The statement has been terminated..
GeneralQueueJobFailed (26000) - ReportingProjectPublish.ReportProjectPublishMessageEx
Estos fallos se refieren al trabajo mencionado anteriormente “Reporting (Project Publish)”, lo cual indica que los informes generados a partir de la base de datos de Reporting (y del cubo OLAP, puedan no tener toda la información.)
Existen ocasiones en las que incluso hay fallos al intentar guardar un proyecto, donde se nos muestre el mensaje genérico “MSSOAP 16 Send Incomplete” desde Project PRO 2010 (aunque cuando volvamos a intentar guardarlo pueda hacerlo correctamente), o en el PWA, podamos ver el siguiente mensaje de error:
GeneralQueueException (9131) A Project Operation failed due to a Queue Exception. Sub Job ID is: . Exception details are: System.NullReferenceException: …at Microsoft.Office.Project.DataEdit.Assignments.AssignmentCalendarUpdateHelper.ConvertActualContourToElapsed(,,,
También puede ser que tengamos problemas con usuarios intentando acceder a partes de horas, y se nos muestre un mensaje indicando que no se ha podido cargar la vista, y que pulsemos en OK para recargarla (y aunque pinchemos, no haga nada…)
El error que aparecería en los logs ULS se referiría a un calendario, del cual no puede encontrar el UID…
Exception occurred in method Microsoft.Office.Project.Server.BusinessLayer.Statusing.StatusingGetMyWorkForGridJson System.InvalidOperationException: CacheProjectBaseCalendars could not find project calendar for project. CalUid=0c13de33-2a07-4310-b091-c77990d9dd6a
La causa de todos estos problemas estriba en que cuando usamos alguna de las opciones de guardar y enviar (XML, CSV, Excel, etc) estamos cambiando (de manera incorrecta) algunos de los GUIDs asociados con entidades como las tareas y/o calendarios. Esto no está afectando los GUIDs de las tareas principales y de las asignaciones, ya que estos valores incorrectos no persisten hacia la base de datos, pero sí crean una nueva línea base para aquellos GUIDs nuevos de las tareas no existentes, y pueden también guardar un GUID para un calendario incorrecto (el cual nos lleva al problema de los partes de horas.)
Vamos primero a ver la manera de evitar este problema, y luego veremos cómo detectarlo, y “limpiarlo” a nivel de las bases de datos.
Si necesitamos usar la opción de Guardar y Enviar, la mejor opción mientras se libera la actualización mencionada es la siguiente: guardemos el proyecto, y publiquémoslo, si fuera necesario. Hagamos luego lo que sea pertinente, referente a la opción de Guardar y Enviar, e, inmediatamente después de esto, cerremos y desprotejamos el proyecto, pero no lo volvamos a guardar al sitio PWA. Rechacemos los cambios, si nos preguntara al respecto, (aunque tengamos claro que por supuesto hayamos debido guardarlo antes de usar el Guardar y Enviar) para evitar perder cambios que podamos necesitar. Como los datos “chungos” puedan persistir en la caché local, ésta será una de las raras ocasiones donde os sugeriremos que se elimine dicho proyecto de la caché local, después de habernos asegurado que el proceso de guardar y de desprotección han terminado correctamente.
AVISO. Las siguientes acciones implican consultas directas a las bases de datos de Project Server. Por favor, tengamos claro contra qué base de datos las estamos ejecutando, de tal manera que lo hagamos en las adecuadas. Independientemente, como siempre que hagamos algo de este tipo, recomendamos encarecidamente haber realizado copias de seguridad de las bases de datos antes, por lo que pudiera pasar…
La detección de esta condición es muy directa, ya que estamos buscando líneas base existentes, para una tarea que no existe, de tal manera que la siguiente consulta, ejecutada contra la base de datos de Draft nos localizará dicha información:
USE ProjectServer_Draft -- aquí debemos especificar el nombre adecuado para la base de datos Draft select PROJ_NAME, MTB.PROJ_UID,TASK_UID,TB_BASE_NUM from MSP_TASK_BASELINES MTB inner join MSP_PROJECTS MP on MTB.proj_uid=MP.proj_uid where TASK_UID not in (select TASK_UID from MSP_TASKS)
USE ProjectServer_Draft -- aquí debemos especificar el nombre adecuado para la base de datos Draft
select PROJ_NAME, MTB.PROJ_UID,TASK_UID,TB_BASE_NUM from MSP_TASK_BASELINES MTB inner join MSP_PROJECTS MP on MTB.proj_uid=MP.proj_uid where TASK_UID not in (select TASK_UID from MSP_TASKS)
Si nos devuelve información, indicará que dicha condición existe, a la vez que identificará para cuales proyectos. Esto resulta interesante, de tal manera que se recomienda hacerlos desaparecer de la caché local de los jefes de proyecto, ya que pudieran reintroducir el problema en el futuro.
Los siguientes scripts se encargan de “limpiar” las bases de datos; simplemente eliminan registros de las líneas base de tareas que no existen:
-- Script que se debe ejecutar en la base de datos Draft USE ProjectServer_Draft -- aquí debemos especificar el nombre adecuado para la base de datos Draft delete from MSP_TASK_BASELINES where TASK_UID not in (select TASK_UID from MSP_TASKS) -- Script que se debe ejecutar en la base de datos Published USE ProjectServer_Published -- aquí debemos especificar el nombre adecuado para la base de datos Published delete from MSP_TASK_BASELINES where TASK_UID not in (select TASK_UID from MSP_TASKS)
-- Script que se debe ejecutar en la base de datos Draft
delete from MSP_TASK_BASELINES where TASK_UID not in (select TASK_UID from MSP_TASKS)
-- Script que se debe ejecutar en la base de datos Published USE ProjectServer_Published -- aquí debemos especificar el nombre adecuado para la base de datos Published
Espero esto nos ayude a entender la naturaleza de este problema, y las maneras de evitarlo mientras se haga pública la actualización que lo corrige. Nuestras disculpas por las molestias esto haya podido causar a nuestros clientes, y esperamos que, para aquellos que necesitaran ejecutar los scripts de limpieza de manera periódica, esto les pueda aliviar.
Las entradas de los logs ULS, asociadas a los errores en la cola de Project Server (para optimizar los motores de búsqueda) son las siguientes:
05/01/2012 11:57:55.67 Microsoft.Office.Project.Server (0x1D74) 0x335C Project Server Reporting atwj Critical Standard Information:PSI Entry Point: Project User: REDMOND\brismith Correlation Id: e1f4e953-7dea-448a-a528-709075c698bf PWA Site URL: http://brismith8100/PWA SSP Name: Project Server Service Application PSError: ReportingProjectChangeMessageFailed (24006) RDS: The request to synchronize change(s) to project Project UID='216733b0-e194-469a-afc3-9235da4ce4c1'. PublishType='ProjectPublish' failed. Message: 'ReportingProjectChangeMessageFailed'. Message Body: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_MSP_EpmTaskBaseline_ProjectUID_TaskUID". The conflict occurred in database "ProjectServer_Reporting", table "dbo.MSP_EpmTask". The statement has been terminated. Error:(null) e1f4e953-7dea-448a-a528-709075c698bf
Para el error del parte de horas:
05/01/2012 12:13:29.65 w3wp.exe (0x2444) 0x23D8 Project Server Task Statusing and Updates btw9 High CacheProjectBaseCalendars: could not locate data for calendar 0c13de33-2a07-4310-b091-c77990d9dd6a for project 216733b0-e194-469a-afc3-9235da4ce4c1 e5dd4eaf-551a-469b-a3e0-1f60e2f3d1af
05/01/2012 12:13:29.85 w3wp.exe (0x2444) 0x23D8 Project Server General 0000 Exception Exception occurred in method Microsoft.Office.Project.Server.BusinessLayer.Statusing.StatusingGetMyWorkForGridJson System.InvalidOperationException: CacheProjectBaseCalendars could not find project calendar for project. CalUid=0c13de33-2a07-4310-b091-c77990d9dd6a at Microsoft.Office.Project.Server.BusinessLayer.TimePhasedDataAccess.CacheProjectBaseCalendars() at Microsoft.Office.Project.Server.BusinessLayer.TimePhasedDataAccess..ctor(StatusingPageLoadDataSet dataset) at Microsoft.Office.Project.Server.BusinessLayer.Statusing.ReadStatusTimephasedDataForResource(IList`1 gridChanges, Guid[] vAssnUids, IDictionary`2 assn2proj, StatusingTimephasedPeriod[] tpdPeriods, DateTime tpStart, DateTime tpEnd) at Microsoft.Office.Project.Server.BusinessLayer.Statusing.<>c__DisplayClass57.<CreateTimephasedDataColumnFiller>b__56(IEnumerable`1 Keys) at Microsoft.SharePoint.JSGrid.GridSerializer.BuildOutput() at Microsoft.SharePoint.JSGrid.GridSerializer.ToJson(Serializer s) at Microsoft.SharePoint.JsonUtilities.Serializer.SerializeToJson(Object o) at Microsoft.Office.Project.Server.BusinessLayer.Statusing.GetMyWorkForGridJson(JsGridSerializerArguments gridSerializerArgs, String gridChangesJson, String projectAssignmentsMap, Guid viewUid, String timephasedStart, String timephasedEnd, Byte pane, Int32 durationType, Int32 workType, Int32 dateFormat, Boolean clearPersistedProperties, Nullable`1 rowFilterType) at Microsoft.Office.Project.Server.Wcf.Implementation.PWAImpl.StatusingGetMyWorkForGridJson(JsGridSerializerArguments gridSerializerArgs, String gridChangesJson, String projectAssignmentsMap, Guid viewUid, String timephasedStart, String timephasedEnd, Byte pane, Int32 durationType, Int32 workType, Int32 dateFormat, Boolean clearPersistedProperties, Nullable`1 rowFilterType) e5dd4eaf-551a-469b-a3e0-1f60e2f3d1af
Esperamos sinceramente os resulte igual de útil y provechoso que nos ha parecido a nosotros.
En el post de hoy queríamos haceros llegar un pequeño truco que podemos utilizar en el supuesto que, por algún motivo, nos quedemos sin privilegios de administrador en el sitio PWA. Un ejemplo de esto sería la siguiente situación: imaginemos que tenemosun único administrador en nuestro sitio PWA, y le quitamos del grupo Administradores en PWA. La siguiente vez que intentamos acceder al sitio PWA, con este usuario, recibimos un mensaje similar a este:
La manera oficial de “arreglar” esto realizando un “aprovisionamiento” del sitio PWA otra vez, con el usuario al cual queremos otorgar privilegios de administador en el sitio PWA. Esto hará que dicho usuario vuelva a tener privilegios de administrador en el sitio, y no debiera tener ningún tipo de efecto adverso, no deseado, en nuestro sitio PWA. Independientemente, como siempre que hagamos algo que pueda tener cierto impacto en nuestro entorno, se recomienda efectuar un backup de las bases de datos antes.