lunes, mayo 29, 2006

Exportar Microsoft Project día por día

Este artículo explica cómo exportar las horas asignadas a cada recurso en Microsoft Project día por día a Microsoft Excel en un formato que permita crear una tabla pívot.

Realicé las siguientes búsquedas en Internet sin resultado:

  • Exportar MS Project día por día
  • Export MS Project in daily basis
  • Microsoft Project export timescaled

Finalmente me enteré que MS Project no incluye esta función y, en caso de necesitarla, había que programarla en VBA (Visual Basic for Applications).

Problema Cuando exportamos los datos a otro formato, Microsoft Project crea un registro por cada tarea asignada a cada recurso y esta tarea incluye los datos de fecha de inicio de la tarea, fecha de finalización y cantidad de horas que la tarea requiere. Esto significa que, si una tarea comienza el día 1 y requiere 60 horas, sólo obtendremos un registro con esos datos. Cuando hacemos la tabla pívot, crearemos un reporte en el que dice que el recurso trabajará 60 horas el día 1 y ninguna los días siguientes.

Lo que necesitamos exportar son los datos que representan la vista de “Resource Usage”

Resource usage

En mi caso particular debía exportar los datos desde un archivo Project que funciona como “Resource Pool”. La particularidad de este archivo es que no contiene tareas, sólo recursos y asignaciones.

Solución Primero debemos abrir el entorno de VBA para crear la nueva macro con la combinación de teclas ALT + F11. Visual Basic for Applications

Creé un nuevo formulario llamado “frmExportTimescaled” dentro de “ProjectGlobal (Global.MPT)”. Esto significa que la macro estará disponible para cualquier archivo de Project que abramos.

Armamos la interfaz de usuario con fecha inicial, fecha final, tipo de datos a exportar, dos barras de progreso (una para recursos y otro para asignaciones) y un botón para exportar. Interfaz macro Para poder agregar los controles “Date Time Picker” primero debemos ir al menú Tools -> References y agregar “Microsoft Windows Common Controls 2 (MSCOMCT2.OCX)”. Si no tenemos esta librería, la pueden obtener desde http://activex.microsoft.com/controls/vb6/mscomct2.cab Luego vamos al menú Tools -> Additional Controls y seleccionar “Microsoft Date and Time Picker Control 6.0” para agregarlo al Toolbox.

Los nombres que les puse a los controles para referenciarlos desde código son:
  • Start Date: sDate
  • End Date: eDate
  • Type of data: ddAssignType
  • Label resources: lblResources
  • Resources progress bar: pBarResources
  • Label assignments: lblAssign
  • Assignment progress bar: pBarAssignments
  • Export button: btnExport

Para poder poblar la lista de tipos de datos y para crear un botón con nuestra macro en una barra de herramientas de Project, creamos un nuevo módulo (yo le puse por nombre Export_Timescaled). Este módulo, además de poblar los tipos de datos, invoca al formulario.

El siguiente es el código del módulo Export_Timescaled: Sub Export_Timescaled() frmExportTimescaled.ddAssignType.Clear frmExportTimescaled.ddAssignType.AddItem ("Work") frmExportTimescaled.ddAssignType.AddItem ("Actual Work") frmExportTimescaled.ddAssignType.AddItem ("Cumularive Work") frmExportTimescaled.ddAssignType.AddItem ("Overallocation") frmExportTimescaled.ddAssignType.AddItem ("Cost") frmExportTimescaled.Show End Sub

El siguiente es el código del formulario frmExportTimescaled: Option Explicit Dim xlApp As Excel.Application

Private Sub btnExport_Click() Dim t As Task Dim Asgn As Assignment Dim a As Integer Dim b As Integer Dim currRow As Integer Dim i As Double Dim c As Range Dim TSV As TimeScaleValues Dim AssignType As PjAssignmentTimescaledData

Call ControlsEnable(False) 'Disable all form controls Call CreateExcelFile Application.ActiveWindow.Refresh 'This makes form get focus

Set c = xlApp.ActiveCell currRow = 0 'Set column titles c.Offset(currRow, 0) = "Task Name" c.Offset(currRow, 1) = "Employee" c.Offset(currRow, 2) = "Date" c.Offset(currRow, 3) = "Hours" c.Offset(currRow, 4) = "Week" Call InitProgressBarResources(ActiveProject.Resources.Count)

'Determine Assignment Type to export Select Case ddAssignType.Value Case "Actual Work": AssignType = PjAssignmentTimescaledData.pjAssignmentTimescaledActualWork Case "Cumularive Work": AssignType = PjAssignmentTimescaledData.pjAssignmentTimescaledCumulativeWork Case "Overallocation": AssignType = PjAssignmentTimescaledData.pjAssignmentTimescaledOverallocation Case "Cost": AssignType = PjAssignmentTimescaledData.pjAssignmentTimescaledCost Case Else AssignType = PjAssignmentTimescaledData.pjAssignmentTimescaledWork End Select For a = 1 To ActiveProject.Resources.Count pBarResources.Value = a 'Update progress bar lblResources.Caption = a & "/" & pBarResources.Max 'Update label If Not ActiveProject.Resources.Item(a) Is Nothing And ActiveProject.Resources.Item(a).Assignments.Count > 0 Then Call InitProgressBarAssing(ActiveProject.Resources.Item(a).Assignments.Count) 'Initialize second progress bar For b = 1 To ActiveProject.Resources.Item(a).Assignments.Count If Not ActiveProject.Resources.Item(a).Assignments.Item(b) Is Nothing Then Set TSV = ActiveProject.Resources.Item(a).Assignments(b).TimeScaleData(sDate.Value, eDate.Value + 1, AssignType, pjTimescaleDays) pBarAssignments.Value = b 'Update second progress bar lblAssign.Caption = b & "/" & pBarAssignments.Max 'Update second label For i = 1 To TSV.Count DoEvents If IsNumeric(TSV.Item(i).Value) Then 'Check for data currRow = currRow + 1 c.Offset(currRow, 0) = ActiveProject.Resources.Item(a).Assignments.Item(b).TaskName c.Offset(currRow, 2) = ActiveProject.Resources.Item(a).Name c.Offset(currRow, 3) = TSV.Item(i).StartDate c.Offset(currRow, 4) = Round(TSV.Item(i).Value / 60, 2) c.Offset(currRow, 5) = DateAdd("d", 5 - (Weekday(TSV.Item(i).StartDate, vbSunday)), TSV.Item(i).StartDate) End If Next End If Next End If Next

MsgBox ("Exportación completa") ControlsEnable True End Sub

Sub ControlsEnable(status As Boolean) btnExport.Enabled = status sDate.Enabled = status eDate.Enabled = status ddAssignType.Enabled = status End Sub

Sub InitProgressBarResources(cant As Integer) pBarResources.Min = 0 pBarResources.Max = cant pBarResources.Value = 0 End Sub

Sub InitProgressBarAssing(cant As Integer) pBarAssignments.Min = 0 pBarAssignments.Max = cant pBarAssignments.Value = 0 End Sub

Sub CreateExcelFile() Dim xlBook As Excel.Workbook Dim xlSheet As Excel.Worksheet Dim a As Integer

'Create Excel Object Set xlApp = New Excel.Application xlApp.Visible = True AppActivate "Microsoft Excel"

'Create Workbooks and Output Sheet Set xlBook = xlApp.Workbooks.Add Set xlSheet = xlBook.Worksheets.Add 'Create Sheet name. Must be less than 31 characters xlSheet.Name = Mid(Mid(ActiveProject.Name, 1, Len(ActiveProject.Name) - 4) & " (" & ddAssignType.Value & ")", 1, 31) 'Delete extra sheets For a = 1 To 3 xlBook.Worksheets(2).Delete Next End Sub

Finalmente, para poder compartir la macro con otras personas, la copié a un archivo de Project vacío utilizando el menú Tools -> Organizer, seleccionando “Modules”. De esta forma, abrimos el archivo en otra computadora y copiamos la macro hacia el Global.MPT y ya queda disponible en nuestro MS Project.

Descargar archivos fuente 

Descargar archivo MS Project con la macro

IMPORTANTE Si al correr la macro aparece el error "User-defined type not defined" significa que falta la Referencia al objeto Excel dentro de la macro. Para solucionar esto vamos a la pantalla de VBA (ALT+F11), seleccionamos Tools --> References Y seleccionamos "Microsoft Excel 11.0 Object Library" o similar. Les muestro mis referencias: Guardamos y ejecutamos la macro nuevamente.

32 comentarios:

Alcides Velazco dijo...

Gracias por tu aplicación, tu crees que puedas tener tambien el codigo para exportar el informe de flujo de caja de project a excel.

Gracias

Damián Bacalov dijo...

Entiendo que se puede. Nunca usé esa funcionalidad en Project, pero solo debemos saber cuales son las variables que tienen esa información.

Anónimo dijo...

Hola Damián:
En la escuela me dejaron hacer algo muy similar a lo que publicaste y la verdad no tenia ni idea de como empezar, ya que no hay mucha información sobre el vb6.0 y project.
Una pregunta
¿Esto mismo se puede hacer desde VB6.0?

Muchas gracias por tu ayuda
Saludos

Margarita dijo...

Hola Damián, ayer utilicé su programa, lo copié y lo corrí, pero me sale que no está definido el tipo definido por el usuario en: Dim xlApp As Excel.Application Ud. me puede ayudar? Por otro lado, estuve mirando su perfil y realmente me asombra que alguien sea tan buena persona que ayude a los internautas con su cultura (café recién molido) y sus problemas informáticos!! Un abrazo!

Damián Bacalov dijo...

Margarita: en breve voy a actualizar en archivo con una versión corregida.

Margarita dijo...
Este comentario ha sido eliminado por el autor.
Damián Bacalov dijo...

Margarita: ya está la versión corregida. Era un simple problema de Visual Basic.

Ya lo podés bajar nuevamente. Espero que te sea útil.

Margarita dijo...
Este comentario ha sido eliminado por el autor.
Anónimo dijo...

como puedo saber la actividad padre de un task.

Unknown dijo...

hola Damian, podrias indicar como bajar tu archivo de project
consulta: desarrollaste otro ejemplo ?

Damián Bacalov dijo...

Guillermo:

Ya corregí el POST. Ya podés descargar los ejemplos.

La verdad es que no volví a hacer más ejemplos de este tipo con Project.

Saludos.

Unknown dijo...

gracias Damián.
logré descargar el archivo, sin embargo no ejecuta me sale error

aparece un cuadro de dialogo de visual basic con el mensaje Error de compilación. no se ha definido el tipo definido po el usuario.
al aceptar lo que tiene seleccionado es :
Option Explicit
Dim xlApp As Excel.Application

estoy utilizando la versión 2007 de project en español, talvez eso tenga que ver.

por otro lado quería consultarte si podrías ayudarme con alguna macro en project, resulta que yo utilizo project para obras de construcción civil de diferentes tipos y uno de los inconvenientes es determinar las cantidades de material en la tarea, por la mano de obra y equipos no es inconveniente pero si es trabajoso los materiales, me explico con un ejemplo.
definamos la tarea "Concreto de columna" con una cantidad de 100 m3
tengo mis recursos que pueden avanzar 20m3/dia, con lo cual la duración será de 5 días.
en los recursos yo defino al recurso ayudante como tipo "trabajo" y asigno 2 unidades.
y también defino el material "cemento" con etiqueta "bls" (de bolsas).
en el caso de este material, lo que quiero decirle a project es que por cada m3 de la tarea yo necesito 8 bolsas de cemento de tal forma que project calcule que en la tarea se necesita 800 bolsas como total.
En resumen yo lo que quiero es asignar en project recursos unitarios y que project calcule cantidades totales.
de requerir un ejemplo mi correo es hh.gcarrera@gmail.com
gracias por tu tiempo
saludos
Guillermo

Damián Bacalov dijo...

Guillermo,

Dejame buscar algo de información. No te prometo nada porque hace tiempo que no hago estas cosas con Project. Pero si encuentro algo como para avanzar te mando un mail para que me pases algún ejemplo concreto.

Saludos,
Damián

Unknown dijo...

De acuerdo Damián.
Te pasaré un ejemplo de lo que suelo trabajar.

Unknown dijo...

Algo que estaba pensando es que talvez necesite generar una plantilla en excel o access y de ahi pasarlo a project.

Anónimo dijo...

Hola descargue el archivo que contiene la macro, pero me marca este error: Application.ActiveWindow.Refresh 'This makes form get focus

Y si abre un archivo de excel, pero no aparece ningún dato.

Te agradecería si puedes ayudarme

Damián Bacalov dijo...

Este ejemplo fue hecho con Office 2003 en inglés. Por otro lado, mientras está exportando no hay que tocar la planilla Excel.

Saludos.

Anónimo dijo...

Hola Damián

¿Cómo puedo utilizar la macro en las versiones 2007 de project y excel?

Gracias

Gretel Román

Damián Bacalov dijo...

Para en las versiones 2007 de project y excel primero deberás editar las "referencias" de Project para que incluya el Excel 2007 (esto está explicado en el post teniendo en cuenta la versión 2003).

Luego tenés que revisar el idioma. El problema de VBA (macros) es que depende del idioma. Esta macro fue desarrollada en la versión en Inglés de Office 2003. Si vos tenés office 2007 en español, tal vez debas revisar el código.

Anónimo dijo...

Damián

Te agradezco tu ayuda, pero yo no sé utilizar el VBA, pude seguir tus instrucciones, pero no podría hacer los cambios en la programación. Mi trabajo consiste en llevar el control de proyectos por eso me intereso utilizar la macro.

Gracias

Gretel Román

Damián Bacalov dijo...

Voy a revisar la macro para la versión de Office 2007 en español y la voy a publicar en breve en este mismo blog.

Saludos.

Damián Bacalov dijo...

Ya publiqué un post con la versión Office 2007.

Saludos a todos.

Unknown dijo...

Hola, estoy buscando en Project funciones parecidas a BUSCAR, COINCIDIR, INDICE, etc. de Excel. O, en su defecto, una fórmula que me calcule un valor en cada tarea a partir de valores de otras tareas. Ejemplo: La tarea pago comisión de venta (EDT 01.01.02) tiene un costo2= costo1 de la EDT 01.01 por 25%. Ya sé cómo manipular la EDT, pero no sé cómo encontrar la tarea correspondiente. Gracias (Walter Fernandez - Colombia)

daps21 dijo...

Hola quisera saber como puedo reutilizar el codigo que publicaste pero para pasar los datos de las hoja de recursos....

Damián Bacalov dijo...

Hola daps21,

Hay que investigar un poco. Creo que si analizás mi código vas a poder encontrarle la vuelta.

Unknown dijo...

Y para lograr lo contrario?

Es decir crear los recursos desde VBA


Gracias

JAVIER dijo...

Buenas tardes, me dirijo a usted para solicitarle el apoyo con respecto a una duda que tengo; y la misma es la siguiente: ¿Cómo haría para crear una macro en Microsoft Project que haga lo siguiente?:
1. Copie desde Microsoft Project toda la columna o campo llamado “Nombre” (aquellas que tengan alguna descripción de tareas) y la columna o campo llamado “% completado” (asociadas a las tareas descritas), y luego,
2. Copie esa información en un archivo Excel.

Con lo que usted publico arriba ya se como crear la hoja excel, pero como no manejo visual basic no se cual seria la sintaxis correcta o las lineas de codigo que me permitan pasar desde el project al excel los datos de las 2 campos que le comento arriba.

Esperando su valiosa colaboración me despido.

Saludos.

agustin dijo...

Hola Damian,
estoy usando MS project 2013 y por alguna razon el macro no funciona. He activado las referencias de office pero sigue sin funcionar.
Desde ya agradezco tu ayuda,
Agustin

agustin dijo...

Hola Damian,
Ingrese a visual basic y la linea donde aparece el error es esta: " Set c = xlApp.ActiveCell " Me puede ayudar entender y corregir este error?
Muchas gracias,
Agustin

Ing. Juan Carlos Chávez P. dijo...

Hola Damian, tiene correo electrónico, me gustaría consultarte o desarrollar una aplicacipon.

Te dejo mis direcciones: juanchavezjc_k@gmail.com; chavezjc_k@hotmail.com

Gracias,

Juan Carlos Chávez Pérez

Jhorbam dijo...

Cordial saludo.

Los enlaces no funcionan, podrías por favor compartir nuevamente los archivos. Gracias.

Damián Bacalov dijo...

Hola Jhorbam, ya publiqué nuevamente los archivos. Pero son viejos, no estoy seguro de que todavía funcionen.