Modelo de Factura con macros para imprimir, exportar a PDF y generar resúmenes
Tras varias consultas realizadas en el Foro Oficial en español al respecto, ponemos a vuestra disposición este modelo para emitir facturas en OpenOffice Calc, que sirve también para LibreOffice Calc.
El modelo no pretende ser una solución de facturación; tan sólo es un ejemplo de cómo utilizar algunas técnicas avanzadas en la hoja de cálculo y de cómo automatizar determinadas tareas mediante el uso de macros, creadas con la grabadora de macros, y levemente adaptadas.
Por supuesto que el modelo es muy mejorable, y cada uno deberá, si pretende utilizarlo, adaptarlo a sus necesidades. Nuestra intención es ilustrar algunas de las posibilidades y dar pistas de cómo aplicarlas.
Veamos sin más las técnicas utilizadas en el mismo.
Encabezado de la factura
Logotipo y datos de la empresa
Tras insertar una imagen (Insertar > Imagen > Desde archivo...), que tras ajustarla en posición y tamaño, ha sido bloqueada enviándola al fondo de la hoja desde su menú contextual > Posición > En el fondo. Para poder seleccionarla, consulta Seleccionar una imagen situada en el fondo de la hoja
Para los datos de la empresa que factura hemos utilizada Ctrl+Intro en modo edición para insertar varias líneas en la celda, y hemos aplicado diferentes propiedades a los texto siguiendo el sistema comentado en este artículo: Aplicar varios formatos al texto de una celda en Calc.
Numerador de factura
Símplemente se ha añadido desde la barra de herramientas Campos de control de formulario (podemos mostrarla desde el menú Ver > Barras de herramientas) un Botón de selección; en modo diseño de formulario (segundo botón de la barra de herramientas) editamos las propiedades del Control (tercer botón de la barra de herramientas con el control seleccionado); desde la ficha Datos lo hemos relacionado con la celda C3. Desde la ficha General hemos definido el valor máximo en 10.000.000.
Botones para lanzar macros
Desde esta misma barra de herramientas hemos añadido con su herramienta Botón los botones para lanzar las macros (octavo botón en la barra); editando sus propiedades desde la pestaña Acontecimientos, asignamos las macros creadas previamente a los botones en su evento Botón del ratón soltado.
Finalmente, desactivamos el modo diseño de formulario y cerramos la barra de herramientas.
Selector del cliente
Se ha utilizado la técnica Validez... del menú Datos, asociando la celda D3 con un intervalo de celdas definido en la hoja Datos. A la hora de definir el intervalo, siempre dejaremos la primera celda del rango vacía para hacer más sencilla la selección del cliente.
Datos del cliente
En las celdas D4,D5 y C5 hemos utilizado la función BUSCARV para que rellene los datos del cliente seleccionado en la celda D3
Hemos anidado la función BUSCARV dentro de una función SI, que detecta si D3 está vacío; en caso afirmativo, rellena las celdas con nada (""); en caso contrario, las rellena con el resultado de la búsqueda.
Suponemos que los datos del domicilio de cada cliente se escriben por completo en una única celda, utilizando Ctrl+Intro para añadir nuevas líneas dentro de la celda cuando estamos editando su contenido.
Líneas de detalle de la factura
Los colores de fila alternos se aplican mediante la técnica descrita en este artículo: Ponle el pijama a tus hojas de OpenOffice Calc con formato condicional.
El rango de celdas B8:B37 permiten seleccionar el código del artículo utilizando la misma técnica que hemos utilizado para el código del cliente.
Las columnas Descripción y Precio utilizan la función BUSCARV de nuevo anidadas en una función SI para evitar que muestren algo si el código del artículo está vacío.
La columna Importe incorpora una fórmula que calcula el importe neto de la línea, también anidada en una función SI con el mismo objetivo que la anterior.
Pié de la factura
Forma de pago y vencimientos
La celda B40 permite seleccionar la forma de pago también utilizando la técnica de validez de celdas
El rango de celdas B43:C46 muestran los vencimientos en función de la forma de pago seleccionada. Las formas de pago se definen en la hoja Datos, y permiten definir hasta 4 pagos en partes alícuotas, indicando el número de días a transcurrir desde la fecha de factura hasta el vencimiento.
El primer vencimiento se calcula restando del total los otros vencimientos, de forma que en caso de diferencias por redondeo, se acumulen o resten del primero.
Descuentos, portes e impuestos
La celda G40 permite definir un porcentaje de descuento a aplicar al total bruto.
La celda F42 permite introducir un número de envíos en concepto de portes, mientras que la celda G42 permiten introducir el coste de cada envío.
Total bruto - Descuento + Portes conforman el total antes de impuestos
Las celdas G44 y G45 permiten seleccionar el porcentaje de IVA y de Recargo de equivalencia a aplicar al total antes de impuestos.
Dado que este es un modelo de cómo utilizar determinadas técnicas, no se ajusta a ninguna normativa en particular, por lo que si el usuario decide utilizarlo deberá adaptarlo a la normativa de su país.
Hoja protegida
Se ha protegido la hoja para que no se puedan siquiera seleccionar las celdas que no tienen que editarse.
Las celdas que sí pueden editarse fueron previamente desprotegidas desde Formatear celdas... > Protección de celda, como podeis leer en este capítulo de nuestra wiki: Ocultar, mostrar y proteger en Calc.
Celdas y rangos de celdas con nombre
Para facilitar la personalización y modificación del modelo sin tener que editar las macros, se han creado los siguientes nombres de celdas y rangos:
Celda o rango con nombre | Hoja | Celda o rango | Importante para |
CodCliente | Factura | D3 | Varias |
DatosFactura | Factura | K7:K28 | Exportar a Resumen |
DescuentoFact | Factura | G40 | Vaciar datos |
FormaPago | Factura | B40 | |
ImprimirFactura | Factura | B1:H46 | Imprimir / Generar PDF |
NumFactura | Factura | C3 | |
Portes | Factura | F42:G42 | Vaciar datos |
RecargoEquiv | Factura | G45 | |
ResumenInsertarFila | Resumen | A35 | Exportar a Resumen |
ResumenTotales | Resumen | A38 | |
VaciaCantidad | Factura | E8:E37 | Vaciar datos |
VaciaCodigos | Factura | B8:B37 | |
VaciaDtos | Factura | G8:G37 |
En caso de personalizar la factura, y tener que mover estas celdas o rangos de celdas de lugar, o cambiar el número de líneas o columnas que conforman alguno de los rangos, se deben redefinir los nombres para no tener que modificar las macros y que todo siga funcionando correctamente.
Para saber más sobre rangos y celdas con nombre, consulta Definir rangos o celdas con nombre.
Exportar los datos a la hoja Resumen
La macro que realiza este proceso se llama EnviarDatos, y está asociada al primer botón Enviar datos a Resumen.
Los datos que se quieren exportar a la hoja resumen han sido duplicados mediante vínculos al nombre DatosFactura (rango K7:K28) en una columna para simplificar el proceso que realiza la macro. La macro copia estos datos y mediante pegado especial, transponiendo, pegar los datos en la hora Resumen en forma de fila.
Las columnas J y K se han ocultado a propósito.
En la exportación se utiliza el nombre ResumenInsertarFila para localizar la posición donde insertar la nueva fila.
Se utiliza el nombre CodCliente para volver de nuevo a la hoja Factura tras exportar los datos a la hoja Resumen.
Sub EnviarDatos '---------------------------------------------------------------------- Dim document As Object Dim dispatcher As Object document = ThisComponent.CurrentController.Frame dispatcher = CreateUNOService("com.sun.star.frame.DispatchHelper") Dim aSaltarA(0) As New com.sun.star.beans.PropertyValue aSaltarA(0).Name = "ToPoint" aSaltarA(0).Value = "DatosFactura" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array()) aSaltarA(0).Value = "ResumenInsertarFila" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) Dim aMover(1) As New com.sun.star.beans.PropertyValue aMover(0).Name = "By" aMover(0).Value = 1 aMover(1).Name = "Sel" aMover(1).Value = False dispatcher.executeDispatch(document, ".uno:InsertRows", "", 0, Array()) Dim aPegadoEspecial(5) As New com.sun.star.beans.PropertyValue aPegadoEspecial(0).Name = "Flags" aPegadoEspecial(0).Value = "SVDN" aPegadoEspecial(1).Name = "FormulaCommand" aPegadoEspecial(1).Value = 0 aPegadoEspecial(2).Name = "SkipEmptyCells" aPegadoEspecial(2).Value = False aPegadoEspecial(3).Name = "Transpose" aPegadoEspecial(3).Value = True aPegadoEspecial(4).Name = "AsLink" aPegadoEspecial(4).Value = False aPegadoEspecial(5).Name = "MoveMode" aPegadoEspecial(5).Value = 4 dispatcher.executeDispatch(document, ".uno:InsertContents", "", 0, aPegadoEspecial()) aMover(0).Value = 22 dispatcher.executeDispatch(document, ".uno:GoRight", "", 0, aMover()) aMover(0).Value = 1 dispatcher.executeDispatch(document, ".uno:GoUp", "", 0, aMover()) aMover(1).Value = True dispatcher.executeDispatch(document, ".uno:GoRight", "", 0, aMover()) dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array()) aMover(1).Value = False dispatcher.executeDispatch(document, ".uno:GoLeft", "", 0, aMover()) dispatcher.executeDispatch(document, ".uno:GoDown", "", 0, aMover()) aPegadoEspecial(0).Value = "A" aPegadoEspecial(3).Value = False dispatcher.executeDispatch(document, ".uno:InsertContents", "", 0, aPegadoEspecial()) aSaltarA(0).Value = "ResumenInsertarFila" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) aSaltarA(0).Value = "CodCliente" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) MsgBox ("Datos enviados a la hoja Resumen", 192, "open-office.es") End Sub
Imprimir la factura
La macro que realiza este proceso se llama ImprimirFactura, y está asociada al primer botón Imprimir Factura.
Se utiliza el nombre ImprimirFactura para definir el área de impresión, o sea, las celdas a imprimir.
Se utiliza el nombre CodCliente para situar el cursor en esa posición tras definir el área de impresión.
La macro redefine el área de impresión y muestra el diálogo Imprimir para seleccionar la impresora de salida y otros ajustes.
Si se desea que se presente el diálogo Formato de página (disponible desde la vista preliminar para ajustar las opciones de página, encabezado, etc.) puedes descomentar la línea correspondiente en la macro.
Sub ImprimirFactura '---------------------------------------------------------------------- Dim document As Object Dim dispatcher As Object document = ThisComponent.CurrentController.Frame dispatcher = CreateUNOService("com.sun.star.frame.DispatchHelper") Dim aSaltarA(0) As New com.sun.star.beans.PropertyValue aSaltarA(0).Name = "ToPoint" aSaltarA(0).Value = "ImprimirFactura" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:DefinePrintArea", "", 0, Array()) aSaltarA(0).Value = "CodCliente" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) ' descomentar la siguiente línea para presentar el diálogo Formato de página ' dispatcher.executeDispatch(document, ".uno:PageFormatDialog", "", 0, Array()) dispatcher.executeDispatch(document, ".uno:Print", "", 0, Array()) End Sub
Generar PDF
La macro que realiza este proceso se llama GenerarPDF, y está asociada al primer botón Generar PDF.
Se utiliza el nombre ImprimirFactura para definir el área de impresión y el nombre CodCliente para situar el cursor en esa posición tras definirla.
Se utiliza el nombre NumFactura para componer el nombre del documento PDF generado.
La macro redefine el área de impresión y muestra el diálogo Exportar factura en formato PDF para seleccionar la carpeta destino y modificar, si se considera oportuno, el nombre del documento PDF generado.
Esta macro utiliza para tal fin la función GuardarComo, basada en una función similar tomada del libro de Mauricio Aprendiendo OOo / LibO Basic
Sub GenerarPDF '---------------------------------------------------------------------- Dim document As Object Dim dispatcher As Object Dim numFactura As String Dim CarpetaNombrePDF As String document = ThisComponent.CurrentController.Frame dispatcher = CreateUNOService("com.sun.star.frame.DispatchHelper") Dim aSaltarA(0) As New com.sun.star.beans.PropertyValue aSaltarA(0).Name = "ToPoint" aSaltarA(0).Value = "ImprimirFactura" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:DefinePrintArea", "", 0, Array()) aSaltarA(0).Value = "CodCliente" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) numFactura = ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("NumFactura").getString() CarpetaNombrePDF = GuardarComo( "Factura " & numFactura ) If CarpetaNombrePDF > "" Then Dim args2(1) As New com.sun.star.beans.PropertyValue args2(0).Name = "URL" args2(0).Value = CarpetaNombrePDF args2(1).Name = "FilterName" args2(1).Value = "calc_pdf_Export" dispatcher.executeDispatch(document, ".uno:ExportDirectToPDF", "", 0, args2()) EndIf End Sub Function GuardarComo( cNombre As String ) As String '---------------------------------------------------------------------- Dim oDlgGuardarArchivo As Object Dim mDlgOpciones() Dim mArchivo() As String Dim mOpciones() oDlgGuardarArchivo = CreateUNOService ("com.sun.star.ui.dialogs.FilePicker") mDlgOpciones = Array(com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_AUTOEXTENSION) With oDlgGuardarArchivo .Initialize ( mDlgOpciones() ) .AppendFilter( "Documentos PDF (.pdf)", "*.pdf" ) .Title = "Exportar factura en formato PDF" .SetDefaultName(cNombre) End With If oDlgGuardarArchivo.Execute() Then mArchivo() = oDlgGuardarArchivo.getFiles() GuardarComo = mArchivo(0) End If End Function
Vaciar datos
La macro que realiza este proceso se llama VaciarDatos, y está asociada al primer botón Vaciar datos.
Se utilizan varias nombres de celdas y de rangos para reiniciar los datos de la factura..
Tras utilizar este botón, las celdas afectadas se mostrará vacías de contenidos, incluídos los comentarios que albergaban.
Sub VaciarDatos '---------------------------------------------------------------------- Dim document As Object Dim dispatcher As Object document = ThisComponent.CurrentController.Frame dispatcher = CreateUNOService("com.sun.star.frame.DispatchHelper") Dim aSaltarA(0) As New com.sun.star.beans.PropertyValue aSaltarA(0).Name = "ToPoint" aSaltarA(0).Value = "VaciaCodigos" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()) aSaltarA(0).Value = "VaciaCantidad" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()) aSaltarA(0).Value = "VaciaDtos" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()) aSaltarA(0).Value = "FormaPago" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()) aSaltarA(0).Value = "Portes" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()) aSaltarA(0).Value = "DescuentoFact" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()) aSaltarA(0).Value = "RecargoEquiv" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()) aSaltarA(0).Value = "CodCliente" dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, aSaltarA()) dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()) End Sub
Hoja Factura
Desde la barra de herramientas lateral se ha desactivado la opción Mostrar líneas de cuadrícula de la celda.
Hoja Datos
Para que el método de selección de un dato utilizando la técnica de Validez sea más natural, es importante dejar la primera celda del rango vacía.
En las funciones BUSCARV utilizadas en la hoja Factura, las tablas de búsqueda incluyen hasta la fila 50; se ha marcado de forma especial la última fila para recordar que en caso de necesitar más líneas, deben insertarse por encima de esa marca, con el fin de que las fórmulas se actualicen automáticamente.
Hoja Resumen
Las dos primera y las dos últimas filas que se ven en la hoja no deben eliminarse para que todo funcione perfectamente.
Cuando se insertan nuevas filas se copia automáticamente el formato de las filas anteriores;además, las celdas de las columnas W y X contienen fórmulas que automáticamente copia la macro de la fila anterior a la insertada. Por eso no debemos eliminar ni la fila 2, ni el contenido, ni el formato de sus celdas.
Para que se actualicen automáticamente las fórmulas de las dos últimas filas (los totales) debe respetarse la fila situada justo encima, que no debe eliminarse ni ocultarse.
Se ha activado el filtro automático (autofiltro) para obtener fácilmente información del resumen.
Descargar el modelo
Si quieres descargar el modelo, haz clic sobre el siguiente enlace:
Descargar Modelo Factura Openoffice Libreoffice Calc
8 comentarios
Hola!
Yo tengo un modelo de factura hecho en excel donde tengo protegido el documento excepto las casillas de fecha, nº de factura, Nombre cliente, Nif cliente y direccion cliente.
Tengo un modelo en una hoja y otro modelo en otra hoja dependiendo de la consulta donde yo trabaje ese dia.
Mi problema es que para exportar a PDF la hoja actual que estoy usando, calc me exporta todo el documento (todas las hojas) y yo solo quiero la que está activa (en uso), de modo que cada vez que quiero exportar una factura tengo que seleccionar todo el rango de la hoja activa del documento y exportar sólo la selección.
¿Se puede hacer una macro para exportar una hoja a pdf? ¿Como puedo hacerla?
Gracias.
Hola Meredith:
En cuanto a la impresión ocurre igual en Calc que en Excel. Debes configurarlo adecuadamente seleccionando un rango de impresión para que imprima la factura y no todas las hojas.
Este ejemplo incluye una macro que exporta el rango de impresión a PDF; en realidad, exporta el rango de impresión definido, pues exportar a PDF es equivalente a imprimir.
Espero que te sirva.
Buenas Tardes.
Descargue el archivo y coloque mis datos (imagen, nombre de empresa....), pero a la hora de ejecutar los macros, estes no me funcionan. Nose que puede pasar, la macro que mas me interesa es la de enviar datos a resumen.
Por favor, necesito ayuda.
Hola Alberto
Dada la dificultad de establecer un diálogo en este blog mediante comentarios, recomiendo que te dirijas al Foro Oficial de OpenOffice y expongas allí el problema. Podremos ayudarte más rápidamente que por aquí.
Saludos
Hola masters, tengo un problema utilice el codigo para hacer unos respaldos de datos el problema que me dio es que cuando actualice a la version nueva de openoffice 5.1 dejo de funcionar, me graba en cualquier parte menos de forma ordenada como lo estaba haciendo.
Hola.
primero que nada excelente aplicación, me estaba funcionando bien hasta que se me ocurrio actualizar el office con lo que estaba trabajando era la libreoffice 4.1 y funcinaba de maravilla actualize a libreoffice 5.1 y al momento de grabar los datos no los graba como corresponde. quisiera saber si hay alguna posibilidad de poder hacer funcionar en esa version esta excelente aplicación.
Tiene un buen diseño pero no me deja cambiar los datos de la empresa y el precio final no incluye el IVA, al estar protegido y ser una plantilla no deja ediar, una decepción
He creado una factura basándome en esta, el área "ImprimirFactura" esta bien configurada y si le doy a imprimir solo me imprime la hoja de la factura pero si le doy a exportar a pdf me imprime todo el documento
Esta publicación tiene 1 reacción esperando moderación...