Con este código podrás generar una factura en XML desde tu programa de Access y la factura ya firmada en formato XSIG de eFactura.
Copia y pega el código en un botón de tu programa de facturación.
Tendrás que cambiar tus datos de empresa y el nombre de los campos que usas en tu programa.
Serán necesarios 6 campos nuevos en tu ficha de cliente y en ellos se almacenan la información que da la institución a la que facturas (Órgano Gestor, Unidad Tramitadora y Oficina Contable). Estos campos son: GestorCode, GestorNombre, UnidadCode, UnidadNombre, OficinaCode y OficinaNombre. Todos ellos de texto.
Se abrirá automáticamente autofirma de forma oculta y te pesentará los certificados que tengas disponibles para firmar digitalmente la factura.
Se generará el fichero firmado que podrás subirlo directamente a FACE.
Tener en cuenta una cosa, las líneas de detalle de la factura no pueden contener solo texto en el concepto, si hay una línea de detalle con sólo texto hay que rellenar los campos de cantidad, precio unidad y líneatotal con ceros o unos (según el campo) porque FACE no admite líneas de detalle con datos parciales o campos sin datos.
'®Tantor Systems Creative Commons CC BY Dim dbs As Database, tdf2 As Recordset, fld As Field, tdf3 As Recordset Dim stDocName As String Dim xxx, nrolineas As Integer Dim cuantoiva As Double Dim lineacomando as string Dim retval Set dbs = CurrentDb ' abro la tabla donde tengo al cliente stDocName = "SELECT * FROM Agenda WHERE Agenda.Id_Agenda=" + Str(Me.Id_Clientes) + "; " Set tdf2 = dbs.OpenRecordset(stDocName) tdf2.MoveFirst 'Creo el fichero XML de destino cuyo nombre será Emit-nºfactura.xml 'Open "C:\Directorio\Borrador-" & Trim(Str(Me.NroFact)) & ".xml" For Output As #1 Open "C:\Directorio\Emit-" & Trim(Str(Me.NroFact)) & ".xml" For Output As #1 Print #1, "<?xml version=""1.0"" encoding=""UTF-8""?>" Print #1, "<fe:Facturae xmlns:ds=""http://www.w3.org/2000/09/xmldsig#"" xmlns:fe=""http://www.facturae.es/Facturae/2014/v3.2.1/Facturae"">"; Print #1, "<FileHeader>"; Print #1, "<SchemaVersion>3.2.1</SchemaVersion>"; Print #1, "<Modality>I</Modality>"; Print #1, "<InvoiceIssuerType>EM</InvoiceIssuerType>"; Print #1, "<Batch>"; Print #1, "<BatchIdentifier>" & Trim(tdf2!CIF) & Trim(Str(Me.NroFact)) & "Emit-</BatchIdentifier>"; ' grabo nro de factura Print #1, "<InvoicesCount>1</InvoicesCount>"; Print #1, "<TotalInvoicesAmount><TotalAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalAmount></TotalInvoicesAmount>"; ' grabo importe factura Print #1, "<TotalOutstandingAmount><TotalAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalAmount></TotalOutstandingAmount>"; ' grabo importe factura Print #1, "<TotalExecutableAmount><TotalAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalAmount></TotalExecutableAmount>"; ' grabo importe factura Print #1, "<InvoiceCurrencyCode>EUR</InvoiceCurrencyCode>"; Print #1, "</Batch>"; Print #1, "</FileHeader>"; Print #1, "<Parties>"; ' Vendedor Print #1, "<SellerParty>"; Print #1, "<TaxIdentification><PersonTypeCode>J</PersonTypeCode><ResidenceTypeCode>U</ResidenceTypeCode><TaxIdentificationNumber>MI NIF/CIF</TaxIdentificationNumber></TaxIdentification>"; Print #1, "<LegalEntity>"; Print #1, "<CorporateName>NOMBRE DE MI EMPRESA</CorporateName>"; ' CAMBIA LOS DATOS POR LOS TUYOS Print #1, "<RegistrationData><RegisterOfCompaniesLocation>Santander</RegisterOfCompaniesLocation><Sheet>5555</Sheet><Folio>666</Folio><Volume>777</Volume></RegistrationData>"; Print #1, "<AddressInSpain><Address>FERNANDEZ DE ISLA 10, BAJO</Address><PostCode>39008</PostCode><Town>SANTANDER</Town><Province>CANTABRIA</Province><CountryCode>ESP</CountryCode></AddressInSpain>"; Print #1, "<ContactDetails><Telephone>942123456</Telephone><TeleFax>942123456</TeleFax><WebAddress>www.miweb.com</WebAddress><ElectronicMail>micorreo@miempresa.com</ElectronicMail></ContactDetails>"; Print #1, "</LegalEntity>"; Print #1, "</SellerParty>"; ' Comprador Print #1, "<BuyerParty>"; ' grabo los datos del cliente Print #1, "<TaxIdentification><PersonTypeCode>J</PersonTypeCode><ResidenceTypeCode>U</ResidenceTypeCode><TaxIdentificationNumber>" & tdf2!CIF & "</TaxIdentificationNumber></TaxIdentification>"; Print #1, "<AdministrativeCentres>"; ' Los campos GestorCode, GestorNombre, UnidadCode, UnidadNombre, OficinaCode y OficinaNombre los tienes que tener en la tabla del cliente y estos datos ' los consigues de la página web o llamando a la institución a la que facturas 'Receptor / Organo Gestor Print #1, "<AdministrativeCentre>"; Print #1, "<CentreCode>" & tdf2!GestorCode & "</CentreCode><RoleTypeCode>02</RoleTypeCode><Name>" & tdf2!GestorNombre & "</Name>"; Print #1, "<AddressInSpain><Address>" & tdf2!DIRECCION & "</Address><PostCode>" & tdf2!cp & "</PostCode><Town>" & tdf2!POBLACION & "</Town><Province>" & tdf2!PROVINCIA & "</Province><CountryCode>ESP</CountryCode></AddressInSpain>"; Print #1, "</AdministrativeCentre>"; 'Fiscal / Unidad tramitadora Print #1, "<AdministrativeCentre>"; Print #1, "<CentreCode>" & tdf2!UnidadCode & "</CentreCode><RoleTypeCode>03</RoleTypeCode><Name>" & tdf2!UnidadNombre & "</Name>"; Print #1, "<AddressInSpain><Address>" & tdf2!DIRECCION & "</Address><PostCode>" & tdf2!cp & "</PostCode><Town>" & tdf2!POBLACION & "</Town><Province>" & tdf2!PROVINCIA & "</Province><CountryCode>ESP</CountryCode></AddressInSpain>"; Print #1, "</AdministrativeCentre>"; 'Pagador / Oficina contable Print #1, "<AdministrativeCentre>"; Print #1, "<CentreCode>" & tdf2!OficinaCode & "</CentreCode><RoleTypeCode>01</RoleTypeCode><Name>" & tdf2!OficinaNombre & "</Name>"; Print #1, "<AddressInSpain><Address>" & tdf2!DIRECCION & "</Address><PostCode>" & tdf2!cp & "</PostCode><Town>" & tdf2!POBLACION & "</Town><Province>" & tdf2!PROVINCIA & "</Province><CountryCode>ESP</CountryCode></AddressInSpain>"; Print #1, "</AdministrativeCentre>"; Print #1, "</AdministrativeCentres>"; Print #1, "<LegalEntity>"; Print #1, "<CorporateName>" & tdf2!NOMBRE & "</CorporateName>"; Print #1, "<TradeName>" & tdf2!RAZONSOCIA & "</TradeName>"; Print #1, "<AddressInSpain>"; Print #1, "<Address>" & tdf2!DIRECCION & "</Address><PostCode>" & tdf2!cp & "</PostCode><Town>" & tdf2!POBLACION & "</Town><Province>" & tdf2!PROVINCIA & "</Province><CountryCode>ESP</CountryCode>"; Print #1, "</AddressInSpain>"; Print #1, "</LegalEntity>"; Print #1, "</BuyerParty>"; Print #1, "</Parties>"; ' Grabo los datos de la Factura Print #1, "<Invoices>"; Print #1, "<Invoice>"; Print #1, "<InvoiceHeader>"; Print #1, "<InvoiceNumber>" & Trim(Str(Me.NroFact)) & "</InvoiceNumber>"; Print #1, "<InvoiceSeriesCode>Borrador-</InvoiceSeriesCode>"; Print #1, "<InvoiceDocumentType>FC</InvoiceDocumentType>"; Print #1, "<InvoiceClass>OO</InvoiceClass>"; Print #1, "</InvoiceHeader>"; Print #1, "<InvoiceIssueData>"; Print #1, "<IssueDate>" & Format(Me.FechaFactura, "yyyy-mm-dd") & "</IssueDate>"; Print #1, "<PlaceOfIssue><PostCode>39008</PostCode><PlaceOfIssueDescription>Asiento nro 30</PlaceOfIssueDescription></PlaceOfIssue>"; Print #1, "<InvoiceCurrencyCode>EUR</InvoiceCurrencyCode><TaxCurrencyCode>EUR</TaxCurrencyCode><LanguageName>es</LanguageName>"; Print #1, "</InvoiceIssueData>"; Print #1, "<TaxesOutputs>"; Print #1, "<Tax>"; Print #1, "<TaxTypeCode>01</TaxTypeCode><TaxRate>" & Trim(Str(Me.Iva)) & "</TaxRate>"; Print #1, "<TaxableBase><TotalAmount>" & Trim(Str(Me.SubtotalFactura)) & "</TotalAmount></TaxableBase>"; Print #1, "<TaxAmount><TotalAmount>" & Trim(Str(Me.ImporteIVA)) & "</TotalAmount></TaxAmount>"; Print #1, "</Tax>"; Print #1, "</TaxesOutputs>"; Print #1, "<InvoiceTotals>"; Print #1, "<TotalGrossAmount>" & Trim(Str(Me.SubtotalFactura)) & "</TotalGrossAmount>"; Print #1, "<TotalGeneralDiscounts>0.0</TotalGeneralDiscounts>"; Print #1, "<TotalGeneralSurcharges>0.0</TotalGeneralSurcharges>"; Print #1, "<TotalGrossAmountBeforeTaxes>" & Trim(Str(Me.SubtotalFactura)) & "</TotalGrossAmountBeforeTaxes>"; Print #1, "<TotalTaxOutputs>" & Trim(Str(Me.ImporteIVA)) & "</TotalTaxOutputs>"; Print #1, "<TotalTaxesWithheld>0.0</TotalTaxesWithheld>"; Print #1, "<InvoiceTotal>" & Trim(Str(Me.ImporteFactura)) & "</InvoiceTotal>"; Print #1, "<TotalOutstandingAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalOutstandingAmount>"; Print #1, "<TotalExecutableAmount>" & Trim(Str(Me.ImporteFactura)) & "</TotalExecutableAmount>"; Print #1, "</InvoiceTotals>"; ' Líneas de detalle stDocName = "SELECT * FROM FacturasLineas WHERE FacturasLineas.IdFactura=" + Str(Me.IdFactura) + "; " Set tdf3 = dbs.OpenRecordset(stDocName) Print #1, "<Items>"; If tdf3.EOF = False Then tdf3.MoveFirst Do Print #1, "<InvoiceLine>"; Print #1, "<ItemDescription>" & tdf3!DENOMINACION & "</ItemDescription>"; If IsNull(tdf3!Cantidad) Then Print #1, "<Quantity>0</Quantity>"; Else Print #1, "<Quantity>" & Trim(Str(tdf3!Cantidad)) & "</Quantity>"; End If Print #1, "<UnitOfMeasure>01</UnitOfMeasure>"; If IsNull(tdf3!PrecioUnidad) Then Print #1, "<UnitPriceWithoutTax>0</UnitPriceWithoutTax>"; Else Print #1, "<UnitPriceWithoutTax>" & Trim(Str((Int((tdf3!PrecioUnidad * 100) + 0.5)) / 100)) & "</UnitPriceWithoutTax>"; End If If IsNull(tdf3!LíneaTotal) Then Print #1, "<TotalCost>0</TotalCost>"; Print #1, "<GrossAmount>0</GrossAmount>"; Else Print #1, "<TotalCost>" & Trim(Str((Int((tdf3!LíneaTotal * 100) + 0.5)) / 100)) & "</TotalCost>"; Print #1, "<GrossAmount>" & Trim(Str((Int((tdf3!LíneaTotal * 100) + 0.5)) / 100)) & "</GrossAmount>"; End If Print #1, "<TaxesOutputs>"; Print #1, "<Tax>"; Print #1, "<TaxTypeCode>01</TaxTypeCode>"; Print #1, "<TaxRate>" & Trim(Str(Me.Iva)) & "</TaxRate>"; Print #1, "<TaxableBase><TotalAmount>" & Trim(Str((Int((tdf3!LíneaTotal * 100) + 0.5)) / 100)) & "</TotalAmount></TaxableBase>"; If IsNull(tdf3!LíneaTotal) Then cuantoiva = 0 Else cuantoiva = (Int((tdf3!LíneaTotal * 100) + 0.5)) / 100 cuantoiva = (cuantoiva * Me.Iva / 100) End If Print #1, "<TaxAmount><TotalAmount>" & Trim(Str((Int((cuantoiva * 100) + 0.5)) / 100)) & "</TotalAmount></TaxAmount>"; Print #1, "</Tax>"; Print #1, "</TaxesOutputs>"; If Not (IsNull(tdf3!Notas)) Then Print #1, "<AdditionalLineItemInformation>" & tdf3!DENOMINACI&; "</AdditionalLineItemInformation>"; End If Print #1, "</InvoiceLine>"; tdf3.MoveNext Loop While tdf3.EOF = False End If Print #1, "</Items>"; Print #1, "</Invoice>"; Print #1, "</Invoices>"; Print #1, "</fe:Facturae>"; Close #1 tdf2.Close tdf3.Close Set dbs = Nothing lineacomando = "sign -i C:\Directorio\Emit-" & Trim(Str(Me.NroFact)) & ".xml -o C:\Directorio\Emit-" & Trim(Str(Me.NroFact)) & ".xsig -certgui" retval = Shell("C:\Program Files\AutoFirma\AutoFirma\autofirma.exe " & lineacomando)