Reputation: 23
I have this code in VB .NET and VSTO that accesses a MS Project file and exports the information from the RESOURCE USAGE view to Excel, but when taking the information about the work distributed over time for the resource, it only prints ZEROs (0) from column D onwards (the area selected for this printout).
' ExportacionUsoRecursos.vb
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop.MSProject
Imports System.Windows.Forms
Imports System.Globalization
Imports System.Drawing
Imports Microsoft.Win32
Imports Microsoft.Office.Interop
Public Enum PjResourceTimescaledDataType2
pjResourceTimescaledWork = 0 ' Trabajo planeado distribuido en el tiempo para recursos
pjResourceActualWork = 2 ' Trabajo real para recursos
pjResourceTimescaledBudgetWork = 1172 ' Trabajo presupuestado para recursos
pjResourceTimescaledBaselineWork = 1 ' Trabajo de línea base para recursos
pjResourceTimescaledBaselineBudgetWork = 1117 ' Trabajo presupuestado de línea base para recursos
End Enum
Public Enum PjTimescaleUnit2
pjTimescaleWeeks = 2 ' Escala de tiempo en semanas
End Enum
''' <summary>
''' Clase que exporta los datos de recursos (vista USO DE RECURSOS) a una hoja de Excel ("DatImp").
''' Por cada recurso se genera una fila con:
''' - Nombre de Recurso (columna A)
''' - Trabajo planeado (columna B, convertido de minutos a horas)
''' - Una fórmula de autosuma en la columna C que sume la distribución semanal del trabajo planeado
''' (desde la columna D en adelante).
''' Los intervalos se determinan a partir de las fechas del proyecto (se usan los mismos intervalos para todos los recursos).
''' Se congela la vista desde la celda D2 y, al finalizar, se cierra MS Project para evitar procesos en segundo plano.
''' </summary>
Public Class ExportacionUsoRecursos
''' <summary>
''' Exporta a la hoja "DatImp" los datos de recursos y la distribución semanal del trabajo planeado.
''' </summary>
''' <param name="proj">Objeto Project obtenido vía MS Project Interop.</param>
Public Sub ExportarRecursosConDistribucion(proj As Project)
Try
Dim excelApp As Microsoft.Office.Interop.Excel.Application = Globals.ThisAddIn.Application
Dim wb As Workbook = excelApp.ActiveWorkbook
Dim ws As Worksheet = Nothing
' Buscar o crear la hoja "DatImp"
For Each sheet As Worksheet In wb.Worksheets
If sheet.Name = "DatImp" Then
ws = sheet
Exit For
End If
Next
If ws Is Nothing Then
ws = CType(wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count)), Worksheet)
ws.Name = "DatImp"
End If
' Limpiar contenido previo
ws.Cells.Clear()
' --- Encabezados generales en la fila 1 ---
ws.Cells(1, 1).Value = "Nombre de Recurso"
ws.Cells(1, 2).Value = "Trabajo"
ws.Cells(1, 3).Value = "Autosuma"
' Desde la columna D en adelante se imprimirán los intervalos semanales
' --- Determinar los intervalos semanales (usando las fechas del proyecto) ---
Dim projectStart As DateTime = proj.Start
Dim projectFinish As DateTime = proj.Finish
' Ajustar projectStart para que sea un lunes (si no lo es, tomar el siguiente lunes)
Dim startOfWeek As DateTime = projectStart
If startOfWeek.DayOfWeek <> DayOfWeek.Monday Then
Dim daysToAdd As Integer = (CInt(DayOfWeek.Monday) - CInt(startOfWeek.DayOfWeek) + 7) Mod 7
startOfWeek = startOfWeek.AddDays(daysToAdd)
End If
' Calcular el número de semanas (redondeando hacia arriba)
Dim numWeeks As Integer = Math.Ceiling((projectFinish - startOfWeek).TotalDays / 7)
Dim intervalDates As New List(Of DateTime)
For i As Integer = 0 To numWeeks - 1
intervalDates.Add(startOfWeek.AddDays(i * 7))
Next
' --- Imprimir la cabecera de intervalos (fechas) a partir de la columna D en la fila 1 ---
Dim col As Integer = 4 ' Columna D
For Each intervalDate As DateTime In intervalDates
ws.Cells(1, col).NumberFormat = "@" ' Forzar formato de texto
ws.Cells(1, col).Value = intervalDate.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture)
col += 1
Next
' --- Desactivar actualización de pantalla y cálculo automático para mejorar el rendimiento ---
excelApp.ScreenUpdating = False
excelApp.Calculation = XlCalculation.xlCalculationManual
Dim currentRow As Integer = 2
' Iterar sobre cada recurso en el proyecto
For Each res As Resource In proj.Resources
If res IsNot Nothing AndAlso Not String.IsNullOrEmpty(res.Name) Then
' Datos generales para el recurso:
ws.Cells(currentRow, 1).Value = res.Name
ws.Cells(currentRow, 2).Value = res.Work / 60 ' Convertir minutos a horas
' Para cada intervalo, obtener la distribución del trabajo planeado para el recurso.
' Se usa el período global del proyecto (startOfWeek a projectFinish).
col = 4 ' Comenzar en la columna D
For Each intervalDate As DateTime In intervalDates
Dim intervalEnd As DateTime = intervalDate.AddDays(6)
Dim totalWork As Double = 0
Try
' Usar el tipo de dato correcto para recursos
Dim tsd As TimeScaleValues = res.TimeScaleData(
intervalDate, intervalEnd,
PjResourceTimescaledDataType2.pjResourceTimescaledWork,
PjTimescaleUnit2.pjTimescaleWeeks, 1)
If tsd IsNot Nothing AndAlso tsd.Count > 0 Then
totalWork = CDbl(tsd(1).Value) / 60 ' Convertir minutos a horas
End If
Catch ex As System.Exception
' Mensaje de depuración para inspeccionar errores
'Debug.WriteLine("Error al obtener datos escalados para el recurso " & res.Name & ": " & ex.Message)
totalWork = 0
End Try
ws.Cells(currentRow, col).Value = totalWork
col += 1
System.Windows.Forms.Application.DoEvents()
Next
' Insertar fórmula de autosuma en la columna C que sume las columnas D hasta la última columna de intervalo
Dim firstCell As String = ws.Cells(currentRow, 4).Address(False, False)
Dim lastCell As String = ws.Cells(currentRow, 3 + numWeeks).Address(False, False)
ws.Cells(currentRow, 3).Formula = "=SUM(" & firstCell & ":" & lastCell & ")"
' (Opcional) Se puede aplicar un color de fondo a la fila, si se desea. Para recursos se usa un color predeterminado.
ws.Rows(currentRow).Interior.Color = ColorTranslator.ToOle(Color.LightGray)
currentRow += 1
If currentRow Mod 10 = 0 Then
excelApp.ScreenUpdating = True
System.Windows.Forms.Application.DoEvents()
excelApp.ScreenUpdating = False
End If
End If
System.Windows.Forms.Application.DoEvents()
Next
excelApp.ScreenUpdating = True
excelApp.Calculation = XlCalculation.xlCalculationAutomatic
ws.Activate()
Dim freezeRange As Range = ws.Range("D2")
freezeRange.Select()
excelApp.ActiveWindow.FreezePanes = True
Dim msProjApp As MSProject.Application = proj.Application
msProjApp.Quit(MSProject.PjSaveType.pjDoNotSave)
System.Runtime.InteropServices.Marshal.ReleaseComObject(msProjApp)
MessageBox.Show("Datos de recursos y Trabajo Presupuestado exportados en la hoja 'DatImp'.",
"Exportación de Recursos", MessageBoxButtons.OK, MessageBoxIcon.Information)
Catch ex As System.Exception
MessageBox.Show("Error al exportar datos de recursos: " & ex.Message,
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
End Class
What could be wrong with my code?
Upvotes: 0
Views: 35