From 65f67ddd824950e7c8fe357d413253682d5d62f7 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sat, 1 Mar 2025 13:37:31 +0100 Subject: [PATCH] Primera version refactorizada --- Constants.vba | 22 ++++ ConsultarFechas.vba | 227 ++++++++++++++++++++++++++++++++++ DataProcessor.vba | 135 ++++++++++++++++++++ DateUtils.vba | 63 ++++++++++ ExportUtils.vba | 120 ++++++++++++++++++ Funciones.vba | 152 +++++++++++++++++++++++ MainModule.vba | 74 +++++++++++ Menu.vba | 73 +++++++++++ RefactoredConsultarFechas.vba | 29 +++++ RefactoredMenu.vba | 58 +++++++++ readme.txt | 64 ++++++++++ 11 files changed, 1017 insertions(+) create mode 100644 Constants.vba create mode 100644 ConsultarFechas.vba create mode 100644 DataProcessor.vba create mode 100644 DateUtils.vba create mode 100644 ExportUtils.vba create mode 100644 Funciones.vba create mode 100644 MainModule.vba create mode 100644 Menu.vba create mode 100644 RefactoredConsultarFechas.vba create mode 100644 RefactoredMenu.vba create mode 100644 readme.txt diff --git a/Constants.vba b/Constants.vba new file mode 100644 index 0000000..ae96606 --- /dev/null +++ b/Constants.vba @@ -0,0 +1,22 @@ +' Module: Constants +' Description: Contains application-wide constants + +' Sheet Names +Public Const SHEET_HORAS As String = "Horas" +Public Const SHEET_FDL_1 As String = "FDL_1" +Public Const SHEET_FDL_2 As String = "FDL_2" +Public Const SHEET_FDL_3 As String = "FDL_3" +Public Const SHEET_NOTA As String = "Nota" +Public Const SHEET_FOGLIO_1 As String = "Foglio 1" +Public Const SHEET_COMMESSE As String = "Commesse" + +' Row Constants +Public Const PRIMERA_FILA_FDL As Integer = 17 +Public Const MAX_ENTRIES_PER_FDL As Integer = 14 +Public Const MAX_TOTAL_ENTRIES As Integer = 42 + +' File Paths +Public Const PYTHON_EXE_PATH As String = "C:\Users\migue\miniconda3\envs\general\python.exe" +Public Const SCRIPT_PATH As String = "d:\Proyectos\Scripts\Horarios\InicioApagadoToExcel\LeerLogsToExcel.py" +Public Const LOG_FILE_PATH As String = "d:\Proyectos\Scripts\Horarios\InicioApagadoToExcel\python_log.txt" +Public Const LOG_EXCEL_PATH As String = "D:\Proyectos\Scripts\Horarios\InicioApagadoToExcel\LogEncendidoApagado.xlsx" diff --git a/ConsultarFechas.vba b/ConsultarFechas.vba new file mode 100644 index 0000000..b289d14 --- /dev/null +++ b/ConsultarFechas.vba @@ -0,0 +1,227 @@ +Dim b_Export As Boolean + +Private Sub b_completar_Click() + + b_Export = False + CopiarCeldas + + Unload Me + +End Sub + +Private Sub b_completar_exportar_Click() + + b_Export = True + CopiarCeldas + + Unload Me + +End Sub + + +Sub CopiarCeldas() + Dim wsHoras As Worksheet, wsFdl As Worksheet + Dim fechaDesde As Date, fechaHasta As Date + Dim ultimaFilaConDatos As Long, ultimaFilaHoras As Long + Dim i As Long, j As Long, k As Integer + Dim respuesta As VbMsgBoxResult + Dim nombreHojaHoras As String, nombreHojaFdl_1 As String, nombreHojaFdl_2 As String, nombreHojaFdl_3 As String, nombreHojaNota As String + Dim pdfExportado As Boolean + Const PrimeraFilaFDL = 17 + + + ' Nombres de las hojas en variables estáticas + nombreHojaHoras = "Horas" + nombreHojaFdl_1 = "FDL_1" + nombreHojaFdl_2 = "FDL_2" + nombreHojaFdl_3 = "FDL_3" + nombreHojaNota = "Nota" + + ' Establecer referencias a las hojas de trabajo + Set wsHoras = ThisWorkbook.Sheets(nombreHojaHoras) + Set wsFdl = ThisWorkbook.Sheets(nombreHojaFdl_1) + + ultimaFilaHoras = wsHoras.Cells(Rows.Count, 5).End(xlUp).Row + + ' Leer fechas desde los TextBox del formulario + On Error Resume Next + + + fechaDesde = GetDateFromForm(ConsultarFechas.t_desde.value) + fechaHasta = GetDateFromForm(ConsultarFechas.t_hasta.value) + + ' Escribir el numero de factura + ThisWorkbook.Sheets(nombreHojaNota).Cells(6, 3).value = ConsultarFechas.frm_factnro.value + + ' Validar que las fechas son correctas + If IsEmpty(fechaDesde) Or IsEmpty(fechaHasta) Then + MsgBox "Por favor, ingrese fechas válidas." + Exit Sub + End If + + On Error GoTo 0 + + ' Validar que las fechas son correctas + If IsEmpty(fechaDesde) Or IsEmpty(fechaHasta) Then + MsgBox "Por favor, ingrese fechas válidas." + Exit Sub + End If + + ' Comprobar que el rango de fechas no excede los 31 días + If fechaHasta - fechaDesde > 31 Then + MsgBox "El rango de fechas no puede exceder los 31 días." + Exit Sub + End If + + ' Preguntar al usuario si desea borrar el contenido selectivo de FDL_1 + 'respuesta = MsgBox("¿Desea borrar el contenido selectivo de la hoja FDL ?", vbYesNo) + 'If respuesta = vbYes Then + wsFdl.Range("A17:P44").ClearContents + ThisWorkbook.Sheets(nombreHojaFdl_2).Range("A17:P44").ClearContents + ThisWorkbook.Sheets(nombreHojaFdl_3).Range("A17:P44").ClearContents + 'End If + + + ' Iniciar variable para la fila de destino + j = PrimeraFilaFDL ' Puesto que quieres empezar desde la fila 17 en FDL_1 + k = 0 + + ' Recorrer cada fila en la hoja "Horas" + For i = 3 To ultimaFilaHoras + If CDate(wsHoras.Cells(i, 5).Value2) >= fechaDesde And CDate(wsHoras.Cells(i, 5).Value2) <= fechaHasta Then + ' Copiar la celda a la hoja "FDL_1/2/3" + wsFdl.Cells(j, 1).Value2 = wsHoras.Cells(i, 5).Value2 + wsFdl.Cells(j, 3).value = Format(wsHoras.Cells(i, 6).value, "hh:mm") + wsFdl.Cells(j, 4).value = wsHoras.Cells(i, 7).value + wsFdl.Cells(j, 5).value = wsHoras.Cells(i, 8).value + wsFdl.Cells(j, 6).value = wsHoras.Cells(i, 9).value + If wsHoras.Cells(i, 14).value > 0 Then wsFdl.Cells(j, 7).value = wsHoras.Cells(i, 14).value + If wsHoras.Cells(i, 15).value > 0 Then wsFdl.Cells(j, 8).value = wsHoras.Cells(i, 15).value + wsFdl.Cells(j, 10).value = wsHoras.Cells(i, 2).value + j = j + 2: k = k + 1 + pdfExportado = False + If k = 14 Then + ExportarAsPDF wsFdl, Format(fechaDesde, "dd-MM"), Format(wsFdl.Cells(j - 2, 1).Value2, "dd-MM") + + Set wsFdl = ThisWorkbook.Sheets(nombreHojaFdl_2) + j = PrimeraFilaFDL + pdfExportado = True + End If + If k = 28 Then + ExportarAsPDF wsFdl, Format(wsFdl.Cells(PrimeraFilaFDL, 1).Value2, "dd-MM"), Format(wsFdl.Cells(j - 2, 1).Value2, "dd-MM") + + Set wsFdl = ThisWorkbook.Sheets(nombreHojaFdl_3) + j = PrimeraFilaFDL + pdfExportado = True + End If + + ' Si j supera 42, salir del bucle + If k > 42 Then Exit For + End If + Next i + If Not pdfExportado Then + ExportarAsPDF wsFdl, Format(wsFdl.Cells(PrimeraFilaFDL, 1).Value2, "dd-MM"), Format(fechaHasta, "dd-MM") + End If + + ' Exportar la factura + ExportarAsPDF ThisWorkbook.Sheets(nombreHojaNota), "Fattura_" & Format(fechaDesde, "dd-MM"), Format(fechaHasta, "dd-MM") + + ' Exportar la factura + ExportarAsPDF ThisWorkbook.Sheets("Foglio 1"), "Expenses_" & Format(fechaDesde, "dd-MM"), Format(fechaHasta, "dd-MM") + + ExportarAsXLS "Expenses_" & Format(fechaDesde, "dd-MM"), Format(fechaHasta, "dd-MM") + + ' Limpiar objetos + Set wsFdl = Nothing + +End Sub + + +Private Sub ExportarAsPDF(wsFdl As Worksheet, fechaDesde As String, fechaHasta As String) + Dim rutaPDF As String + Dim nombreArchivo As String + + If b_Export Then + + ' Construir el nombre del archivo PDF basado en las fechas + nombreArchivo = "fdl_" & fechaDesde & " al " & fechaHasta & ".pdf" + + + ' Mostrar el cuadro de diálogo "Guardar como" y obtener la ruta seleccionada + rutaPDF = Application.GetSaveAsFilename(InitialFileName:=nombreArchivo, _ + FileFilter:="PDF Files (*.pdf), *.pdf", Title:="Guardar como PDF") + + ' Comprobar si el usuario ha cancelado el cuadro de diálogo + If (rutaPDF <> "False") And (rutaPDF <> "Falso") Then + ' Exportar la hoja como PDF + wsFdl.ExportAsFixedFormat Type:=xlTypePDF, Filename:=rutaPDF, _ + Quality:=xlQualityStandard, IncludeDocProperties:=True, _ + IgnorePrintAreas:=False, OpenAfterPublish:=False + End If + + End If +End Sub + +Private Sub ExportarAsXLS(fechaDesde As String, fechaHasta As String) + Dim rutaPDF As String + Dim nombreArchivo As String + + If b_Export Then + + ' Construir el nombre del archivo PDF basado en las fechas + nombreArchivo = "fdl_" & fechaDesde & " al " & fechaHasta & ".xlsx" + + + ' Mostrar el cuadro de diálogo "Guardar como" y obtener la ruta seleccionada + rutaPDF = Application.GetSaveAsFilename(InitialFileName:=nombreArchivo, _ + FileFilter:="XLS Files (*.xlsx), *.xlsx", Title:="Guardar como XLS") + + ' Comprobar si el usuario ha cancelado el cuadro de diálogo + If (rutaPDF <> "False") And (rutaPDF <> "Falso") Then + ' Exportar la hoja como PDF + + Dim Hoja1 As Worksheet, Hoja2 As Worksheet, Hoja3 As Worksheet, Hoja4 As Worksheet, Hoja5 As Worksheet + Dim NuevoLibro As Workbook + + ' Ajusta los nombres de las hojas a los que necesitas + Set Hoja1 = ThisWorkbook.Sheets("Nota") + Set Hoja2 = ThisWorkbook.Sheets("FDL_1") + Set Hoja3 = ThisWorkbook.Sheets("FDL_2") + Set Hoja4 = ThisWorkbook.Sheets("FDL_3") + Set Hoja5 = ThisWorkbook.Sheets("Foglio 1") + + + ' Copia las hojas a un nuevo libro + Hoja1.Copy + Set NuevoLibro = ActiveWorkbook + + ' Con el nuevo libro activo, copia la segunda hoja + Hoja2.Copy After:=NuevoLibro.Sheets(1) + Hoja3.Copy After:=NuevoLibro.Sheets(2) + Hoja4.Copy After:=NuevoLibro.Sheets(3) + Hoja5.Copy After:=NuevoLibro.Sheets(4) + + ' Guarda el nuevo libro como archivo .xls + ' Cambia la ruta de archivo y el nombre según necesites + NuevoLibro.SaveAs rutaPDF, FileFormat:=xlWorkbookDefault + + ' Cierra el nuevo libro sin guardar cambios + NuevoLibro.Close SaveChanges:=False + + End If + + End If +End Sub + + + +Public Function GetDateFromForm(value As String) As Date + Dim partesFecha() As String + + ' Leer fecha desde el TextBox t_desde + partesFecha = Split(value, "/") + On Error Resume Next + GetDateFromForm = DateSerial(CInt(partesFecha(2)), CInt(partesFecha(1)), CInt(partesFecha(0))) + On Error GoTo 0 +End Function + diff --git a/DataProcessor.vba b/DataProcessor.vba new file mode 100644 index 0000000..1736a9b --- /dev/null +++ b/DataProcessor.vba @@ -0,0 +1,135 @@ +' Module: DataProcessor +' Description: Core data processing functions + +Public Sub ProcessWorkHourData(fechaDesde As Date, fechaHasta As Date, exportResults As Boolean, facturaNum As String) + Dim wsHoras As Worksheet, wsFdl As Worksheet + Dim ultimaFilaHoras As Long + Dim i As Long, j As Long, k As Integer + Dim pdfExportado As Boolean + + ' Update invoice number + ThisWorkbook.Sheets(SHEET_NOTA).Cells(6, 3).Value = facturaNum + + ' Validate date range + If Not ValidateDateRange(fechaDesde, fechaHasta) Then + Exit Sub + End If + + ' Clear existing content in FDL sheets + ClearFDLSheets + + ' Set references to worksheets + Set wsHoras = ThisWorkbook.Sheets(SHEET_HORAS) + Set wsFdl = ThisWorkbook.Sheets(SHEET_FDL_1) + + ultimaFilaHoras = wsHoras.Cells(Rows.Count, 5).End(xlUp).Row + + ' Initialize variables for destination row and entry count + j = PRIMERA_FILA_FDL + k = 0 + + ' Process each row in Horas sheet + For i = 3 To ultimaFilaHoras + If CDate(wsHoras.Cells(i, 5).Value2) >= fechaDesde And CDate(wsHoras.Cells(i, 5).Value2) <= fechaHasta Then + ' Copy data to current FDL sheet + CopyRowToFDL wsHoras, wsFdl, i, j + + j = j + 2: k = k + 1 + pdfExportado = False + + ' Handle sheet transitions at MAX_ENTRIES_PER_FDL entries + If k = MAX_ENTRIES_PER_FDL Then + If exportResults Then + ExportToPDF wsFdl, Format(fechaDesde, "dd-MM"), Format(wsFdl.Cells(j - 2, 1).Value2, "dd-MM") + End If + + Set wsFdl = ThisWorkbook.Sheets(SHEET_FDL_2) + j = PRIMERA_FILA_FDL + pdfExportado = True + End If + + ' Handle sheet transitions at MAX_ENTRIES_PER_FDL * 2 entries + If k = MAX_ENTRIES_PER_FDL * 2 Then + If exportResults Then + ExportToPDF wsFdl, Format(wsFdl.Cells(PRIMERA_FILA_FDL, 1).Value2, "dd-MM"), Format(wsFdl.Cells(j - 2, 1).Value2, "dd-MM") + End If + + Set wsFdl = ThisWorkbook.Sheets(SHEET_FDL_3) + j = PRIMERA_FILA_FDL + pdfExportado = True + End If + + ' Exit if we exceed maximum entries + If k > MAX_TOTAL_ENTRIES Then Exit For + End If + Next i + + ' Export final sheet if not already exported + If exportResults And Not pdfExportado Then + ExportToPDF wsFdl, Format(wsFdl.Cells(PRIMERA_FILA_FDL, 1).Value2, "dd-MM"), Format(fechaHasta, "dd-MM") + End If + + ' Export additional documents if needed + If exportResults Then + ExportToPDF ThisWorkbook.Sheets(SHEET_NOTA), "Fattura_" & Format(fechaDesde, "dd-MM"), Format(fechaHasta, "dd-MM") + ExportToPDF ThisWorkbook.Sheets(SHEET_FOGLIO_1), "Expenses_" & Format(fechaDesde, "dd-MM"), Format(fechaHasta, "dd-MM") + ExportToExcel Format(fechaDesde, "dd-MM"), Format(fechaHasta, "dd-MM") + End If +End Sub + +Private Sub CopyRowToFDL(wsSource As Worksheet, wsTarget As Worksheet, sourceRow As Long, targetRow As Long) + ' Copy data from source row to target row in FDL sheet + wsTarget.Cells(targetRow, 1).Value2 = wsSource.Cells(sourceRow, 5).Value2 + wsTarget.Cells(targetRow, 3).Value = Format(wsSource.Cells(sourceRow, 6).Value, "hh:mm") + wsTarget.Cells(targetRow, 4).Value = wsSource.Cells(sourceRow, 7).Value + wsTarget.Cells(targetRow, 5).Value = wsSource.Cells(sourceRow, 8).Value + wsTarget.Cells(targetRow, 6).Value = wsSource.Cells(sourceRow, 9).Value + + ' Set optional values only if they're greater than 0 + If wsSource.Cells(sourceRow, 14).Value > 0 Then + wsTarget.Cells(targetRow, 7).Value = wsSource.Cells(sourceRow, 14).Value + End If + + If wsSource.Cells(sourceRow, 15).Value > 0 Then + wsTarget.Cells(targetRow, 8).Value = wsSource.Cells(sourceRow, 15).Value + End If + + wsTarget.Cells(targetRow, 10).Value = wsSource.Cells(sourceRow, 2).Value +End Sub + +Private Sub ClearFDLSheets() + ' Clear content in all FDL sheets + ThisWorkbook.Sheets(SHEET_FDL_1).Range("A17:P44").ClearContents + ThisWorkbook.Sheets(SHEET_FDL_2).Range("A17:P44").ClearContents + ThisWorkbook.Sheets(SHEET_FDL_3).Range("A17:P44").ClearContents +End Sub + +Public Sub RunPythonLogProcessor() + Dim objShell As Object + + ' Create shell object + Set objShell = VBA.CreateObject("WScript.Shell") + + ' Execute Python script + objShell.Run "cmd /c " & PYTHON_EXE_PATH & " " & SCRIPT_PATH & " > " & LOG_FILE_PATH & " 2>&1", 0, True + Set objShell = Nothing +End Sub + +Public Sub RefreshLogData() + Dim wb As Workbook + + ' Open log Excel file + Set wb = Workbooks.Open(LOG_EXCEL_PATH) + + ' Refresh all connections + wb.RefreshAll + + ' Wait for refresh to complete + Application.Wait Now + TimeValue("00:00:05") + + ' Close without saving + wb.Close SaveChanges:=False + + ' Refresh current workbook + ThisWorkbook.RefreshAll +End Sub diff --git a/DateUtils.vba b/DateUtils.vba new file mode 100644 index 0000000..b048f75 --- /dev/null +++ b/DateUtils.vba @@ -0,0 +1,63 @@ +' Module: DateUtils +' Description: Functions for date manipulation and validation + +Public Function GetDateFromString(value As String) As Date + Dim partesFecha() As String + + ' Parse date from string in format dd/mm/yyyy + partesFecha = Split(value, "/") + On Error Resume Next + GetDateFromString = DateSerial(CInt(partesFecha(2)), CInt(partesFecha(1)), CInt(partesFecha(0))) + On Error GoTo 0 +End Function + +Public Function ValidateDateRange(fechaDesde As Date, fechaHasta As Date) As Boolean + ' Check if dates are valid + If IsEmpty(fechaDesde) Or IsEmpty(fechaHasta) Then + MsgBox "Por favor, ingrese fechas válidas." + ValidateDateRange = False + Exit Function + End If + + ' Check that date range doesn't exceed 31 days + If fechaHasta - fechaDesde > 31 Then + MsgBox "El rango de fechas no puede exceder los 31 días." + ValidateDateRange = False + Exit Function + End If + + ValidateDateRange = True +End Function + +Public Function GetDefaultEndDate() As Date + Dim wsHoras As Worksheet + Dim ultimaFilaConDatos As Long + + ' Get last date from Horas sheet + Set wsHoras = ThisWorkbook.Sheets(SHEET_HORAS) + ultimaFilaConDatos = wsHoras.Range("F:M").Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row + + GetDefaultEndDate = wsHoras.Cells(ultimaFilaConDatos, 5).Value2 +End Function + +Public Function GetDefaultStartDate(fechaHasta As Date) As Date + ' Default to 28 days before end date + GetDefaultStartDate = DateAdd("d", -28, fechaHasta) +End Function + +Public Function SumarPorMes(rangoFechas As Range, mes As Integer, rangoSuma As Range) As Double + Dim sumaTotal As Double + Dim i As Integer + + On Error Resume Next + sumaTotal = 0 + + ' Sum values where month matches + For i = 1 To rangoFechas.Count + If Month(rangoFechas.Cells(i).Value2) = mes Then + sumaTotal = sumaTotal + rangoSuma.Cells(i).Value2 + End If + Next i + + SumarPorMes = sumaTotal +End Function diff --git a/ExportUtils.vba b/ExportUtils.vba new file mode 100644 index 0000000..5ad6a86 --- /dev/null +++ b/ExportUtils.vba @@ -0,0 +1,120 @@ +' Module: ExportUtils +' Description: Functions for exporting data to different formats + +Public Function ExportToPDF(ws As Worksheet, fechaDesde As String, fechaHasta As String) As Boolean + Dim rutaPDF As String + Dim nombreArchivo As String + + ' Construct PDF filename based on the dates + nombreArchivo = "fdl_" & fechaDesde & " al " & fechaHasta & ".pdf" + + ' Show "Save As" dialog and get the selected path + rutaPDF = Application.GetSaveAsFilename(InitialFileName:=nombreArchivo, _ + FileFilter:="PDF Files (*.pdf), *.pdf", Title:="Guardar como PDF") + + ' Check if user cancelled the dialog + If (rutaPDF <> "False") And (rutaPDF <> "Falso") Then + ' Export sheet as PDF + ws.ExportAsFixedFormat Type:=xlTypePDF, Filename:=rutaPDF, _ + Quality:=xlQualityStandard, IncludeDocProperties:=True, _ + IgnorePrintAreas:=False, OpenAfterPublish:=False + ExportToPDF = True + Else + ExportToPDF = False + End If +End Function + +Public Function ExportToExcel(fechaDesde As String, fechaHasta As String) As Boolean + Dim rutaPDF As String + Dim nombreArchivo As String + + ' Construct Excel filename based on dates + nombreArchivo = "fdl_" & fechaDesde & " al " & fechaHasta & ".xlsx" + + ' Show "Save As" dialog and get the selected path + rutaPDF = Application.GetSaveAsFilename(InitialFileName:=nombreArchivo, _ + FileFilter:="XLS Files (*.xlsx), *.xlsx", Title:="Guardar como XLS") + + ' Check if user cancelled the dialog + If (rutaPDF <> "False") And (rutaPDF <> "Falso") Then + Dim Hoja1 As Worksheet, Hoja2 As Worksheet, Hoja3 As Worksheet, Hoja4 As Worksheet, Hoja5 As Worksheet + Dim NuevoLibro As Workbook + + ' Set references to sheets + Set Hoja1 = ThisWorkbook.Sheets(SHEET_NOTA) + Set Hoja2 = ThisWorkbook.Sheets(SHEET_FDL_1) + Set Hoja3 = ThisWorkbook.Sheets(SHEET_FDL_2) + Set Hoja4 = ThisWorkbook.Sheets(SHEET_FDL_3) + Set Hoja5 = ThisWorkbook.Sheets(SHEET_FOGLIO_1) + + ' Copy sheets to new workbook + Hoja1.Copy + Set NuevoLibro = ActiveWorkbook + + ' Copy remaining sheets + Hoja2.Copy After:=NuevoLibro.Sheets(1) + Hoja3.Copy After:=NuevoLibro.Sheets(2) + Hoja4.Copy After:=NuevoLibro.Sheets(3) + Hoja5.Copy After:=NuevoLibro.Sheets(4) + + ' Save and close + NuevoLibro.SaveAs rutaPDF, FileFormat:=xlWorkbookDefault + NuevoLibro.Close SaveChanges:=False + + ExportToExcel = True + Else + ExportToExcel = False + End If +End Function + +Public Function ExportComessaToExcel() As Boolean + Dim rutaPDF As String + Dim nombreArchivo As String + Dim wsComesse As Worksheet + Dim fechaDesde As Date + Dim n As Integer + + ' Set reference to Commesse sheet + Set wsComesse = ThisWorkbook.Sheets(SHEET_COMMESSE) + + ' Find the date to use in filename + For n = 1 To 7 + If wsComesse.Cells(8, 2 * n).Value2 <> 0 Then + fechaDesde = wsComesse.Cells(2, 2 * n).Value2 + End If + Next n + + ' Build filename + nombreArchivo = "C:\Users\migue\OneDrive\Miguel\CSA - Trabajo\2024\Angelo Comesse\" + _ + "Ore " & Format(fechaDesde, "dd-MM") & " Vera Miguel.xlsx" + + ' Show Save dialog + rutaPDF = Application.GetSaveAsFilename(InitialFileName:=nombreArchivo, _ + FileFilter:="XLS Files (*.xlsx), *.xlsx", Title:="Guardar como XLS") + + If (rutaPDF <> "False") And (rutaPDF <> "Falso") Then + Dim NuevoLibro As Workbook + Dim NuevaHoja As Worksheet + + ' Create new workbook and copy data + Set NuevoLibro = Workbooks.Add + Set NuevaHoja = NuevoLibro.Sheets(1) + + wsComesse.Cells.Copy + With NuevaHoja.Cells + .PasteSpecial Paste:=xlPasteValues + .PasteSpecial Paste:=xlPasteFormats + End With + Application.CutCopyMode = False + + ' Save the new workbook + NuevoLibro.SaveAs rutaPDF, FileFormat:=xlWorkbookDefault + + ' Close the new workbook + NuevoLibro.Close SaveChanges:=False + + ExportComessaToExcel = True + Else + ExportComessaToExcel = False + End If +End Function \ No newline at end of file diff --git a/Funciones.vba b/Funciones.vba new file mode 100644 index 0000000..8d3f513 --- /dev/null +++ b/Funciones.vba @@ -0,0 +1,152 @@ +Public Sub CargarFDL() + Dim wsHoras As Worksheet + Dim fechaDesde As Date, fechaHasta As Date + Dim ultimaFilaConDatos As Long, ultimaFilaHoras As Long + Dim i As Long, j As Long + Dim nombreHojaHoras As String, nombreHojaFdl_1 As String, nombreHojaNota As String + Dim rangoSeleccionado As Range + + ' Nombres de las hojas en variables estáticas + nombreHojaHoras = "Horas" + nombreHojaNota = "Nota" + + ' Establecer referencias a las hojas de trabajo + Set wsHoras = ThisWorkbook.Sheets(nombreHojaHoras) + + ' Verificar si hay un rango seleccionado en la hoja "Horas" y en la columna E + If Not Application.Selection Is Nothing Then + Set rangoSeleccionado = Application.Selection + If rangoSeleccionado.Worksheet.Name = "Horas" And rangoSeleccionado.EntireColumn.Address = wsHoras.Columns("E").Address Then + ' Si es así, usar las fechas en el rango seleccionado + fechaDesde = rangoSeleccionado.Cells(1, 1).Value2 + fechaHasta = rangoSeleccionado.Cells(rangoSeleccionado.Rows.Count, 1).Value2 + End If + End If + + ' Si no hay una selección apropiada, utilizar otro método para determinar las fechas + If fechaDesde = 0 Or fechaHasta = 0 Then + ' Encontrar la última fila con datos en las columnas F:M en la hoja "Horas" + ultimaFilaConDatos = wsHoras.Range("F:M").Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row + ultimaFilaHoras = wsHoras.Cells(Rows.Count, 5).End(xlUp).Row + + ' Establecer la fechaDesde y fechaHasta según la última fila con datos en la columna E + fechaHasta = wsHoras.Cells(ultimaFilaConDatos, 5).Value2 + fechaDesde = DateAdd("d", -28, fechaHasta) + End If + + ' Establecer las fechas por defecto en los TextBox + ConsultarFechas.t_hasta.value = Format(fechaHasta, "dd/mm/yyyy") + ConsultarFechas.t_desde.value = Format(fechaDesde, "dd/mm/yyyy") + + ' Obtener ultimo numero de Factura + ConsultarFechas.frm_factnro.value = ThisWorkbook.Sheets(nombreHojaNota).Cells(6, 3).value + + ConsultarFechas.Show + + +End Sub + +' C:/Users/migue/miniconda3/envs/general/python.exe d:/Proyectos/Scripts/InicioApagadoToExcel/LeerLogsToExcel.py + +Sub RunLeerLogsToExcel() + + Python_ActualizarLogsHorarios + + ActualizarDatos + +End Sub + +Sub AbrirLogsHorarios() + + Dim wb As Workbook + + ' Abre el libro de trabajo especificado + Set wb = Workbooks.Open("D:\Proyectos\Scripts\Horarios\InicioApagadoToExcel\LogEncendidoApagado.xlsx") + + ' Actualiza todas las conexiones del libro de trabajo abierto + wb.RefreshAll + +End Sub + +Sub Python_ActualizarLogsHorarios() + + Dim objShell As Object + Dim PythonExePath As String + Dim PythonScriptPath As String + + + ' Define la ruta del ejecutable de Python + PythonExePath = "C:\Users\migue\miniconda3\envs\general\python.exe" + + ' Define la ruta de tu script de Python + PythonScriptPath = "d:\Proyectos\Scripts\Horarios\InicioApagadoToExcel\LeerLogsToExcel.py" + + ' Define la ruta del archivo donde se guardarán los logs + Dim LogFilePath As String + LogFilePath = "d:\Proyectos\Scripts\Horarios\InicioApagadoToExcel\python_log.txt" + + ' Crear un objeto Shell + Set objShell = VBA.CreateObject("WScript.Shell") + + + ' Ejecutar el script de Python + objShell.Run "cmd /c " & PythonExePath & " " & PythonScriptPath & " > " & LogFilePath & " 2>&1", 0, True + Set objShell = Nothing + + +End Sub + + +Sub ActualizarDatos() + Dim wb As Workbook + + ' Abre el libro de trabajo especificado + Set wb = Workbooks.Open("D:\Proyectos\Scripts\Horarios\InicioApagadoToExcel\LogEncendidoApagado.xlsx") + + ' Actualiza todas las conexiones del libro de trabajo abierto + wb.RefreshAll + + ' Espera un tiempo específico para que se completen las actualizaciones + ' Por ejemplo, espera 5 segundos. Ajusta este tiempo según sea necesario + Application.Wait Now + TimeValue("00:00:05") + + ' Cierra el libro de trabajo sin guardar los cambios + wb.Close SaveChanges:=False + + ' Actualiza todas las conexiones del libro de trabajo actual (opcional) + ThisWorkbook.RefreshAll +End Sub + +Sub SaveComessas() + Menu.b_gen_hoja_comessas_Click +End Sub + +Public Sub CargarMENU() + + Menu.Show + +End Sub + +Public Function SumarPorMes(rangoFechas As Range, mes As Integer, rangoSuma As Range) As Double + Dim sumaTotal As Double + Dim i As Integer + + On Error Resume Next + sumaTotal = 0 + + ' Recorre el rango de fechas y suma los valores si el mes coincide + For i = 1 To rangoFechas.Count + If Month(rangoFechas.Cells(i).Value2) = mes Then + sumaTotal = sumaTotal + rangoSuma.Cells(i).Value2 + End If + Next i + + SumarPorMes = sumaTotal +End Function + +Public Sub Test() + Dim resultado As Double + resultado = SumarPorMes(Sheets("Horas").Range("E3:E367"), 9, Sheets("Horas").Range("O3:O367")) + Debug.Print "La suma para el mes 9 es: " & resultado +End Sub + diff --git a/MainModule.vba b/MainModule.vba new file mode 100644 index 0000000..e91ba62 --- /dev/null +++ b/MainModule.vba @@ -0,0 +1,74 @@ +' Module: MainModule +' Description: Main entry points for the application + +Public Sub ShowMenu() + ' Display the main menu form + Menu.Show +End Sub + +Public Sub ProcessLogs() + ' Update logs and refresh data + RunPythonLogProcessor + RefreshLogData +End Sub + +Public Sub GenerateInvoice() + ' Generate invoice by showing date selection form + ShowDateSelectionForm +End Sub + +Public Sub ExportCommessaSheet() + ' Export Comesse sheet to Excel + ExportComessaToExcel +End Sub + +' Helper function to display date selection form +Private Sub ShowDateSelectionForm() + Dim wsHoras As Worksheet + Dim fechaDesde As Date, fechaHasta As Date + Dim rangoSeleccionado As Range + + ' Set reference to Horas sheet + Set wsHoras = ThisWorkbook.Sheets(SHEET_HORAS) + + ' Check if there's a selected range in Horas sheet and column E + If Not Application.Selection Is Nothing Then + Set rangoSeleccionado = Application.Selection + If rangoSeleccionado.Worksheet.Name = SHEET_HORAS And _ + rangoSeleccionado.EntireColumn.Address = wsHoras.Columns("E").Address Then + ' Use dates from selected range + fechaDesde = rangoSeleccionado.Cells(1, 1).Value2 + fechaHasta = rangoSeleccionado.Cells(rangoSeleccionado.Rows.Count, 1).Value2 + End If + End If + + ' If no appropriate selection, use default date calculation + If fechaDesde = 0 Or fechaHasta = 0 Then + fechaHasta = GetDefaultEndDate() + fechaDesde = GetDefaultStartDate(fechaHasta) + End If + + ' Set default values in the form + ConsultarFechas.t_hasta.Value = Format(fechaHasta, "dd/mm/yyyy") + ConsultarFechas.t_desde.Value = Format(fechaDesde, "dd/mm/yyyy") + + ' Set invoice number + ConsultarFechas.frm_factnro.Value = ThisWorkbook.Sheets(SHEET_NOTA).Cells(6, 3).Value + + ' Show form + ConsultarFechas.Show +End Sub + +Public Sub RunDiagnostic() + ' Run a diagnostic test + Debug.Print "System Diagnostics:" + Debug.Print "-------------------" + Debug.Print "Python Path: " & PYTHON_EXE_PATH + Debug.Print "Script Path: " & SCRIPT_PATH + Debug.Print "Log Path: " & LOG_FILE_PATH + Debug.Print "Excel Log Path: " & LOG_EXCEL_PATH + + Dim testResult As Double + testResult = SumarPorMes(Sheets(SHEET_HORAS).Range("E3:E367"), Month(Date), Sheets(SHEET_HORAS).Range("O3:O367")) + Debug.Print "Test sum for current month: " & testResult +End Sub diff --git a/Menu.vba b/Menu.vba new file mode 100644 index 0000000..416af08 --- /dev/null +++ b/Menu.vba @@ -0,0 +1,73 @@ +Private Sub b_cargar_logs_Click() + RunLeerLogsToExcel + Unload Me +End Sub + +Private Sub b_gen_factura_Click() + CargarFDL.CargarFDL + Unload Me +End Sub + + + +Public Sub b_gen_hoja_comessas_Click() + Dim rutaPDF As String + Dim nombreArchivo As String + + Dim wsComesse As Worksheet + Dim fechaDesde As Date, fechaHasta As Date + Dim nombreComesseHoras As String + Dim n As Integer + + ' Nombres de las hojas en variables estáticas + nombreHojaHoras = "Horas" + nombreComesseHoras = "Commesse" + + ' Establecer referencias a las hojas de Comesse + Set wsComesse = ThisWorkbook.Sheets(nombreComesseHoras) + + For n = 1 To 7 + If wsComesse.Cells(8, 2 * n).Value2 <> 0 Then + ' Establecer la fechaDesde y fechaHasta según la última fila con datos en la columna E + fechaDesde = wsComesse.Cells(2, 2 * n).Value2 + End If + Next n + ' Construir el nombre del archivo PDF basado en las fechas - Ore 16-09 Vera Miguel.xlsx + nombreArchivo = "C:\Users\migue\OneDrive\Miguel\CSA - Trabajo\2024\Angelo Comesse\" + "Ore " & Format(fechaDesde, "dd-MM") & " Vera Miguel.xlsx" + + ' Mostrar el cuadro de diálogo "Guardar como" y obtener la ruta seleccionada + rutaPDF = Application.GetSaveAsFilename(InitialFileName:=nombreArchivo, _ + FileFilter:="XLS Files (*.xlsx), *.xlsx", Title:="Guardar como XLS") + + ' Comprobar si el usuario ha cancelado el cuadro de diálogo + If (rutaPDF <> "False") And (rutaPDF <> "Falso") Then + Dim Hoja1 As Worksheet + Dim NuevoLibro As Workbook + Dim NuevaHoja As Worksheet + + ' Ajusta los nombres de las hojas a los que necesitas + Set Hoja1 = ThisWorkbook.Sheets(nombreComesseHoras) + + ' Crea un nuevo libro + Set NuevoLibro = Workbooks.Add + Set NuevaHoja = NuevoLibro.Sheets(1) + + ' Copia las celdas como valores desde la hoja original a la nueva hoja + Hoja1.Cells.Copy + With NuevaHoja.Cells + .PasteSpecial Paste:=xlPasteValues + .PasteSpecial Paste:=xlPasteFormats + End With + Application.CutCopyMode = False + + ' Guarda el nuevo libro como archivo .xls + ' Cambia la ruta de archivo y el nombre según necesites + NuevoLibro.SaveAs rutaPDF, FileFormat:=xlWorkbookDefault + + ' Cierra el nuevo libro sin guardar cambios + NuevoLibro.Close SaveChanges:=False + End If + Unload Me +End Sub + + diff --git a/RefactoredConsultarFechas.vba b/RefactoredConsultarFechas.vba new file mode 100644 index 0000000..dbc0b83 --- /dev/null +++ b/RefactoredConsultarFechas.vba @@ -0,0 +1,29 @@ +' Form module: ConsultarFechas +' Description: Date selection form with refactored code + +Dim b_Export As Boolean + +Private Sub b_completar_Click() + ' Process data without exporting + b_Export = False + ProcessFormData + Unload Me +End Sub + +Private Sub b_completar_exportar_Click() + ' Process data and export + b_Export = True + ProcessFormData + Unload Me +End Sub + +Private Sub ProcessFormData() + Dim fechaDesde As Date, fechaHasta As Date + + ' Parse dates from form inputs + fechaDesde = GetDateFromString(Me.t_desde.Value) + fechaHasta = GetDateFromString(Me.t_hasta.Value) + + ' Process the work hour data + ProcessWorkHourData fechaDesde, fechaHasta, b_Export, Me.frm_factnro.Value +End Sub diff --git a/RefactoredMenu.vba b/RefactoredMenu.vba new file mode 100644 index 0000000..1bfe32e --- /dev/null +++ b/RefactoredMenu.vba @@ -0,0 +1,58 @@ +' Form module: Menu +' Description: Main application menu with refactored code + +Private Sub b_cargar_logs_Click() + ' Process logs and update data + RunPythonLogProcessor + RefreshLogData + Unload Me +End Sub + +Private Sub b_gen_factura_Click() + ' Show the date selection form + ShowDateSelectionForm + Unload Me +End Sub + +Public Sub b_gen_hoja_comessas_Click() + ' Export Comesse to Excel + ExportComessaToExcel + Unload Me +End Sub + +' Helper method to display the date selection form +Private Sub ShowDateSelectionForm() + Dim wsHoras As Worksheet + Dim fechaDesde As Date, fechaHasta As Date + Dim rangoSeleccionado As Range + + ' Set reference to Horas sheet + Set wsHoras = ThisWorkbook.Sheets(SHEET_HORAS) + + ' Check if there's a selected range in Horas sheet and column E + If Not Application.Selection Is Nothing Then + Set rangoSeleccionado = Application.Selection + If rangoSeleccionado.Worksheet.Name = SHEET_HORAS And _ + rangoSeleccionado.EntireColumn.Address = wsHoras.Columns("E").Address Then + ' Use dates from selected range + fechaDesde = rangoSeleccionado.Cells(1, 1).Value2 + fechaHasta = rangoSeleccionado.Cells(rangoSeleccionado.Rows.Count, 1).Value2 + End If + End If + + ' If no appropriate selection, use default date calculation + If fechaDesde = 0 Or fechaHasta = 0 Then + fechaHasta = GetDefaultEndDate() + fechaDesde = GetDefaultStartDate(fechaHasta) + End If + + ' Set default values in the form + ConsultarFechas.t_hasta.Value = Format(fechaHasta, "dd/mm/yyyy") + ConsultarFechas.t_desde.Value = Format(fechaDesde, "dd/mm/yyyy") + + ' Set invoice number + ConsultarFechas.frm_factnro.Value = ThisWorkbook.Sheets(SHEET_NOTA).Cells(6, 3).Value + + ' Show form + ConsultarFechas.Show +End Sub diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..776663f --- /dev/null +++ b/readme.txt @@ -0,0 +1,64 @@ +Work Hours Management System +This VBA-based system helps manage work hours, generate reports, and create invoices. + +Core Components +1. Menu System (Menu.vba) +Provides the main interface for accessing different functionalities +Features: +Load work logs +Generate invoices +Export work commission sheets ("comesse") + +2. Date Query Interface (ConsultarFechas.vba) +Handles date-based operations and report generation +Key features: +Date range selection +PDF export functionality +Excel export functionality +Multi-sheet FDL report generation (FDL_1, FDL_2, FDL_3) +3. Core Module (Modulo.vba) +Contains core functionality including: +FDL report loading +Python script integration for log processing +Monthly sum calculations +Data refresh operations +Key Features +Work Log Management + +Automatic log reading and Excel conversion +Integration with Python scripts for log processing +Automated data refresh capabilities +Report Generation + +PDF export functionality +Excel workbook export +Support for multiple FDL sheets +Invoice generation +Date Management + +Flexible date range selection +Monthly data aggregation +Date validation and error handling +Usage +Opening the System + +Generating Reports + +Use the menu interface to select desired operation +Choose date ranges when prompted +Select export location for generated files +Working with Logs + +Technical Notes +The system supports up to 31-day periods for report generation +Automatically handles multi-page reports (up to 42 entries) +Integrates with external Python scripts for log processing +Supports both PDF and Excel export formats +Dependencies +Excel with VBA support +Python environment (for log processing) +Required Excel sheets: +Horas +FDL_1, FDL_2, FDL_3 +Nota +Foglio 1 \ No newline at end of file