VBA Excel macro para leer XML nómina 1.2 de forma masiva

7 ago 2019

VBA Excel macro para leer XML nómina 1.2 de forma masiva


Les comparto una macro que he adaptado para leer los XML de nómina versión 1.2 de forma masiva.
Para que la macro funcione hay que seguir los siguientes pasos:
1. Abrir el editor Visual Basic para Aplicaciones (VBA).
2. Insertar un módulo.
3. Agregar la referencia "Microsoft XML, v3.0" en el menú herramientas del editor VBA, dar click en referencias.
3. Pegar el siguiente código:
Private Sub Ruta_CFDI()
'macro para en listar los XML que va a leer
'Adapatado por Luis Reyes
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False

Dim fs, carpeta, archivo, subcarpeta As Object
contador = 2 'determinar en que fila comenzará a colocar la ruta y nombre de los XML

Set fs = CreateObject("Scripting.FileSystemObject")

With Application.FileDialog(msoFileDialogFolderPicker) 'se obtiene la ruta la carpeta

  If .Show = -1 Then
    ruta = .SelectedItems(1)
    Range("V1").Value = ruta & "\"
  End If

End With

Set carpeta = fs.GetFolder(ruta)

For Each archivo In carpeta.Files

If Right(archivo, 4) = ".xml" Then

Range("AD" & contador).Value = ruta & "\" & archivo.Name
 contador = contador + 1

End If

If Right(archivo, 4) = ".XML" Then
 Range("AD" & contador).Value = ruta & "\" & archivo.Name
 contador = contador + 1

End If

Next

  

If Application.WorksheetFunction.CountA(Columns(30)) = 0 Then
MsgBox "No se encontro ningún archivo *.XML" & Chr(10) & ruta, vbCritical, "Importar datos CFDI"
End

End If

Run "Lectura_CFDI" 'ejecuta la macro que lee los XML

End Sub

Private Sub Lectura_CFDI()

'Adapatado por Luis Reyes

With Application
   .ScreenUpdating = False
   .Calculation = xlCalculationManual
   .EnableEvents = False
   .DisplayStatusBar = False

Dim Concepto As String
Dim pctCompl As Single

Set DocumentoXML = New DOMDocument

Set R = Hoja1.Range("AD2").CurrentRegion 'determina apartir de donde comienza a contar
filas = R.Rows.Count

For i = 2 To filas + 1 'número de documentos que va a leer

DocumentoXML.Load ("" & Cells(i, 30) & "")

Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante")

On Error Resume Next

For Each Nodo In ListaNodo

Serie = Nodo.Attributes.getNamedItem("Serie").Text
Folio = Nodo.Attributes.getNamedItem("Folio").Text
Fecha = Mid(Nodo.Attributes.getNamedItem("Fecha").Text, 1, 10)
Sello = Nodo.Attributes.getNamedItem("Sello").Text
FormaPago = Nodo.Attributes.getNamedItem("FormaPago").Text
NoCertificado = Nodo.Attributes.getNamedItem("NoCertificado").Text
Certificado = Nodo.Attributes.getNamedItem("Certificado").Text
Subtotal = Val(Nodo.Attributes.getNamedItem("SubTotal").Text)
Descuento = Val(Nodo.Attributes.getNamedItem("Descuento").Text)
Moneda = Nodo.Attributes.getNamedItem("Moneda").Text
Total = Val(Nodo.Attributes.getNamedItem("Total").Text)
TipoDeComprobante = Nodo.Attributes.getNamedItem("TipoDeComprobante").Text
MetodoPago = Nodo.Attributes.getNamedItem("MetodoPago").Text
LugarExpedicion = Nodo.Attributes.getNamedItem("LugarExpedicion").Text

Next Nodo

''''''''''''''''''''''''''''''''''''''''''''''''Nombre del emisor'''''''''''''''''''''''''''''''''''''''''''''''''''

Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Emisor")

For Each Nodo In ListaNodo
  NombreEmisor = Nodo.Attributes.getNamedItem("Nombre").Text
  RFCEmisor = Nodo.Attributes.getNamedItem("Rfc").Text
  Regimen = Nodo.Attributes.getNamedItem("RegimenFiscal").Text
Next Nodo

Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Receptor")

For Each Nodo In ListaNodo

  NombreReceptor = Nodo.Attributes.getNamedItem("Nombre").Text
  RFCReceptor = Nodo.Attributes.getNamedItem("Rfc").Text
  Regimen = Nodo.Attributes.getNamedItem("RegimenFiscal").Text
  UsoCFDI = Nodo.Attributes.getNamedItem("UsoCFDI").Text

Next Nodo

''''''''''''''''''''''''''''''''''''''''''''''''Conceptos'''''''''''''''''''''''''''''''''''''''''''''''''''

Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Conceptos/cfdi:Concepto")

For Each Nodo In ListaNodo

  ClaveProducto = ClaveProducto & Nodo.Attributes.getNamedItem("ClaveProdServ").Text & "|"
  CantidadP = CantidadP & Nodo.Attributes.getNamedItem("Cantidad").Text & "|"
  ClaveUnidadP = ClaveUnidadP & Nodo.Attributes.getNamedItem("ClaveUnidad").Text & "|"
  Concepto = Concepto & Nodo.Attributes.getNamedItem("Descripcion").Text & "|"
  ValorU = ValorU & Nodo.Attributes.getNamedItem("ValorUnitario").Text & "|"
  ImporteL = ImporteL & Nodo.Attributes.getNamedItem("Importe").Text & "|"
  DescuentoL = DescuentoL & Nodo.Attributes.getNamedItem("Descuento").Text & "|"

Next Nodo



Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Complemento/nomina12:Nomina")

For Each Nodo In ListaNodo

  FechaFinal = Nodo.Attributes.getNamedItem("FechaFinalPago").Text
  FechaInicial = Nodo.Attributes.getNamedItem("FechaInicialPago").Text
  Pago = Nodo.Attributes.getNamedItem("FechaPago").Text
  DiasPagados = Nodo.Attributes.getNamedItem("NumDiasPagados").Text
  TipoNom = Nodo.Attributes.getNamedItem("TipoNomina").Text
  TotalDeduc = Nodo.Attributes.getNamedItem("TotalDeducciones").Text
  TotalPercep = Nodo.Attributes.getNamedItem("TotalPercepciones").Text
  VersionNomina = Nodo.Attributes.getNamedItem("Version").Text

Next Nodo



Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Complemento/nomina12:Nomina/nomina12:Emisor")

For Each Nodo In ListaNodo

  RegistroPat = Nodo.Attributes.getNamedItem("RegistroPatronal").Text

Next Nodo



Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Complemento/nomina12:Nomina/nomina12:Receptor")

For Each Nodo In ListaNodo

AntigüedadR = Nodo.Attributes.getNamedItem("Antigüedad").Text
BancoR = Nodo.Attributes.getNamedItem("Banco").Text
ClaveEntFedR = Nodo.Attributes.getNamedItem("ClaveEntFed").Text
CuentaBancariaR = Nodo.Attributes.getNamedItem("CuentaBancaria").Text
CurpR = Nodo.Attributes.getNamedItem("Curp").Text
DepartamentoR = Nodo.Attributes.getNamedItem("Departamento").Text
FechaInicioRelLaboralR = Nodo.Attributes.getNamedItem("FechaInicioRelLaboral").Text
NumEmpleadoR = Nodo.Attributes.getNamedItem("NumEmpleado").Text
NumSeguridadSocialR = Nodo.Attributes.getNamedItem("NumSeguridadSocial").Text
PeriodicidadPagoR = Nodo.Attributes.getNamedItem("PeriodicidadPago").Text
PuestoR = Nodo.Attributes.getNamedItem("Puesto").Text
RiesgoPuestoR = Nodo.Attributes.getNamedItem("RiesgoPuesto").Text
SalarioBaseCotAporR = Nodo.Attributes.getNamedItem("SalarioBaseCotApor").Text
SalarioDiarioIntegradoR = Nodo.Attributes.getNamedItem("SalarioDiarioIntegrado").Text
SindicalizadoR = Nodo.Attributes.getNamedItem("Sindicalizado").Text
TipoContratoR = Nodo.Attributes.getNamedItem("TipoContrato").Text
TipoJornadaR = Nodo.Attributes.getNamedItem("TipoJornada").Text
TipoRegimenR = Nodo.Attributes.getNamedItem("TipoRegimen").Text

Next Nodo



Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Complemento/nomina12:Nomina/nomina12:Percepciones")

For Each Nodo In ListaNodo

TotalExentoPe = Nodo.Attributes.getNamedItem("TotalExento").Text
TotalGravadoPe = Nodo.Attributes.getNamedItem("TotalGravado").Text
TotalSueldosPe = Nodo.Attributes.getNamedItem("TotalSueldos").Text

Next Nodo


Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Complemento/nomina12:Nomina/nomina12:Deducciones")

For Each Nodo In ListaNodo

TotalImpuestosRetenidosDe = Nodo.Attributes.getNamedItem("TotalImpuestosRetenidos").Text
TotalOtrasDeduccionesDe = Nodo.Attributes.getNamedItem("TotalOtrasDeducciones").Text

Next Nodo

Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Complemento/nomina12:Nomina/nomina12:Deducciones/nomina12:Deduccion")

For Each Nodo In ListaNodo

If Nodo.Attributes.getNamedItem("TipoDeduccion").Text = "002" Then

ClaveDeISR = Nodo.Attributes.getNamedItem("Clave").Text
ConceptoDeISR = Nodo.Attributes.getNamedItem("Concepto").Text
ImporteDeISR = Nodo.Attributes.getNamedItem("Importe").Text
TipoDeduccionDeISR = Nodo.Attributes.getNamedItem("TipoDeduccion").Text
ElseIf Nodo.Attributes.getNamedItem("TipoDeduccion").Text = "001" Then
ClaveDeIMSS = Nodo.Attributes.getNamedItem("Clave").Text
ConceptoDeIMSS = Nodo.Attributes.getNamedItem("Concepto").Text
ImporteDeIMSS = Nodo.Attributes.getNamedItem("Importe").Text
TipoDeduccionDeIMSS = Nodo.Attributes.getNamedItem("TipoDeduccion").Text

End If

Next Nodo

Set ListaNodo = DocumentoXML.SelectNodes("/cfdi:Comprobante/cfdi:Complemento/tfd:TimbreFiscalDigital")

For Each Nodo In ListaNodo

UUIDTF = Nodo.Attributes.getNamedItem("UUID").Text
FechaTimbradoTF = Nodo.Attributes.getNamedItem("FechaTimbrado").Text
RfcProvCertifTF = Nodo.Attributes.getNamedItem("RfcProvCertif").Text
SelloCFDTF = Nodo.Attributes.getNamedItem("SelloCFD").Text
NoCertificadoSATTF = Nodo.Attributes.getNamedItem("NoCertificadoSAT").Text
SelloSATTF = Nodo.Attributes.getNamedItem("SelloSAT").Text

Next Nodo

Cells(i, 1) = Serie
Cells(i, 2) = Folio
Cells(i, 3) = Fecha
Cells(i, 4) = Sello
Cells(i, 5) = FormaPago
Cells(i, 6) = "'" & NoCertificado
Cells(i, 7) = "'" & Certificado
Cells(i, 8) = Subtotal
Cells(i, 9) = Descuento
Cells(i, 10) = Moneda
Cells(i, 11) = Total
Cells(i, 12) = TipoDeComprobante
Cells(i, 13) = MetodoPago
Cells(i, 14) = LugarExpedicion
Cells(i, 15) = NombreEmisor
Cells(i, 16) = RFCEmisor
Cells(i, 17) = Regimen
Cells(i, 18) = NombreReceptor
Cells(i, 19) = RFCReceptor
Cells(i, 20) = Regimen
Cells(i, 21) = UsoCFDI
Cells(i, 22) = ClaveProducto
Cells(i, 23) = CantidadP
Cells(i, 24) = ClaveUnidadP
Cells(i, 25) = Concepto
Cells(i, 26) = ValorU
Cells(i, 27) = ImporteL
Cells(i, 28) = DescuentoL
Cells(i, 29) = FechaFinal
Cells(i, 30) = FechaInicial
Cells(i, 31) = Pago
Cells(i, 32) = DiasPagados
Cells(i, 33) = TipoNom
Cells(i, 34) = TotalDeduc
Cells(i, 35) = TotalPercep
Cells(i, 36) = VersionNomina
Cells(i, 37) = RegistroPat
Cells(i, 38) = AntigüedadR
Cells(i, 39) = BancoR
Cells(i, 40) = ClaveEntFedR
Cells(i, 41) = CuentaBancariaR
Cells(i, 42) = CurpR
Cells(i, 43) = DepartamentoR
Cells(i, 44) = FechaInicioRelLaboralR
Cells(i, 45) = NumEmpleadoR
Cells(i, 46) = NumSeguridadSocialR
Cells(i, 47) = PeriodicidadPagoR
Cells(i, 48) = PuestoR
Cells(i, 49) = RiesgoPuestoR
Cells(i, 50) = SalarioBaseCotAporR
Cells(i, 51) = SalarioDiarioIntegradoR
Cells(i, 52) = SindicalizadoR
Cells(i, 53) = TipoContratoR
Cells(i, 54) = TipoJornadaR
Cells(i, 55) = TipoRegimenR
Cells(i, 56) = TotalExentoPe
Cells(i, 57) = TotalGravadoPe
Cells(i, 58) = TotalSueldosPe
Cells(i, 59) = TotalImpuestosRetenidosDe
Cells(i, 60) = TotalOtrasDeduccionesDe
Cells(i, 61) = ClaveDeISR
Cells(i, 62) = ConceptoDeISR
Cells(i, 63) = ImporteDeISR
Cells(i, 64) = TipoDeduccionDeISR
Cells(i, 65) = ClaveDeIMSS
Cells(i, 66) = ConceptoDeIMSS
Cells(i, 67) = ImporteDeIMSS
Cells(i, 68) = TipoDeduccionDeIMSS
Cells(i, 69) = UUIDTF
Cells(i, 70) = FechaTimbradoTF
Cells(i, 71) = "'" & RfcProvCertifTF
Cells(i, 72) = SelloCFDTF
Cells(i, 73) = "'" & NoCertificadoSATTF
Cells(i, 74) = SelloSATTF

Serie = ""
Folio = ""
Fecha = ""
Sello = ""
FormaPago = ""
NoCertificado = ""
Certificado = ""
Subtotal = 0
Descuento = 0
Moneda = ""
Total = 0
TipoDeComprobante = 0
MetodoPago = ""
LugarExpedicion = ""
NombreEmisor = ""
RFCEmisor = ""
Regimen = ""
NombreReceptor = ""
RFCReceptor = ""
Regimen = ""
UsoCFDI = ""
ClaveProducto = ""
CantidadP = ""
ClaveUnidadP = ""
Concepto = ""
ValorU = 0
ImporteL = 0
DescuentoL = 0
FechaFinal = ""
FechaInicial = ""
Pago = ""
DiasPagados = ""
TipoNom = ""
TotalDeduc = 0
TotalPercep = 0
VersionNomina = ""
RegistroPat = ""
AntigüedadR = ""
BancoR = ""
ClaveEntFedR = ""
CuentaBancariaR = ""
CurpR = ""
DepartamentoR = ""
FechaInicioRelLaboralR = ""
NumEmpleadoR = ""
NumSeguridadSocialR = ""
PeriodicidadPagoR = ""
PuestoR = ""
RiesgoPuestoR = ""
SalarioBaseCotAporR = 0
SalarioDiarioIntegradoR = 0
SindicalizadoR = ""
TipoContratoR = ""
TipoJornadaR = ""
TipoRegimenR = ""
TotalExentoPe = 0
TotalGravadoPe = 0
TotalSueldosPe = 0
TotalImpuestosRetenidosDe = 0
TotalOtrasDeduccionesDe = 0
ClaveDeISR = ""
ConceptoDeISR = ""
ImporteDeISR = 0
TipoDeduccionDeISR = ""
ClaveDeIMSS = ""
ConceptoDeIMSS = ""
ImporteDeIMSS = 0
TipoDeduccionDeIMSS = ""
UUIDTF = ""
FechaTimbradoTF = ""
RfcProvCertifTF = ""
SelloCFDTF = ""
NoCertificadoSATTF = ""
SelloSATTF = ""

Next

Cells(1, 1) = "Serie"
Cells(1, 2) = "Folio"
Cells(1, 3) = "Fecha"
Cells(1, 4) = "Sello"
Cells(1, 5) = "Forma Pago"
Cells(1, 6) = "No Certificado"
Cells(1, 7) = "Certificado"
Cells(1, 8) = "Subtotal"
Cells(1, 9) = "Descuento"
Cells(1, 10) = "Moneda"
Cells(1, 11) = "Total"
Cells(1, 12) = "Tipo De Comprobante"
Cells(1, 13) = "Método Pago"
Cells(1, 14) = "Lugar Expedición"
Cells(1, 15) = "Nombre del Emisor"
Cells(1, 16) = "RFC del Emisor"
Cells(1, 17) = "Régimen Fiscal"
Cells(1, 18) = "Nombre del Receptor"
Cells(1, 19) = "RFC del Receptor"
Cells(1, 20) = "Régimen"
Cells(1, 21) = "Uso CFDI"
Cells(1, 22) = "Clave Producto"
Cells(1, 23) = "Cantidad"
Cells(1, 24) = "Clave Unidad"
Cells(1, 25) = "Concepto"
Cells(1, 26) = "Valor"
Cells(1, 27) = "Importe"
Cells(1, 28) = "Descuento"
Cells(1, 29) = "Fecha Final"
Cells(1, 30) = "Fecha Inicial"
Cells(1, 31) = "Fecha Pago"
Cells(1, 32) = "Días Pagados"
Cells(1, 33) = "Tipo Nomina"
Cells(1, 34) = "Total de Deducciones"
Cells(1, 35) = "Total Percepciones"
Cells(1, 36) = "Versión Nomina"
Cells(1, 37) = "Registro Patronal"
Cells(1, 38) = "Antigüedad"
Cells(1, 39) = "Banco"
Cells(1, 40) = "ClaveEntFed"
Cells(1, 41) = "Cuenta Bancaria"
Cells(1, 42) = "Curp"
Cells(1, 43) = "Departamento"
Cells(1, 44) = "Fecha Inicio Laboral"
Cells(1, 45) = "Núm. Empleado"
Cells(1, 46) = "NSS"
Cells(1, 47) = "Periodicidad Pago R"
Cells(1, 48) = "Puesto"
Cells(1, 49) = "Riesgo Puesto"
Cells(1, 50) = "SBC"
Cells(1, 51) = "SDI"
Cells(1, 52) = "Sindicalizado"
Cells(1, 53) = "Tipo Contrato"
Cells(1, 54) = "Tipo Jornada"
Cells(1, 55) = "Tipo Regimen"
Cells(1, 56) = "Total Exento"
Cells(1, 57) = "Total Gravado"
Cells(1, 58) = "Total Sueldos"
Cells(1, 59) = "Total Impuestos Retenidos"
Cells(1, 60) = "Total Otras Deducciones"
Cells(1, 61) = "Clave Deducción"
Cells(1, 62) = "Concepto Deducción"
Cells(1, 63) = "Importe Deducción"
Cells(1, 64) = "Tipo Deduccion Deducción"
Cells(1, 65) = "Clave Deducción"
Cells(1, 66) = "Concepto Deducción"
Cells(1, 67) = "Importe Deducción"
Cells(1, 68) = "Tipo Deduccion"
Cells(1, 69) = "UUID"
Cells(1, 70) = "Fecha Timbrado"
Cells(1, 71) = "Rfc Proveedor Certificado"
Cells(1, 72) = "Sello CFD"
Cells(1, 73) = "No Certificado SAT"
Cells(1, 74) = "Sello SAT"

MsgBox "Se importaron " & Application.WorksheetFunction.CountA(Hoja1.Columns(24)) - 1 & " XML", , "Luis Reyes"

MsgBox "Importación Completa", , "Luis Reyes"

   ActiveSheet.UsedRange
   .Calculation = xlCalculationAutomatic
   .EnableEvents = True
   .DisplayStatusBar = True

 End With

End Sub



20 comentarios :

  1. intente correr el programa en una version de xecel en ingles y marca error e la linea
    "Set R = Hoja1.Range("AD2").CurrentRegion 'determina apartir de donde comienza a contar"

    Deberia cambiarle algo?

    ResponderBorrar
    Respuestas
    1. Hola buen día, debes cambiar:

      Hoja1 por el nombre de tu hoja.

      Borrar
  2. Actualice el nombre y marca Object required (Error 424)

    ResponderBorrar
  3. Una consulta, como le puedo hacer para que me traiga todos los atriutos que se encuentran en nomina12:Percepcion nomina12:deduccion

    ResponderBorrar
  4. Cuanto me cobrarias por hacer que en el excel se muestre todo el contenido del xml de nominas

    ResponderBorrar
  5. La plantilla para convertir a Excel, no considera todos los conceptos de los recibos, por ejemplo el SPE efectivamente entregado al trabajador, así como el SPE que resulta de la tarifa. ¿Tendrá alguna versión completa que convierta todo el contenido del XML de nómina?

    ResponderBorrar
    Respuestas
    1. Hola buen día, estoy trabajando en una versión mas completa, espero tenerla pronto.

      Saludos!!

      Borrar
    2. Muchas gracias, en realidad su plantilla es muy útil y solamente faltaría depurarla para que incluyera todos los conceptos de ingresos y deducciones que permita "cuadrar" la información contenida. Sigo al pendiente y nuevamente gracias

      Borrar
    3. Adicionalmente, me parecería bien que propusiera un costo por proyecto, solicitando que los interesados nos inscribiéramos aportando hasta integrar el número de aportantes necesario para cubrir el proyecto. Considero que sería muy adecuado y además justo para todos. Muchas gracias

      Borrar
  6. Como siempre, código bien comentado y fácil de entender. Muchas gracias.

    ResponderBorrar
  7. Hola al tratar de ejecutar el botón me sale este mensaje
    no se puede ejecutar la macro nomina12.xlsm!auto_open. Puede que la macro no este disponible en este libro o que se hayan deshabilitado todas las macros

    ResponderBorrar
    Respuestas
    1. Hola buen día, habilitaste las macros?

      Borrar
    2. me marca el mismo error, no se puede ejecutar la macro nomina12.xlsm!auto_open, ya active las macros y nada

      Borrar
    3. Hola Luis, una disculpa, sobre el botón tienes que dar clic derecho, -> asignar macro -> en el recuadro que sale colocas: Ruta_CFDI y listo

      Borrar