ReadCFDI 2.8

ReadCFDI es una biblioteca para la lectura de nodos y atributos de comprobantes fiscales digitales en sus versiones más actuales (3.3 y 4.0).

En esta bibilioteca encontrarás funciones y métodos que te permitirán leer los acuses de cancelación y CFDI con los siguientes complementos:
  • Instituciones educativas 1.0
  • Donatarias 1.1
  • Divisas 1.0
  • Impuestos locales 1.0
  • INE 1.1
  • Comercio exterior 1.1
  • Carta porte 2.0
  • Nómina 1.2
  • Pagos 1.0
  • Pagos 2.0

Se incluyen clases para la lectura de los principales catálogos del SAT para comprobantes fiscales digitales:
  • Acuse
  • c_Banco
  • c_ClavePedimento
  • c_ClaveProdServ
  • c_ClaveUnidad
  • c_ClaveUnidadPeso
  • c_Colonia
  • c_ConfigAutotransporte
  • c_ContenedorMaritimo
  • c_CveTransporte
  • c_Estado
  • c_Exportacion
  • c_FiguraTransporte
  • c_FormaPago
  • c_FraccionArancelaria
  • c_Impuesto
  • c_Incoterm
  • c_Localidad
  • c_MaterialPeligroso
  • c_Meses
  • c_MetodoPago
  • c_Moneda
  • c_MotivoTraslado
  • c_Municipio
  • c_ObjetoImp
  • c_OrigenRecursos
  • c_Pais
  • c_ParteTransporte
  • c_Periodicidad
  • c_PeriodicidadPago
  • c_RegimenFiscal
  • c_RiesgoPuesto
  • c_SubTipoRem
  • c_TipoContrato
  • c_TipoDeComprobante
  • c_TipoDeduccion
  • c_TipoEmbalaje
  • c_TipoHoras
  • c_TipoIncapacidad
  • c_TipoJornada
  • c_TipoNomina
  • c_TipoOperacion
  • c_TipoOtroPago
  • c_TipoPercepcion
  • c_TipoPermiso
  • c_TipoRegimen
  • c_TipoRelacion
  • c_UnidadAduana
  • c_UsoCFDI

block Disponible solo para usuarios registrados.


using tagcode.ReadFDI;


//Configuración general para el uso de servicios
ConfiguracionesReadCFDI config = new ConfiguracionesReadCFDI("CFx4....Hg", "micontraseñaPIN");

//Es posible establecer la cuenta PIN para el uso de servicios
config.EstablecerPIN("CFx4....Hg", "miconstraseñaPIN");

//Podemos establecer una dirección Proxy para el paso de la información a la Red.
config.EstablecerProxy = "127.0.0.1:8888";

//Es posible establecer el comportamiento de los mensajes de errores.
config.MostrarDetallesEnErrores = true;

//Esta propiedad nos permite cambiar la URL de la API para usuarios con servicio personalizado.
config.UrlAPI = "https://...";
'Configuración general para el uso de servicios
Dim config As New ConfiguracionesReadCFDI

'Establecer la cuenta PIN para el uso de servicios (Obligatorio)
config.EstablecerPIN "CFx4....Hg", "miconstraseñaPIN"

'Podemos establecer una dirección Proxy para el paso de la información a la Red.
config.EstablecerProxy = "127.0.0.1:8888"

'Es posible establecer el comportamiento de los mensajes de errores.
config.MostrarDetallesEnErrores = True

'Esta propiedad nos permite cambiar la URL de la API para usuarios con servicio personalizado.
config.UrlAPI = "https://..."
{
  "ConfiguracionesConsola": {
    //Establece la cuenta PIN (Cuenta de timbres)
    "PIN": "CFx45...Hg",
    //Establece la contraseña de la cuenta PIN
    "PasswordPIN": "micontraseña",
    //Mostramos información mas detallada en caso de recibir un error a la hora de timbrar el documento.
    "MostrarDetallesEnErrores": true,
    //Podemos establecer una dirección Proxy para el paso de la información a la Red.
    "EstablecerProxy": "127.0.0.1:8888",
    //Indica si la salida de errores será por medio de un Archivo ó directo a la consola.
    "ErroresEnConsola": false,
    //Indica si la salida de resultados de la función ejecutada será por medio de un Archivo ó directo a la consola.
    "ResultadosEnConsola": false,
    //Cuando el campo ErroresEnConsola sea 'true', este campo será obligatorio establecerlo. (Condicional)
    "ArchivoErrores": "C:\\Errores.json",
    //Cuando el campo ResultadosEnConsola sea 'true', este campo será obligatorio establecerlo. (Condicional)
    "ArchivoResultados": "C:\\Resultados.json"
  },
  "ReadCFDI": {
    "..."
  }
}

using tagcode.ReadCFDI;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoCartaPorte.NodoMercanciasCartaPorte;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoComercioExterior;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoComercioExterior.NodoMercanciasComercioExterior;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoComercioExterior.NodoMercanciasComercioExterior.NodoMercanciaComercioExterior;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoImpuestosLocales;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoPagos10;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoPagos10.NodoPago10.NodoImpuestosPagos10.NodoRetencionesPagos10;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoPagos10.NodoPago10.NodoImpuestosPagos10.NodoTrasladosPagos10;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoPagos20;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoPagos20.NodoPago20.NodoDoctoRelacionadoPagos20;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoPagos20.NodoPago20.NodoImpuestosPPagos20.NodoRetencionesPPagos20;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoComplemento.NodoPagos20.NodoPago20.NodoImpuestosPPagos20.NodoTrasladosPPagos20;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoConceptos;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoConceptos.NodoConcepto;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoConceptos.NodoConcepto.NodoComplementoConcepto;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoImpuestos.NodoRetencionesImpuestos;
using static tagcode.ReadCFDI.ResultadosLecturaCFDI.NodoComprobante.NodoImpuestos.NodoTrasladosImpuestos;


//Configuración general para el uso de servicios (Obligatorio para poder el uso de las funciones)
ConfiguracionesReadCFDI config = new ConfiguracionesReadCFDI();

//Establece los parametros de la cuenta de timbre que se usará para la lectura.
config.EstablecerPIN("CFx45...Hg", "micontraseña");

//Mostramos información mas detallada en caso de recibir un error a la hora de generar la lectura.
config.MostrarDetallesEnErrores = true;


//Clase para lectura de comprobantes fiscales y cancelaciones
Lectura lectura = new Lectura();

//Función para obtener los datos del CFDI
ResultadosLecturaCFDI res = lectura.LeerCFDI("C:\\XML\\CfdiTimbrado.xml");

//Obtenemos los datos del comprobante
Console.WriteLine(res.Comprobante.Version);
Console.WriteLine(res.Comprobante.Fecha);
Console.WriteLine(res.Comprobante.Serie);
Console.WriteLine(res.Comprobante.Folio);
Console.WriteLine(res.Comprobante.LugarExpedicion);
Console.WriteLine(res.Comprobante.TipoDeComprobante);
Console.WriteLine(res.Comprobante.MetodoPago);
Console.WriteLine(res.Comprobante.FormaPago);
Console.WriteLine(res.Comprobante.Moneda);
Console.WriteLine(res.Comprobante.TipoCambio);
Console.WriteLine(res.Comprobante.CondicionesDePago);
Console.WriteLine(res.Comprobante.SubTotal);
Console.WriteLine(res.Comprobante.Descuento);
Console.WriteLine(res.Comprobante.Total);
Console.WriteLine(res.Comprobante.Exportacion);
Console.WriteLine(res.Comprobante.Certificado);
Console.WriteLine(res.Comprobante.Sello);
Console.WriteLine(res.Comprobante.NoCertificado);
Console.WriteLine(res.Comprobante.Confirmacion);

//Comprobamos que exista el nodo InformacionGlobal
if (res.Comprobante.InformacionGlobal != null)
{
    //Obtenemos los datos del nodo InformacionGlobal
    Console.WriteLine(res.Comprobante.InformacionGlobal.Periodicidad);
    Console.WriteLine(res.Comprobante.InformacionGlobal.Meses);
    Console.WriteLine(res.Comprobante.InformacionGlobal.Año);
}

//Comprobamos que exista el nodo CfdiRelacionados
if (res.Comprobante.CfdiRelacionados != null)
{
    //Asignamos el nodo a una variable para facilitar su lectura
    NodoCfdiRelacionados cr = res.Comprobante.CfdiRelacionados;

    //Obtenemos los datos del nodo CfdiRelacionados
    Console.WriteLine(cr.TipoRelacion);
    for (int i = 0; i < cr.CfdiRelacionado.Length; i++)
    {
        Console.WriteLine(cr.CfdiRelacionado[i].UUID);
    }
}

//Obtenemos los datos del Emisor
Console.WriteLine(res.Comprobante.Emisor.Rfc);
Console.WriteLine(res.Comprobante.Emisor.Nombre);
Console.WriteLine(res.Comprobante.Emisor.RegimenFiscal);
Console.WriteLine(res.Comprobante.Emisor.FacAtrAdquirente);

//Obtenemos los datos del Receptor
Console.WriteLine(res.Comprobante.Receptor.Rfc);
Console.WriteLine(res.Comprobante.Receptor.Nombre);
Console.WriteLine(res.Comprobante.Receptor.RegimenFiscalReceptor);
Console.WriteLine(res.Comprobante.Receptor.DomicilioFiscalReceptor);
Console.WriteLine(res.Comprobante.Receptor.UsoCFDI);
Console.WriteLine(res.Comprobante.Receptor.ResidenciaFiscal);
Console.WriteLine(res.Comprobante.Receptor.NumRegIdTrib);

//Obtenemos los datos del Concepto
for (int i = 0; i < res.Comprobante.Conceptos.Concepto.Length; i++)
{
    //Asignamos una variable de tipo Concepto para facilitar la lectura
    NodoConcepto concepto = res.Comprobante.Conceptos.Concepto[i];

    //Obtenemos los datos del concepto
    Console.WriteLine(concepto.ClaveProdServ);
    Console.WriteLine(concepto.ClaveUnidad);
    Console.WriteLine(concepto.Unidad);
    Console.WriteLine(concepto.NoIdentificacion);
    Console.WriteLine(concepto.Descripcion);
    Console.WriteLine(concepto.Cantidad);
    Console.WriteLine(concepto.ValorUnitario);
    Console.WriteLine(concepto.Importe);
    Console.WriteLine(concepto.Descuento);
    Console.WriteLine(concepto.ObjetoImp);

    //Comprobamos que existan impuestos en el concepto
    if (concepto.Impuestos != null)
    {
        //Asignamos una variable de tipo ImpuestoConcepto para facilitar la lectura
        NodoImpuestosConcepto impuestos = concepto.Impuestos;

        //Comprobamos que existan impuestos Retenciones
        if (impuestos.Retenciones != null)
        {
            for (int ii = 0; ii < impuestos.Retenciones.Retencion.Length; ii++)
            {
                //Obtenemos los datos del impuesto
                Console.WriteLine(impuestos.Retenciones.Retencion[ii].Base);
                Console.WriteLine(impuestos.Retenciones.Retencion[ii].Impuesto);
                Console.WriteLine(impuestos.Retenciones.Retencion[ii].TipoFactor);
                Console.WriteLine(impuestos.Retenciones.Retencion[ii].TasaOCuota);
                Console.WriteLine(impuestos.Retenciones.Retencion[ii].Importe);
            }
        }

        //Comprobamos que existan impuestos Traslados
        if (impuestos.Traslados != null)
        {
            for (int ii = 0; ii < impuestos.Traslados.Traslado.Length; ii++)
            {
                //Obtenemos los datos del impuesto
                Console.WriteLine(impuestos.Traslados.Traslado[ii].Base);
                Console.WriteLine(impuestos.Traslados.Traslado[ii].Impuesto);
                Console.WriteLine(impuestos.Traslados.Traslado[ii].TipoFactor);
                Console.WriteLine(impuestos.Traslados.Traslado[ii].TasaOCuota);
                Console.WriteLine(impuestos.Traslados.Traslado[ii].Importe);
            }
        }
    }

    //Comprobamos que existan nodos de información aduanera
    if (concepto.InformacionAduanera != null)
    {
        //Obtenemos los datos de todos los nodos de la información aduanera del concepto
        for (int ii = 0; ii < concepto.InformacionAduanera.Length; ii++)
        {
            Console.WriteLine(concepto.InformacionAduanera[ii].NumeroPedimento);
        }
    }

    //Comprobamos que exista el nodo cuenta predial
    if (concepto.CuentaPredial != null)
    {
        //Obtenemos el numero de la cuenta predial
        Console.WriteLine(concepto.CuentaPredial.Numero);
    }

    //Comprobamos que exista el nodo ACuentaTerceros
    if (concepto.ACuentaTerceros != null)
    {
        //obtenemos todos sus datos
        Console.WriteLine(concepto.ACuentaTerceros.RfcACuentaTerceros);
        Console.WriteLine(concepto.ACuentaTerceros.NombreACuentaTerceros);
        Console.WriteLine(concepto.ACuentaTerceros.RegimenFiscalACuentaTerceros);
        Console.WriteLine(concepto.ACuentaTerceros.DomicilioFiscalACuentaTerceros);
    }

    //Comprobamos que exista el nodo ComplementoConcepto
    if (concepto.ComplementoConcepto != null)
    {
        //Revisamos los complementos existentes
        if (concepto.ComplementoConcepto.instEducativas != null)
        {
            //Asignamos una variable para facilitar su lectura
            NodoinstEducativas iedu = concepto.ComplementoConcepto.instEducativas;

            //Obtenemos sus datos
            Console.WriteLine(iedu.version);
            Console.WriteLine(iedu.nombreAlumno);
            Console.WriteLine(iedu.nivelEducativo);
            Console.WriteLine(iedu.CURP);
            Console.WriteLine(iedu.autRVOE);
            Console.WriteLine(iedu.rfcPago);
        }
    }

    //Comprobamos que existan los nodos Parte
    if (concepto.Parte != null)
    {
        for (int ii = 0; ii < concepto.Parte.Length; ii++)
        {
            //Asignamos una variable de tipo Parte para facilitar la lectura
            NodoParte parte = concepto.Parte[i];

            //Obtenemos los datos del nodo Parte
            Console.WriteLine(parte.ClaveProdServ);
            Console.WriteLine(parte.Unidad);
            Console.WriteLine(parte.NoIdentificacion);
            Console.WriteLine(parte.Descripcion);
            Console.WriteLine(parte.Cantidad);
            Console.WriteLine(parte.ValorUnitario);
            Console.WriteLine(parte.Importe);

            //Comprobamos que el nodo Parte tenga información aduanera
            if (parte.InformacionAduanera != null)
            {
                //Obtenemos todos los datos de los nodos de la información aduanera
                for (int iii = 0; iii < parte.InformacionAduanera.Length; i++)
                {
                    Console.WriteLine(parte.InformacionAduanera[iii].NumeroPedimento);
                }
            }
        }
    }
}

//Comprobamos que exista nodo de Impuestos en el comprobante
if (res.Comprobante.Impuestos != null)
{
    //Obtenemos los totales de impuestos
    Console.WriteLine(res.Comprobante.Impuestos.TotalImpuestosRetenidos);
    Console.WriteLine(res.Comprobante.Impuestos.TotalImpuestosTrasladados);

    //Comprobamos que existan nodos de impuestos retenidos
    if (res.Comprobante.Impuestos.Retenciones != null)
    {
        for (int i = 0; i < res.Comprobante.Impuestos.Retenciones.Retencion.Length; i++)
        {
            //Asignamos los valores a una variable de tipo Retenciones para facilitar su lectura
            NodoRetencionImpuestos retencion = res.Comprobante.Impuestos.Retenciones.Retencion[i];

            //Obtenemos todos los datos de la retención
            Console.WriteLine(retencion.Impuesto);
            Console.WriteLine(retencion.Importe);
        }
    }

    //Comprobamos que existan nodos de impuestos trasladados
    if (res.Comprobante.Impuestos.Traslados != null)
    {
        for (int i = 0; i < res.Comprobante.Impuestos.Traslados.Traslado.Length; i++)
        {
            //Asignamos los valores a una variable de tipo Trasladados para facilitar su lectura
            NodoTrasladoImpuestos traslado = res.Comprobante.Impuestos.Traslados.Traslado[i];

            //Obtenemos todos los datos del impuesto trasladado
            Console.WriteLine(traslado.Base);
            Console.WriteLine(traslado.Impuesto);
            Console.WriteLine(traslado.TipoFactor);
            Console.WriteLine(traslado.TasaOCuota);
            Console.WriteLine(traslado.Importe);
        }
    }
}

//Comprobamos si existen el nodo Complementos
if (res.Comprobante.Complemento != null)
{
    //Comprobamos si existe el complemento Divisas
    if (res.Comprobante.Complemento.Divisas != null)
    {
        //Obtenemos el tipo de operación
        Console.WriteLine(res.Comprobante.Complemento.Divisas.tipoOperacion);
    }

    //Comprobamos si existe el complemento Donatarias
    if (res.Comprobante.Complemento.Donatarias != null)
    {
        //Obtenemos los datos de la Donataria
        Console.WriteLine(res.Comprobante.Complemento.Donatarias.version);
        Console.WriteLine(res.Comprobante.Complemento.Donatarias.noAutorizacion);
        Console.WriteLine(res.Comprobante.Complemento.Donatarias.fechaAutorizacion);
        Console.WriteLine(res.Comprobante.Complemento.Donatarias.leyenda);
    }

    if (res.Comprobante.Complemento.ImpuestosLocales != null)
    {
        //Obtenemos los datos del complemento Impuestos locales
        Console.WriteLine(res.Comprobante.Complemento.ImpuestosLocales.version);
        Console.WriteLine(res.Comprobante.Complemento.ImpuestosLocales.TotaldeRetenciones);
        Console.WriteLine(res.Comprobante.Complemento.ImpuestosLocales.TotaldeTraslados);

        //Comprobamos que la variable contenga información
        if (res.Comprobante.Complemento.ImpuestosLocales.TrasladosLocales != null)
        {
            //Asignamos variable de los impuestos trasladados para facilitar la lectura
            NodoTrasladosImpuestosLocales[] traslados = res.Comprobante.Complemento.ImpuestosLocales.TrasladosLocales;

            //Obtenemos la información de cada impuesto trasladado local
            for (int i = 0; i < traslados.Length; i++)
            {
                Console.WriteLine(traslados[i].ImpLocTrasladado);
                Console.WriteLine(traslados[i].TasadeTraslado);
                Console.WriteLine(traslados[i].Importe);
            }
        }

        //Comprobamos que la variable contenga información
        if (res.Comprobante.Complemento.ImpuestosLocales.RetencionesLocales != null)
        {
            //Asignamos variable de los impuestos retenidos para facilitar la lectura
            NodoRetencionesImpuestosLocales[] retenciones = res.Comprobante.Complemento.ImpuestosLocales.RetencionesLocales;

            //Obtenemos la información de cada impuesto retenido local
            for (int i = 0; i < retenciones.Length; i++)
            {
                Console.WriteLine(retenciones[i].ImpLocRetenido);
                Console.WriteLine(retenciones[i].TasadeRetencion);
                Console.WriteLine(retenciones[i].Importe);
            }
        }
    }

    //Comprobamos si existe el complemento INE
    if (res.Comprobante.Complemento.INE != null)
    {
        //Obtenemos los datos del complemento INE
        Console.WriteLine(res.Comprobante.Complemento.INE.Version);
        Console.WriteLine(res.Comprobante.Complemento.INE.TipoProceso);
        Console.WriteLine(res.Comprobante.Complemento.INE.TipoComite);
        Console.WriteLine(res.Comprobante.Complemento.INE.IdContabilidad);

        //Comprobamos que el complemento tenga nodo Entidad
        if (res.Comprobante.Complemento.INE.Entidad != null)
        {
            //Obtenemos todos los datos de los nodos Entidad
            for (int i = 0; i < res.Comprobante.Complemento.INE.Entidad.Length; i++)
            {
                Console.WriteLine(res.Comprobante.Complemento.INE.Entidad[i].Ambito);
                Console.WriteLine(res.Comprobante.Complemento.INE.Entidad[i].ClaveEntidad);

                //Comprobamos que cada nodo entidad tenga nodos Contabilidad
                if (res.Comprobante.Complemento.INE.Entidad[i].Contabilidad != null)
                {
                    //Obtenemos los datos de los nodos Contabilidad
                    for (int ii = 0; ii < res.Comprobante.Complemento.INE.Entidad[i].Contabilidad.Length; ii++)
                    {
                        Console.WriteLine(res.Comprobante.Complemento.INE.Entidad[i].Contabilidad[ii].IdContabilidad);
                    }
                }
            }
        }
    }

    //Comprobamos si existe el complemento Comercio Exterior
    if (res.Comprobante.Complemento.ComercioExterior != null)
    {
        //Asignamos el complemento a una variable para facilitar la lectura
        NodoComercioExterior comext = res.Comprobante.Complemento.ComercioExterior;

        Console.WriteLine(comext.Version);
        Console.WriteLine(comext.TipoOperacion);
        Console.WriteLine(comext.MotivoTraslado);
        Console.WriteLine(comext.Incoterm);
        Console.WriteLine(comext.Subdivision);
        Console.WriteLine(comext.ClaveDePedimento);
        Console.WriteLine(comext.NumCertificadoOrigen);
        Console.WriteLine(comext.CertificadoOrigen);
        Console.WriteLine(comext.NumeroExportadorConfiable);
        Console.WriteLine(comext.Observaciones);
        Console.WriteLine(comext.TipoCambioUSD);
        Console.WriteLine(comext.TotalUSD);

        //Comprobamos que exista el nodo Emisor de Comercio Exterior
        if (comext.Emisor != null)
        {
            //Obtenemos los datos del emisor
            Console.WriteLine(comext.Emisor.Curp);

            //Comprobamos que exista domicilio en el emisor del comercio exterior
            if (comext.Emisor.Domicilio != null)
            {
                //Obtenemos todos los datos del domicilio
                Console.WriteLine(comext.Emisor.Domicilio.Calle);
                Console.WriteLine(comext.Emisor.Domicilio.NumeroExterior);
                Console.WriteLine(comext.Emisor.Domicilio.NumeroInterior);
                Console.WriteLine(comext.Emisor.Domicilio.Colonia);
                Console.WriteLine(comext.Emisor.Domicilio.CodigoPostal);
                Console.WriteLine(comext.Emisor.Domicilio.Referencia);
                Console.WriteLine(comext.Emisor.Domicilio.Localidad);
                Console.WriteLine(comext.Emisor.Domicilio.Municipio);
                Console.WriteLine(comext.Emisor.Domicilio.Estado);
                Console.WriteLine(comext.Emisor.Domicilio.Pais);
            }
        }

        //Comprobamos que exista el nodo Receptor de Comercio Exterior
        if (comext.Receptor != null)
        {
            //Obtenemos los datos del receptor
            Console.WriteLine(comext.Receptor.NumRegIdTrib);

            //Comprobamos que exista domicilio en el receptor del comercio exterior
            if (comext.Receptor.Domicilio != null)
            {
                //Obtenemos todos los datos del domicilio
                Console.WriteLine(comext.Receptor.Domicilio.Calle);
                Console.WriteLine(comext.Receptor.Domicilio.NumeroExterior);
                Console.WriteLine(comext.Receptor.Domicilio.NumeroInterior);
                Console.WriteLine(comext.Receptor.Domicilio.Colonia);
                Console.WriteLine(comext.Receptor.Domicilio.CodigoPostal);
                Console.WriteLine(comext.Receptor.Domicilio.Referencia);
                Console.WriteLine(comext.Receptor.Domicilio.Localidad);
                Console.WriteLine(comext.Receptor.Domicilio.Municipio);
                Console.WriteLine(comext.Receptor.Domicilio.Estado);
                Console.WriteLine(comext.Receptor.Domicilio.Pais);
            }
        }

        //Comprobamos que existan nodos Propietario de Comercio Exterior
        if (comext.Propietario != null)
        {
            //Obtenemos los datos de cada nodo Propietario
            for (int i = 0; i < comext.Propietario.Length; i++)
            {
                Console.WriteLine(comext.Propietario[i].NumRegIdTrib);
                Console.WriteLine(comext.Propietario[i].ResidenciaFiscal);
            }
        }

        //Comprobamos que existan nodos Destinatarios de Comercio Exterior
        if (comext.Destinatario != null)
        {
            //Obtenemos los datos del receptor
            for (int i = 0; i < comext.Destinatario.Length; i++)
            {
                //Asignamos una variable de lectura al nodo Destinatario
                NodoDestinatarioComercioExterior destinatario = comext.Destinatario[i];

                Console.WriteLine(destinatario.Nombre);
                Console.WriteLine(destinatario.NumRegIdTrib);

                //Comprobamos que exista domicilio en el destinatario del comercio exterior
                if (destinatario.Domicilio != null)
                {
                    //Recorremos todos los domicilios del destinatario
                    for (int ii = 0; ii < comext.Destinatario[i].Domicilio.Length; ii++)
                    {
                        //Obtenemos todos los datos del domicilio
                        Console.WriteLine(destinatario.Domicilio[ii].Calle);
                        Console.WriteLine(destinatario.Domicilio[ii].NumeroExterior);
                        Console.WriteLine(destinatario.Domicilio[ii].NumeroInterior);
                        Console.WriteLine(destinatario.Domicilio[ii].Colonia);
                        Console.WriteLine(destinatario.Domicilio[ii].CodigoPostal);
                        Console.WriteLine(destinatario.Domicilio[ii].Referencia);
                        Console.WriteLine(destinatario.Domicilio[ii].Localidad);
                        Console.WriteLine(destinatario.Domicilio[ii].Municipio);
                        Console.WriteLine(destinatario.Domicilio[ii].Estado);
                        Console.WriteLine(destinatario.Domicilio[ii].Pais);
                    }
                }
            }
        }

        //Comprobamos que existan mercancias en el complemento comercio exterior
        if (comext.Mercancias != null)
        {
            //Obtenemos todos los datos de las mercancias
            for (int i = 0; i < comext.Mercancias.Mercancia.Length; i++)
            {
                //Asignamos una variable por cada mercancia para facilitar la lectura
                NodoMercanciaComercioExterior mercancia = comext.Mercancias.Mercancia[i];

                Console.WriteLine(mercancia.FraccionArancelaria);
                Console.WriteLine(mercancia.UnidadAduana);
                Console.WriteLine(mercancia.NoIdentificacion);
                Console.WriteLine(mercancia.CantidadAduana);
                Console.WriteLine(mercancia.ValorUnitarioAduana);
                Console.WriteLine(mercancia.ValorDolares);

                //Comprobamos que existan descripciones específicas en la mercancia
                if (mercancia.DescripcionesEspecificas != null)
                {
                    for (int ii = 0; ii < mercancia.DescripcionesEspecificas.Length; ii++)
                    {
                        //Asignamos una variable de descripciones específicas para facilitar la lectura de cada nodo
                        NodoDescripcionesEspecificasComercioExterior descripciones = mercancia.DescripcionesEspecificas[ii];

                        //Obtenemos los datos de la descripción específica
                        Console.WriteLine(descripciones.Marca);
                        Console.WriteLine(descripciones.Modelo);
                        Console.WriteLine(descripciones.SubModelo);
                        Console.WriteLine(descripciones.NumeroSerie);
                    }
                }
            }
        }
    }

    //Comprobamos que exista complemento de Pagos 1.0
    if (res.Comprobante.Complemento.Pagos10 != null)
    {
        //Obtenemos los datos del complemento Pagos 1.0
        Console.WriteLine(res.Comprobante.Complemento.Pagos10.Version);

        for (int i = 0; i < res.Comprobante.Complemento.Pagos10.Pago.Length; i++)
        {
            //Asignamos una variable de tipo Pago para facilitar la lectura
            NodoPago10 pago = res.Comprobante.Complemento.Pagos10.Pago[i];

            //Obtenemos los datos del nodo Pago
            Console.WriteLine(pago.FechaPago);
            Console.WriteLine(pago.FormaDePagoP);
            Console.WriteLine(pago.CadPago);
            Console.WriteLine(pago.CertPago);
            Console.WriteLine(pago.CtaBeneficiario);
            Console.WriteLine(pago.CtaOrdenante);
            Console.WriteLine(pago.MonedaP);
            Console.WriteLine(pago.Monto);
            Console.WriteLine(pago.NomBancoOrdExt);
            Console.WriteLine(pago.NumOperacion);
            Console.WriteLine(pago.RfcEmisorCtaBen);
            Console.WriteLine(pago.RfcEmisorCtaOrd);
            Console.WriteLine(pago.SelloPago);
            Console.WriteLine(pago.TipoCadPago);
            Console.WriteLine(pago.TipoCambioP);

            //Comprobamos que el pago contenga nodos DoctoRelacionado
            if (pago.DoctoRelacionado != null)
            {
                //Obtenemos los datos de cada DoctoRelacionado
                for (int ii = 0; ii < pago.DoctoRelacionado.Length; ii++)
                {
                    Console.WriteLine(pago.DoctoRelacionado[ii].IdDocumento);
                    Console.WriteLine(pago.DoctoRelacionado[ii].Serie);
                    Console.WriteLine(pago.DoctoRelacionado[ii].Folio);
                    Console.WriteLine(pago.DoctoRelacionado[ii].MetodoDePagoDR);
                    Console.WriteLine(pago.DoctoRelacionado[ii].MonedaDR);
                    Console.WriteLine(pago.DoctoRelacionado[ii].TipoCambioDR);
                    Console.WriteLine(pago.DoctoRelacionado[ii].NumParcialidad);
                    Console.WriteLine(pago.DoctoRelacionado[ii].ImpSaldoAnt);
                    Console.WriteLine(pago.DoctoRelacionado[ii].ImpPagado);
                    Console.WriteLine(pago.DoctoRelacionado[ii].ImpSaldoInsoluto);
                }
            }

            //Comprobamos que el pago contenga nodo Impuestos
            if (pago.Impuestos != null)
            {
                //Comprobamos que contenga impuestos retenidos
                if (pago.Impuestos.Retenciones.Retencion != null)
                {
                    //Obtenemos los datos de cada impuesto retenido
                    for (int ii = 0; ii < pago.Impuestos.Retenciones.Retencion.Length; ii++)
                    {
                        //Asignamos el impuesto para facilitar la lectura
                        NodoRetencionPagos10 retencion10 = pago.Impuestos.Retenciones.Retencion[ii];

                        Console.WriteLine(retencion10.Impuesto);
                        Console.WriteLine(retencion10.Importe);
                    }
                }

                //Comprobamos que contenga impuestos trasladados
                if (pago.Impuestos.Traslados != null)
                {
                    //Obtenemos los datos de cada impuesto trasladado
                    for (int ii = 0; ii < pago.Impuestos.Traslados.Traslado.Length; ii++)
                    {
                        //Asignamos el impuesto para facilitar la lectura
                        NodoTrasladoPagos10 traslado10 = pago.Impuestos.Traslados.Traslado[ii];

                        Console.WriteLine(traslado10.Impuesto);
                        Console.WriteLine(traslado10.TipoFactor);
                        Console.WriteLine(traslado10.TasaOCuota);
                        Console.WriteLine(traslado10.Importe);
                    }
                }
            }
        }
    }

    //Comprobamos que exista complemento de Pagos 2.0
    if (res.Comprobante.Complemento.Pagos20 != null)
    {
        //Obtenemos los datos del complemento Pagos 2.0
        Console.WriteLine(res.Comprobante.Complemento.Pagos20.Version);

        //Asignamos una variable al nodo Totales para facilitar la lectura
        NodoTotalesPagos20 totales = res.Comprobante.Complemento.Pagos20.Totales;

        Console.WriteLine(totales.MontoTotalPagos);
        Console.WriteLine(totales.TotalRetencionesIEPS);
        Console.WriteLine(totales.TotalRetencionesISR);
        Console.WriteLine(totales.TotalRetencionesIVA);
        Console.WriteLine(totales.TotalTrasladosBaseExento);
        Console.WriteLine(totales.TotalTrasladosBaseIVA0);
        Console.WriteLine(totales.TotalTrasladosImpuestoIVA0);
        Console.WriteLine(totales.TotalTrasladosBaseIVA8);
        Console.WriteLine(totales.TotalTrasladosImpuestoIVA8);
        Console.WriteLine(totales.TotalTrasladosBaseIVA16);
        Console.WriteLine(totales.TotalTrasladosImpuestoIVA16);

        //Obtenemos los datos de todos los nodos de Pago
        for (int i = 0; i < res.Comprobante.Complemento.Pagos20.Pago.Length; i++)
        {
            //Asignamos una variable de tipo Pago para facilitar la lectura
            NodoPago20 pago20 = res.Comprobante.Complemento.Pagos20.Pago[i];

            Console.WriteLine(pago20.FechaPago);
            Console.WriteLine(pago20.FormaDePagoP);
            Console.WriteLine(pago20.CadPago);
            Console.WriteLine(pago20.CertPago);
            Console.WriteLine(pago20.CtaBeneficiario);
            Console.WriteLine(pago20.CtaOrdenante);
            Console.WriteLine(pago20.MonedaP);
            Console.WriteLine(pago20.Monto);
            Console.WriteLine(pago20.NomBancoOrdExt);
            Console.WriteLine(pago20.NumOperacion);
            Console.WriteLine(pago20.RfcEmisorCtaBen);
            Console.WriteLine(pago20.RfcEmisorCtaOrd);
            Console.WriteLine(pago20.SelloPago);
            Console.WriteLine(pago20.TipoCadPago);
            Console.WriteLine(pago20.TipoCambioP);

            //Comprobamos que el pago contenga nodos DoctoRelacionado
            if (pago20.DoctoRelacionado != null)
            {
                //Obtenemos los datos de cada DoctoRelacionado
                for (int ii = 0; ii < pago20.DoctoRelacionado.Length; i++)
                {
                    Console.WriteLine(pago20.DoctoRelacionado[ii].IdDocumento);
                    Console.WriteLine(pago20.DoctoRelacionado[ii].Serie);
                    Console.WriteLine(pago20.DoctoRelacionado[ii].Folio);
                    Console.WriteLine(pago20.DoctoRelacionado[ii].MonedaDR);
                    Console.WriteLine(pago20.DoctoRelacionado[ii].EquivalenciaDR);
                    Console.WriteLine(pago20.DoctoRelacionado[ii].NumParcialidad);
                    Console.WriteLine(pago20.DoctoRelacionado[ii].ImpSaldoAnt);
                    Console.WriteLine(pago20.DoctoRelacionado[ii].ImpPagado);
                    Console.WriteLine(pago20.DoctoRelacionado[ii].ImpSaldoInsoluto);
                    Console.WriteLine(pago20.DoctoRelacionado[ii].ObjetoImpDR);

                    //Comprobamos si el documento relacionado tiene impuestos
                    if (pago20.DoctoRelacionado[ii].ImpuestosDR != null)
                    {
                        //Asignamos una variable de impuestos para facilitar la lectura
                        NodoImpuestosDRPagos20 impdr = pago20.DoctoRelacionado[ii].ImpuestosDR;

                        //Confirmamos que existan impuestos retenidos
                        if (impdr.RetencionesDR != null)
                        {

                            //Obtenemos todos los datos de los impuestos
                            for (int iii = 0; iii < impdr.RetencionesDR.RetencionDR.Length; iii++)
                            {
                                Console.WriteLine(impdr.RetencionesDR.RetencionDR[iii].BaseDR);
                                Console.WriteLine(impdr.RetencionesDR.RetencionDR[iii].ImpuestoDR);
                                Console.WriteLine(impdr.RetencionesDR.RetencionDR[iii].TipoFactorDR);
                                Console.WriteLine(impdr.RetencionesDR.RetencionDR[iii].TasaOCuotaDR);
                                Console.WriteLine(impdr.RetencionesDR.RetencionDR[iii].ImporteDR);
                            }
                        }

                        //Confirmamos que existan impuestos trasladados
                        if (impdr.TrasladosDR != null)
                        {
                            //Obtenemos todos los datos de los impuestos
                            for (int iii = 0; iii < impdr.TrasladosDR.TrasladoDR.Length; iii++)
                            {
                                Console.WriteLine(impdr.TrasladosDR.TrasladoDR[iii].BaseDR);
                                Console.WriteLine(impdr.TrasladosDR.TrasladoDR[iii].ImpuestoDR);
                                Console.WriteLine(impdr.TrasladosDR.TrasladoDR[iii].TipoFactorDR);
                                Console.WriteLine(impdr.TrasladosDR.TrasladoDR[iii].TasaOCuotaDR);
                                Console.WriteLine(impdr.TrasladosDR.TrasladoDR[iii].ImporteDR);
                            }
                        }
                    }
                }
            }

            //Comprobamos que el pago contenga nodo Impuestos
            if (pago20.ImpuestosP != null)
            {
                //Comprobamos que contenga impuestos retenidos
                if (pago20.ImpuestosP.RetencionesP != null)
                {
                    //Obtenemos los datos de cada impuesto retenido
                    for (int ii = 0; ii < pago20.ImpuestosP.RetencionesP.RetencionP.Length; i++)
                    {
                        //Asignamos el impuesto para facilitar la lectura
                        NodoRetencionPPagos20 retencion20 = pago20.ImpuestosP.RetencionesP.RetencionP[ii];

                        Console.WriteLine(retencion20.ImpuestoP);
                        Console.WriteLine(retencion20.ImporteP);
                    }
                }

                //Comprobamos que contenga impuestos trasladados
                if (pago20.ImpuestosP.TrasladosP != null)
                {
                    //Obtenemos los datos de cada impuesto trasladado
                    for (int ii = 0; ii < pago20.ImpuestosP.TrasladosP.TrasladoP.Length; i++)
                    {
                        //Asignamos el impuesto para facilitar la lectura
                        NodoTrasladoPPagos20 traslado20 = pago20.ImpuestosP.TrasladosP.TrasladoP[ii];

                        Console.WriteLine(traslado20.BaseP);
                        Console.WriteLine(traslado20.ImpuestoP);
                        Console.WriteLine(traslado20.TipoFactorP);
                        Console.WriteLine(traslado20.TasaOCuotaP);
                        Console.WriteLine(traslado20.ImporteP);
                    }
                }
            }
        }
    }

    //Comprobamos que exista complemento Nómina
    if (res.Comprobante.Complemento.Nomina != null)
    {
        //Asignamos una variable del nodo Nómina para facilitar la lectura
        NodoNomina Nomina = res.Comprobante.Complemento.Nomina;

        Console.WriteLine(Nomina.Version);
        Console.WriteLine(Nomina.TipoNomina);
        Console.WriteLine(Nomina.FechaPago);
        Console.WriteLine(Nomina.FechaInicialPago);
        Console.WriteLine(Nomina.FechaFinalPago);
        Console.WriteLine(Nomina.NumDiasPagados);

        //Comprobamos que existan percepciones en el complemento
        if (Nomina.Percepciones != null)
        {
            //Obtenemos los datos de las percepciones
            Console.WriteLine(Nomina.Percepciones.TotalSueldos);
            Console.WriteLine(Nomina.Percepciones.TotalSeparacionIndemnizacion);
            Console.WriteLine(Nomina.Percepciones.TotalJubilacionPensionRetiro);
            Console.WriteLine(Nomina.Percepciones.TotalExento);
            Console.WriteLine(Nomina.Percepciones.TotalGravado);

            //Comprobamos que exista nodo JubilacionPensionRetiro
            if (Nomina.Percepciones.JubilacionPensionRetiro != null)
            {
                //Obtenemos los datos del nodo JubilacionPensionRetiro
                Console.WriteLine(Nomina.Percepciones.JubilacionPensionRetiro.TotalUnaExhibicion);
                Console.WriteLine(Nomina.Percepciones.JubilacionPensionRetiro.TotalParcialidad);
                Console.WriteLine(Nomina.Percepciones.JubilacionPensionRetiro.MontoDiario);
                Console.WriteLine(Nomina.Percepciones.JubilacionPensionRetiro.IngresoAcumulable);
                Console.WriteLine(Nomina.Percepciones.JubilacionPensionRetiro.IngresoNoAcumulable);
            }

            //Comprobamos que exista nodo SeparacionIndemnizacion
            if (Nomina.Percepciones.SeparacionIndemnizacion != null)
            {
                //Obtenemos los datos del nodo JubilacionPensionRetiro
                Console.WriteLine(Nomina.Percepciones.SeparacionIndemnizacion.UltimoSueldoMensOrd);
                Console.WriteLine(Nomina.Percepciones.SeparacionIndemnizacion.TotalPagado);
                Console.WriteLine(Nomina.Percepciones.SeparacionIndemnizacion.NumAñosServicio);
                Console.WriteLine(Nomina.Percepciones.SeparacionIndemnizacion.IngresoAcumulable);
                Console.WriteLine(Nomina.Percepciones.SeparacionIndemnizacion.IngresoNoAcumulable);
            }

            //Obtenemos todos los nodos de percepción
            for (int i = 0; i < Nomina.Percepciones.Percepcion.Length; i++)
            {
                Console.WriteLine(Nomina.Percepciones.Percepcion[i].TipoPercepcion);
                Console.WriteLine(Nomina.Percepciones.Percepcion[i].Clave);
                Console.WriteLine(Nomina.Percepciones.Percepcion[i].Concepto);
                Console.WriteLine(Nomina.Percepciones.Percepcion[i].ImporteExento);
                Console.WriteLine(Nomina.Percepciones.Percepcion[i].ImporteGravado);

                //Comprobamos que existan horas extras en la percepción
                if (Nomina.Percepciones.Percepcion[i].HorasExtra != null)
                {
                    //Obtenemos los datos de las horas extra
                    for (int ii = 0; ii < Nomina.Percepciones.Percepcion[i].HorasExtra.Length; ii++)
                    {
                        Console.WriteLine(Nomina.Percepciones.Percepcion[i].HorasExtra[ii].Dias);
                        Console.WriteLine(Nomina.Percepciones.Percepcion[i].HorasExtra[ii].HorasExtra);
                        Console.WriteLine(Nomina.Percepciones.Percepcion[i].HorasExtra[ii].ImportePagado);
                        Console.WriteLine(Nomina.Percepciones.Percepcion[i].HorasExtra[ii].TipoHoras);
                    }
                }

                //Comprobamos que exista nodo AccionesOTitulos
                if (Nomina.Percepciones.Percepcion[i].AccionesOTitulos != null)
                {
                    //Obtenemos todos los datos del nodo AccionesOTitulos
                    Console.WriteLine(Nomina.Percepciones.Percepcion[i].AccionesOTitulos.PrecioAlOtorgarse);
                    Console.WriteLine(Nomina.Percepciones.Percepcion[i].AccionesOTitulos.ValorMercado);
                }
            }
        }

        //Comprobamos que existan deducciones en el complemento
        if (Nomina.Deducciones != null)
        {
            //Obtenemos los datos de las deducciones
            Console.WriteLine(Nomina.Deducciones.TotalImpuestosRetenidos);
            Console.WriteLine(Nomina.Deducciones.TotalOtrasDeducciones);

            //Obtenemos todos los nodos de deducción
            for (int i = 0; i < Nomina.Deducciones.Deduccion.Length; i++)
            {
                Console.WriteLine(Nomina.Deducciones.Deduccion[i].TipoDeduccion);
                Console.WriteLine(Nomina.Deducciones.Deduccion[i].Clave);
                Console.WriteLine(Nomina.Deducciones.Deduccion[i].Concepto);
                Console.WriteLine(Nomina.Deducciones.Deduccion[i].Importe);
            }
        }

        //Comprobamos que existan otros pagos en el complemento
        if (Nomina.OtrosPagos != null)
        {
            //Obtenemos todos los nodos de otros pagos
            for (int i = 0; i < Nomina.OtrosPagos.OtroPago.Length; i++)
            {
                Console.WriteLine(Nomina.OtrosPagos.OtroPago[i].TipoOtroPago);
                Console.WriteLine(Nomina.OtrosPagos.OtroPago[i].Clave);
                Console.WriteLine(Nomina.OtrosPagos.OtroPago[i].Concepto);
                Console.WriteLine(Nomina.OtrosPagos.OtroPago[i].Importe);

                //Comprobamos que exista nodo SubsidioAlEmpleo
                if (Nomina.OtrosPagos.OtroPago[i].SubsidioAlEmpleo != null)
                {
                    //Obtenemos todos los datos del nodo SubsidioAlEmpleo
                    Console.WriteLine(Nomina.OtrosPagos.OtroPago[i].SubsidioAlEmpleo.SubsidioCausado);
                }

                //Comprobamos que exista el nodo CompensacionSaldosAFavor
                if (Nomina.OtrosPagos.OtroPago[i].CompensacionSaldosAFavor != null)
                {
                    //Obtenemos todos los datos del nodo CompensacionSaldosAFavor
                    Console.WriteLine(Nomina.OtrosPagos.OtroPago[i].CompensacionSaldosAFavor.Año);
                    Console.WriteLine(Nomina.OtrosPagos.OtroPago[i].CompensacionSaldosAFavor.RemanenteSalFav);
                    Console.WriteLine(Nomina.OtrosPagos.OtroPago[i].CompensacionSaldosAFavor.SaldoAFavor);
                }
            }
        }

        //Comprobamos que existan incapacidades en el complemento
        if (Nomina.Incapacidades != null)
        {
            //Obtenemos todos los nodos de incapacidad
            for (int i = 0; i < Nomina.Incapacidades.Incapacidad.Length; i++)
            {
                Console.WriteLine(Nomina.Incapacidades.Incapacidad[i].TipoIncapacidad);
                Console.WriteLine(Nomina.Incapacidades.Incapacidad[i].DiasIncapacidad);
                Console.WriteLine(Nomina.Incapacidades.Incapacidad[i].ImporteMonetario);
            }
        }
    }

    //Comprobamos que exista complemento Carta porte 2.0
    if (res.Comprobante.Complemento.CartaPorte != null)
    {
        //Asignamos una variable al complemento para facilitar la lectura
        NodoCartaPorte CartaPorte = res.Comprobante.Complemento.CartaPorte;

        //Obtenemos los datos del nodo CartaPorte
        Console.WriteLine(CartaPorte.Version);
        Console.WriteLine(CartaPorte.EntradaSalidaMerc);
        Console.WriteLine(CartaPorte.PaisOrigenDestino);
        Console.WriteLine(CartaPorte.TotalDistRec);
        Console.WriteLine(CartaPorte.TranspInternac);
        Console.WriteLine(CartaPorte.ViaEntradaSalida);

        //Comprobamos que exista nodo Ubicaciones
        if (CartaPorte.Ubicaciones != null)
        {
            //Obtenemos los datos de cada nodo Ubicaciones
            for (int i = 0; i < CartaPorte.Ubicaciones.Ubicacion.Length; i++)
            {
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].RFCRemitenteDestinatario);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].NombreRemitenteDestinatario);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].NumRegIdTrib);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].ResidenciaFiscal);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].TipoUbicacion);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].IDUbicacion);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].FechaHoraSalidaLlegada);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].TipoEstacion);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].DistanciaRecorrida);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].NavegacionTrafico);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].NumEstacion);
                Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].NombreEstacion);

                //Comprobamos que exista el nodo Domicilio
                if (CartaPorte.Ubicaciones.Ubicacion[i].Domicilio != null)
                {
                    //Obtenemos todos los datos del nodo Domicilio
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.Calle);
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.NumeroExterior);
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.NumeroInterior);
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.Colonia);
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.CodigoPostal);
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.Referencia);
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.Localidad);
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.Municipio);
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.Estado);
                    Console.WriteLine(CartaPorte.Ubicaciones.Ubicacion[i].Domicilio.Pais);
                }
            }
        }

        //Comprobamos que exista nodo Mercancias
        if (CartaPorte.Mercancias != null)
        {
            //Obtenemos todos los datos del nodo Mercancias
            Console.WriteLine(CartaPorte.Mercancias.CargoPorTasacion);
            Console.WriteLine(CartaPorte.Mercancias.NumTotalMercancias);
            Console.WriteLine(CartaPorte.Mercancias.PesoBrutoTotal);
            Console.WriteLine(CartaPorte.Mercancias.PesoNetoTotal);
            Console.WriteLine(CartaPorte.Mercancias.UnidadPeso);

            //Obtenemos todos los nodos de Mercancia
            for (int i = 0; i < CartaPorte.Mercancias.Mercancia.Length; i++)
            {
                //Asignamos una variable por cada mercancía para facilitar la lectura
                NodoMercanciaCartaPorte MercanciaCP = CartaPorte.Mercancias.Mercancia[i];

                Console.WriteLine(MercanciaCP.BienesTransp);
                Console.WriteLine(MercanciaCP.Cantidad);
                Console.WriteLine(MercanciaCP.ClaveSTCC);
                Console.WriteLine(MercanciaCP.ClaveUnidad);
                Console.WriteLine(MercanciaCP.CveMaterialPeligroso);
                Console.WriteLine(MercanciaCP.Descripcion);
                Console.WriteLine(MercanciaCP.DescripEmbalaje);
                Console.WriteLine(MercanciaCP.Dimensiones);
                Console.WriteLine(MercanciaCP.Embalaje);
                Console.WriteLine(MercanciaCP.FraccionArancelaria);
                Console.WriteLine(MercanciaCP.MaterialPeligroso);
                Console.WriteLine(MercanciaCP.Moneda);
                Console.WriteLine(MercanciaCP.PesoEnKg);
                Console.WriteLine(MercanciaCP.Unidad);
                Console.WriteLine(MercanciaCP.UUIDComercioExt);
                Console.WriteLine(MercanciaCP.ValorMercancia);

                //Comprobamos que existan los nodos GuiasIdentificacion
                if (MercanciaCP.GuiasIdentificacion != null)
                {
                    //Obtenemos todos los datos de los nodos GuiasIdentificacion
                    for (int ii = 0; ii < MercanciaCP.GuiasIdentificacion.Length; ii++)
                    {
                        Console.WriteLine(MercanciaCP.GuiasIdentificacion[ii].DescripGuiaIdentificacion);
                        Console.WriteLine(MercanciaCP.GuiasIdentificacion[ii].NumeroGuiaIdentificacion);
                        Console.WriteLine(MercanciaCP.GuiasIdentificacion[ii].PesoGuiaIdentificacion);
                    }
                }

                //Comprobamos que exista el nodo DetalleMercancia
                if (MercanciaCP.DetalleMercancia != null)
                {
                    //Obtenemos todos los datos del nodo DetalleMercancia
                    Console.WriteLine(MercanciaCP.DetalleMercancia.NumPiezas);
                    Console.WriteLine(MercanciaCP.DetalleMercancia.PesoBruto);
                    Console.WriteLine(MercanciaCP.DetalleMercancia.PesoNeto);
                    Console.WriteLine(MercanciaCP.DetalleMercancia.PesoTara);
                    Console.WriteLine(MercanciaCP.DetalleMercancia.UnidadPesoMerc);
                }

                //Comprobamos que exista el nodo CantidadTransporta
                if (MercanciaCP.CantidadTransporta != null)
                {
                    //Obtenemos todos los nodos CantidadTransporta
                    for (int ii = 0; ii < MercanciaCP.CantidadTransporta.Length; ii++)
                    {
                        Console.WriteLine(MercanciaCP.CantidadTransporta[ii].Cantidad);
                        Console.WriteLine(MercanciaCP.CantidadTransporta[ii].IDOrigen);
                        Console.WriteLine(MercanciaCP.CantidadTransporta[ii].IDDestino);
                        Console.WriteLine(MercanciaCP.CantidadTransporta[ii].CvesTransporte);
                    }
                }

                //Comprobamos que existan Pedimentos
                if (MercanciaCP.Pedimentos != null)
                {
                    //Obtenemos todos los Pedimentos
                    for (int ii = 0; ii < MercanciaCP.Pedimentos.Length; ii++)
                    {
                        Console.WriteLine(MercanciaCP.Pedimentos[ii].Pedimento);
                    }
                }
            }

            //Comprobamos que exista el nodo Autotransporte
            if (CartaPorte.Mercancias.Autotransporte != null)
            {
                //Obtenemos todos los datos del nodo Autotransporte
                Console.WriteLine(CartaPorte.Mercancias.Autotransporte.PermSCT);
                Console.WriteLine(CartaPorte.Mercancias.Autotransporte.NumPermisoSCT);

                //Comprobamos que exista el nodo Seguros
                if (CartaPorte.Mercancias.Autotransporte.Seguros != null)
                {
                    //Obtenemos los datos del nodo Seguros
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.Seguros.AseguraCarga);
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.Seguros.PolizaCarga);
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.Seguros.AseguraMedAmbiente);
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.Seguros.PolizaMedAmbiente);
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.Seguros.AseguraRespCivil);
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.Seguros.PolizaRespCivil);
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.Seguros.PrimaSeguro);
                }

                //Comprobamos que exista el nodo IdentificacionVehicular
                if (CartaPorte.Mercancias.Autotransporte.IdentificacionVehicular != null)
                {
                    //Obtenemos todos los datos del nodo IdentificacionVehicular
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.IdentificacionVehicular.PlacaVM);
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.IdentificacionVehicular.ConfigVehicular);
                    Console.WriteLine(CartaPorte.Mercancias.Autotransporte.IdentificacionVehicular.AnioModeloVM);
                }

                //Comprobamos que exista el nodo IdentificacionVehicular
                if (CartaPorte.Mercancias.Autotransporte.Remolques != null)
                {
                    //Obtenemos todos los datos del nodo Remolques
                    for (int ii = 0; ii < CartaPorte.Mercancias.Autotransporte.Remolques.Remolque.Length; ii++)
                    {
                        Console.WriteLine(CartaPorte.Mercancias.Autotransporte.Remolques.Remolque[ii].Placa);
                        Console.WriteLine(CartaPorte.Mercancias.Autotransporte.Remolques.Remolque[ii].SubTipoRem);
                    }
                }
            }
        }

        //Comprobamos que exista el nodo FiguraTransporte
        if (CartaPorte.FiguraTransporte != null)
        {
            //Recorremos todos los nodos TiposFigura
            for (int i = 0; i < CartaPorte.FiguraTransporte.TiposFigura.Length; i++)
            {

                //Obtenemos los datos del nodo
                Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].RFCFigura);
                Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].NombreFigura);
                Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].NumLicencia);
                Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].TipoFigura);
                Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].NumRegIdTribFigura);
                Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].ResidenciaFiscalFigura);

                //Comprobamos que el nodo Domicilio exista
                if (CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio != null)
                {
                    //Obtenemos los datos del domicilio
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.Calle);
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.NumeroExterior);
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.NumeroInterior);
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.Colonia);
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.CodigoPostal);
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.Referencia);
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.Localidad);
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.Municipio);
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.Estado);
                    Console.WriteLine(CartaPorte.FiguraTransporte.TiposFigura[i].Domicilio.Pais);
                }
            }
        }
    }

    //Comprobamos que el nodo TimbreFiscalDigital exista
    if (res.Comprobante.Complemento.TimbreFiscalDigital != null)
    {
        //Obtenemos todos los datos del TimbreFiscalDigital
        Console.WriteLine(res.Comprobante.Complemento.TimbreFiscalDigital.Version);
        Console.WriteLine(res.Comprobante.Complemento.TimbreFiscalDigital.FechaTimbrado);
        Console.WriteLine(res.Comprobante.Complemento.TimbreFiscalDigital.UUID);
        Console.WriteLine(res.Comprobante.Complemento.TimbreFiscalDigital.SelloSAT);
        Console.WriteLine(res.Comprobante.Complemento.TimbreFiscalDigital.SelloCFD);
        Console.WriteLine(res.Comprobante.Complemento.TimbreFiscalDigital.Leyenda);
        Console.WriteLine(res.Comprobante.Complemento.TimbreFiscalDigital.NoCertificadoSAT);
        Console.WriteLine(res.Comprobante.Complemento.TimbreFiscalDigital.RfcProvCertif);
    }
}
'Configuración general para el uso de servicios (Obligatorio para poder el uso de las funciones)
Dim config As New ConfiguracionesReadCFDI

'Establece los parametros de la cuenta de timbre que se usará para la lectura.
config.EstablecerPIN "CFx45...Hg", "micontraseña"

'Mostramos información mas detallada en caso de recibir un error a la hora de generar la lectura.
config.MostrarDetallesEnErrores = True


'Clase para lectura de comprobantes fiscales y cancelaciones
Dim lectura As New lectura
Dim res As New ResultadosLecturaCFDI

'Función para obtener los datos del CFDI
Set res = lectura.LeerCFDI("C:\XML\CfdiTimbrado.xml")

'Obtenemos los datos del comprobante
MsgBox res.Comprobante.Version
MsgBox res.Comprobante.Fecha
MsgBox res.Comprobante.Serie
MsgBox res.Comprobante.Folio
MsgBox res.Comprobante.LugarExpedicion
MsgBox res.Comprobante.TipoDeComprobante
MsgBox res.Comprobante.MetodoPago
MsgBox res.Comprobante.FormaPago
MsgBox res.Comprobante.Moneda
MsgBox res.Comprobante.TipoCambio
MsgBox res.Comprobante.CondicionesDePago
MsgBox res.Comprobante.SubTotal
MsgBox res.Comprobante.Descuento
MsgBox res.Comprobante.Total
MsgBox res.Comprobante.Exportacion
MsgBox res.Comprobante.Certificado
MsgBox res.Comprobante.Sello
MsgBox res.Comprobante.NoCertificado
MsgBox res.Comprobante.Confirmacion

'Comprobamos que exista el nodo InformacionGlobal
If Not res.Comprobante.InformacionGlobal Is Nothing Then

    'Obtenemos los datos del nodo InformacionGlobal
    MsgBox res.Comprobante.InformacionGlobal.Periodicidad
    MsgBox res.Comprobante.InformacionGlobal.Meses
    MsgBox res.Comprobante.InformacionGlobal.Año

End If

'Comprobamos que exista el nodo CfdiRelacionados
If Not res.Comprobante.CfdiRelacionados Is Nothing Then
    
    'Asignamos el nodo a una variable para facilitar su lectura
    Dim cr As New NodoCfdiRelacionados
    Set cr = res.Comprobante.CfdiRelacionados
    
    'Obtenemos los datos del nodo CfdiRelacionados
    MsgBox cr.TipoRelacion
    For i = 0 To cr.CfdiRelacionado.Count - 1
        MsgBox cr.CfdiRelacionado.Value(i).UUID
    Next i
    
End If

'Obtenemos los datos del Emisor
MsgBox res.Comprobante.Emisor.Rfc
MsgBox res.Comprobante.Emisor.Nombre
MsgBox res.Comprobante.Emisor.RegimenFiscal
MsgBox res.Comprobante.Emisor.FacAtrAdquirente

'Obtenemos los datos del Receptor
MsgBox res.Comprobante.Receptor.Rfc
MsgBox res.Comprobante.Receptor.Nombre
MsgBox res.Comprobante.Receptor.RegimenFiscalReceptor
MsgBox res.Comprobante.Receptor.DomicilioFiscalReceptor
MsgBox res.Comprobante.Receptor.UsoCFDI
MsgBox res.Comprobante.Receptor.ResidenciaFiscal
MsgBox res.Comprobante.Receptor.NumRegIdTrib

'Obtenemos los datos del Concepto
For i = 0 To res.Comprobante.Conceptos.concepto.Count - 1
    
    'Asignamos una variable de tipo Concepto para facilitar la lectura
    Dim concepto As NodoConcepto
    Set concepto = res.Comprobante.Conceptos.concepto.Value(i)
    
    'Obtenemos los datos del concepto
    MsgBox concepto.ClaveProdServ
    MsgBox concepto.ClaveUnidad
    MsgBox concepto.Unidad
    MsgBox concepto.NoIdentificacion
    MsgBox concepto.Descripcion
    MsgBox concepto.Cantidad
    MsgBox concepto.ValorUnitario
    MsgBox concepto.Importe
    MsgBox concepto.Descuento
    MsgBox concepto.ObjetoImp
        
    'Comprobamos que existan impuestos en el concepto
    If Not concepto.impuestos Is Nothing Then
    
        'Asignamos una variable de tipo ImpuestoConcepto para facilitar la lectura
        Dim impuestos As NodoImpuestosConcepto
        Set impuestos = concepto.impuestos
        
        'Comprobamos que existan impuestos Retenciones
        If Not impuestos.retenciones Is Nothing Then
        
            For ii = 0 To impuestos.retenciones.retencion.Count - 1
                
                'Obtenemos los datos del impuesto
                MsgBox impuestos.retenciones.retencion.Value(ii).Base
                MsgBox impuestos.retenciones.retencion.Value(ii).Impuesto
                MsgBox impuestos.retenciones.retencion.Value(ii).TipoFactor
                MsgBox impuestos.retenciones.retencion.Value(ii).TasaOCuota
                MsgBox impuestos.retenciones.retencion.Value(ii).Importe
                
            Next ii
        
        End If
        
        'Comprobamos que existan impuestos Traslados
        If Not impuestos.traslados Is Nothing Then
        
            For ii = 0 To impuestos.traslados.traslado.Count - 1
                
                'Obtenemos los datos del impuesto
                MsgBox impuestos.traslados.traslado.Value(ii).Base
                MsgBox impuestos.traslados.traslado.Value(ii).Impuesto
                MsgBox impuestos.traslados.traslado.Value(ii).TipoFactor
                MsgBox impuestos.traslados.traslado.Value(ii).TasaOCuota
                MsgBox impuestos.traslados.traslado.Value(ii).Importe
                
            Next ii
        
        End If
        
    End If
    
    'Comprobamos que existan nodos de información aduanera
    If Not concepto.InformacionAduanera Is Nothing Then
    
        'Obtenemos los datos de todos los nodos de la información aduanera del concepto
        For ii = 0 To concepto.InformacionAduanera.Count - 1
            MsgBox concepto.InformacionAduanera.Value(ii).NumeroPedimento
        Next ii
        
    End If
    
    'Comprobamos que exista el nodo cuenta predial
    If Not concepto.CuentaPredial Is Nothing Then
        
        'Obtenemos el numero de la cuenta predial
        MsgBox concepto.CuentaPredial.Numero
        
    End If
    
    'Comprobamos que exista el nodo ACuentaTerceros
    If Not concepto.ACuentaTerceros Is Nothing Then
    
        'obtenemos todos sus datos
        MsgBox concepto.ACuentaTerceros.RfcACuentaTerceros
        MsgBox concepto.ACuentaTerceros.NombreACuentaTerceros
        MsgBox concepto.ACuentaTerceros.RegimenFiscalACuentaTerceros
        MsgBox concepto.ACuentaTerceros.DomicilioFiscalACuentaTerceros
        
    End If
    
    'Comprobamos que exista el nodo ComplementoConcepto
    If Not concepto.ComplementoConcepto Is Nothing Then
    
        'Revisamos los complementos existentes
        If Not concepto.ComplementoConcepto.instEducativas Is Nothing Then
                
            'Asignamos una variable para facilitar su lectura
            Dim iedu As NodoinstEducativas
            Set iedu = concepto.ComplementoConcepto.instEducativas
            
            'Obtenemos sus datos
            MsgBox iedu.Version
            MsgBox iedu.nombreAlumno
            MsgBox iedu.nivelEducativo
            MsgBox iedu.CURP
            MsgBox iedu.autRVOE
            MsgBox iedu.rfcPago
            
        End If
        
    End If
    
    'Comprobamos que existan los nodos Parte
    If Not concepto.parte Is Nothing Then
    
        For ii = 0 To concepto.parte.Count - 1
            
            'Asignamos una variable de tipo Parte para facilitar la lectura
            Dim parte As NodoParte
            Set parte = concepto.parte.Value(i)
            
            'Obtenemos los datos del nodo Parte
            MsgBox parte.ClaveProdServ
            MsgBox parte.Unidad
            MsgBox parte.NoIdentificacion
            MsgBox parte.Descripcion
            MsgBox parte.Cantidad
            MsgBox parte.ValorUnitario
            MsgBox parte.Importe
            
            'Comprobamos que el nodo Parte tenga información aduanera
            If Not parte.InformacionAduanera Is Nothing Then
                
                'Obtenemos todos los datos de los nodos de la información aduanera
                For iii = 0 To parte.InformacionAduanera.Count - 1
                    MsgBox parte.InformacionAduanera.Value(iii).NumeroPedimento
                Next iii
                
            End If
            
        Next ii
        
    End If
    
Next i


'Comprobamos que exista nodo de Impuestos en el comprobante
If Not res.Comprobante.impuestos Is Nothing Then

    'Obtenemos los totales de impuestos
    MsgBox res.Comprobante.impuestos.TotalImpuestosRetenidos
    MsgBox res.Comprobante.impuestos.TotalImpuestosTrasladados
    
    'Comprobamos que existan nodos de impuestos retenidos
    If Not res.Comprobante.impuestos.retenciones Is Nothing Then
        
        For i = 0 To res.Comprobante.impuestos.retenciones.retencion.Count - 1
                
            'Asignamos los valores a una variable de tipo Retenciones para facilitar su lectura
            Dim retencion As NodoRetencionImpuestos
            Set retencion = res.Comprobante.impuestos.retenciones.retencion.Value(i)
            
            'Obtenemos todos los datos de la retención
            MsgBox retencion.Impuesto
            MsgBox retencion.Importe
            
        Next i
        
    End If
    
    'Comprobamos que existan nodos de impuestos trasladados
    If Not res.Comprobante.impuestos.traslados Is Nothing Then
        
        For i = 0 To res.Comprobante.impuestos.traslados.traslado.Count - 1
                
            'Asignamos los valores a una variable de tipo Trasladados para facilitar su lectura
            Dim traslado As NodoTrasladoImpuestos
            Set traslado = res.Comprobante.impuestos.traslados.traslado.Value(i)
            
            'Obtenemos todos los datos del impuesto trasladado
            MsgBox traslado.Base
            MsgBox traslado.Impuesto
            MsgBox traslado.TipoFactor
            MsgBox traslado.TasaOCuota
            MsgBox traslado.Importe
            
        Next i
        
    End If
    
End If

'Comprobamos si existen el nodo Complementos
If Not res.Comprobante.Complemento Is Nothing Then

    'Comprobamos si existe el complemento Divisas
    If Not res.Comprobante.Complemento.Divisas Is Nothing Then

        'Obtenemos el tipo de operación
        MsgBox res.Comprobante.Complemento.Divisas.TipoOperacion
        
    End If
    
    'Comprobamos si existe el complemento Donatarias
    If Not res.Comprobante.Complemento.Donatarias Is Nothing Then
    
        'Obtenemos los datos de la Donataria
        MsgBox res.Comprobante.Complemento.Donatarias.Version
        MsgBox res.Comprobante.Complemento.Donatarias.noAutorizacion
        MsgBox res.Comprobante.Complemento.Donatarias.fechaAutorizacion
        MsgBox res.Comprobante.Complemento.Donatarias.leyenda
        
    End If
    
    If Not res.Comprobante.Complemento.ImpuestosLocales Is Nothing Then
    
        'Obtenemos los datos del complemento Impuestos locales
        MsgBox res.Comprobante.Complemento.ImpuestosLocales.Version
        MsgBox res.Comprobante.Complemento.ImpuestosLocales.TotaldeRetenciones
        MsgBox res.Comprobante.Complemento.ImpuestosLocales.TotaldeTraslados
        
        'Asignamos variable de los impuestos trasladados para facilitar la lectura
        Dim traslados As NodoTrasladosImpuestosLocalesCollection
        Set traslados = res.Comprobante.Complemento.ImpuestosLocales.TrasladosLocales
        
        'Comprobamos que la variable contenga información
        If Not traslados Is Nothing Then
        
            'Obtenemos la información de cada impuesto trasladado local
            For i = 0 To traslados.Count - 1
        
                MsgBox traslados.Value(i).ImpLocTrasladado
                MsgBox traslados.Value(i).TasadeTraslado
                MsgBox traslados.Value(i).Importe
                
            Next i
        
        End If
        
        
        'Asignamos variable de los impuestos retenidos para facilitar la lectura
        Dim retenciones As NodoRetencionesImpuestosLocalesCollection
        Set retenciones = res.Comprobante.Complemento.ImpuestosLocales.RetencionesLocales
        
        'Comprobamos que la variable contenga información
        If Not retenciones Is Nothing Then
        
            'Obtenemos la información de cada impuesto retenido local
            For i = 0 To retenciones.Count - 1
        
                MsgBox retenciones.Value(i).ImpLocRetenido
                MsgBox retenciones.Value(i).TasadeRetencion
                MsgBox retenciones.Value(i).Importe
                
            Next i
        
        End If
        
        
    End If
    
    'Comprobamos si existe el complemento INE
    If Not res.Comprobante.Complemento.INE Is Nothing Then
    
        'Obtenemos los datos del complemento INE
        MsgBox res.Comprobante.Complemento.INE.Version
        MsgBox res.Comprobante.Complemento.INE.TipoProceso
        MsgBox res.Comprobante.Complemento.INE.TipoComite
        MsgBox res.Comprobante.Complemento.INE.IdContabilidad
        
        'Comprobamos que el complemento tenga nodo Entidad
        If Not res.Comprobante.Complemento.INE.Entidad Is Nothing Then
        
            'Obtenemos todos los datos de los nodos Entidad
            For i = 0 To res.Comprobante.Complemento.INE.Entidad.Count - 1
            
                MsgBox res.Comprobante.Complemento.INE.Entidad.Value(i).Ambito
                MsgBox res.Comprobante.Complemento.INE.Entidad.Value(i).ClaveEntidad
                
                'Comprobamos que cada nodo entidad tenga nodos Contabilidad
                If Not res.Comprobante.Complemento.INE.Entidad.Value(i).Contabilidad Is Nothing Then
                
                    'Obtenemos los datos de los nodos Contabilidad
                    For ii = 0 To res.Comprobante.Complemento.INE.Entidad.Value(i).Contabilidad.Count - 1
                    
                        MsgBox res.Comprobante.Complemento.INE.Entidad.Value(i).Contabilidad.Value(ii).IdContabilidad
                        
                    Next ii
                    
                End If
                
            Next i
            
        End If
    
    End If
    
    'Comprobamos si existe el complemento Comercio Exterior
    If Not res.Comprobante.Complemento.ComercioExterior Is Nothing Then
    
        'Asignamos el complemento a una variable para facilitar la lectura
        Dim comext As NodoComercioExterior
        Set comext = res.Comprobante.Complemento.ComercioExterior
        
        MsgBox comext.Version
        MsgBox comext.TipoOperacion
        MsgBox comext.MotivoTraslado
        MsgBox comext.Incoterm
        MsgBox comext.Subdivision
        MsgBox comext.ClaveDePedimento
        MsgBox comext.NumCertificadoOrigen
        MsgBox comext.CertificadoOrigen
        MsgBox comext.NumeroExportadorConfiable
        MsgBox comext.Observaciones
        MsgBox comext.TipoCambioUSD
        MsgBox comext.TotalUSD
        
        'Comprobamos que exista el nodo Emisor de Comercio Exterior
        If Not comext.Emisor Is Nothing Then
            
            'Obtenemos los datos del emisor
            MsgBox comext.Emisor.CURP
            
            'Comprobamos que exista domicilio en el emisor del comercio exterior
            If Not comext.Emisor.Domicilio Is Nothing Then
            
                'Obtenemos todos los datos del domicilio
                MsgBox comext.Emisor.Domicilio.Calle
                MsgBox comext.Emisor.Domicilio.NumeroExterior
                MsgBox comext.Emisor.Domicilio.NumeroInterior
                MsgBox comext.Emisor.Domicilio.Colonia
                MsgBox comext.Emisor.Domicilio.CodigoPostal
                MsgBox comext.Emisor.Domicilio.Referencia
                MsgBox comext.Emisor.Domicilio.Localidad
                MsgBox comext.Emisor.Domicilio.Municipio
                MsgBox comext.Emisor.Domicilio.Estado
                MsgBox comext.Emisor.Domicilio.Pais
            
            End If
            
        End If
        
        'Comprobamos que exista el nodo Receptor de Comercio Exterior
        If Not comext.Receptor Is Nothing Then
            
            'Obtenemos los datos del receptor
            MsgBox comext.Receptor.NumRegIdTrib
            
            'Comprobamos que exista domicilio en el receptor del comercio exterior
            If Not comext.Receptor.Domicilio Is Nothing Then
            
                'Obtenemos todos los datos del domicilio
                MsgBox comext.Receptor.Domicilio.Calle
                MsgBox comext.Receptor.Domicilio.NumeroExterior
                MsgBox comext.Receptor.Domicilio.NumeroInterior
                MsgBox comext.Receptor.Domicilio.Colonia
                MsgBox comext.Receptor.Domicilio.CodigoPostal
                MsgBox comext.Receptor.Domicilio.Referencia
                MsgBox comext.Receptor.Domicilio.Localidad
                MsgBox comext.Receptor.Domicilio.Municipio
                MsgBox comext.Receptor.Domicilio.Estado
                MsgBox comext.Receptor.Domicilio.Pais
            
            End If
            
        End If
        
        'Comprobamos que existan nodos Propietario de Comercio Exterior
        If Not comext.Propietario Is Nothing Then
            
            'Obtenemos los datos de cada nodo Propietario
            For i = 0 To comext.Propietario.Count - 1
                
                MsgBox comext.Propietario.Value(i).NumRegIdTrib
                MsgBox comext.Propietario.Value(i).ResidenciaFiscal
            
            Next i
            
        End If
        
        'Comprobamos que existan nodos Destinatarios de Comercio Exterior
        If Not comext.destinatario Is Nothing Then
            
            'Obtenemos los datos del receptor
            For i = 0 To comext.destinatario.Count - 1
            
                'Asignamos una variable de lectura al nodo Destinatario
                Dim destinatario As NodoDestinatarioComercioExterior
                Set destinatario = comext.destinatario.Value(i)
                
                MsgBox destinatario.Nombre
                MsgBox destinatario.NumRegIdTrib
                
                'Comprobamos que exista domicilio en el destinatario del comercio exterior
                If Not destinatario.Domicilio Is Nothing Then
            
                    'Obtenemos todos nodos de domicilio
                    For ii = 0 To destinatario.Domicilio.Count - 1
                        
                        MsgBox destinatario.Domicilio.Value(ii).Calle
                        MsgBox destinatario.Domicilio.Value(ii).NumeroExterior
                        MsgBox destinatario.Domicilio.Value(ii).NumeroInterior
                        MsgBox destinatario.Domicilio.Value(ii).Colonia
                        MsgBox destinatario.Domicilio.Value(ii).CodigoPostal
                        MsgBox destinatario.Domicilio.Value(ii).Referencia
                        MsgBox destinatario.Domicilio.Value(ii).Localidad
                        MsgBox destinatario.Domicilio.Value(ii).Municipio
                        MsgBox destinatario.Domicilio.Value(ii).Estado
                        MsgBox destinatario.Domicilio.Value(ii).Pais
                    
                    Next ii
            
                End If
                
            Next i
            
        End If
        
        'Comprobamos que existan mercancias en el complemento comercio exterior
        If Not comext.Mercancias Is Nothing Then
        
            'Obtenemos todos los datos de las mercancias
            For i = 0 To comext.Mercancias.mercancia.Count - 1
            
                'Asignamos una variable por cada mercancia para facilitar la lectura
                Dim mercancia As NodoMercanciaComercioExterior
                Set mercancia = comext.Mercancias.mercancia.Value(i)
                
                MsgBox mercancia.FraccionArancelaria
                MsgBox mercancia.UnidadAduana
                MsgBox mercancia.NoIdentificacion
                MsgBox mercancia.CantidadAduana
                MsgBox mercancia.ValorUnitarioAduana
                MsgBox mercancia.ValorDolares
                
                'Comprobamos que existan descripciones específicas en la mercancia
                If Not mercancia.DescripcionesEspecificas Is Nothing Then
                                    
                    'Asignamos una variable de descripciones específicas para facilitar la lectura de cada nodo
                    Dim descripciones As NodoDescripcionesEspecificasComercioExteriorCollection
                    Set descripciones = mercancia.DescripcionesEspecificas
                    
                    For ii = 0 To descripciones.Count - 1
                    
                        'Obtenemos los datos de la descripción específica
                        MsgBox descripciones.Value(ii).Marca
                        MsgBox descripciones.Value(ii).Modelo
                        MsgBox descripciones.Value(ii).SubModelo
                        MsgBox descripciones.Value(ii).NumeroSerie
                        
                    Next ii
                    
                End If
                
            Next i
        
        End If
        
    End If
    
    'Comprobamos que exista complemento de Pagos 1.0
    If Not res.Comprobante.Complemento.Pagos10 Is Nothing Then
    
        'Obtenemos los datos del complemento Pagos 1.0
        MsgBox res.Comprobante.Complemento.Pagos10.Version
        
        For i = 0 To res.Comprobante.Complemento.Pagos10.pago.Count - 1
        
            'Asignamos una variable de tipo Pago para facilitar la lectura
            Dim pago As NodoPago10
            Set pago = res.Comprobante.Complemento.Pagos10.pago.Value(i)
            
            'Obtenemos los datos del nodo Pago
            MsgBox pago.FechaPago
            MsgBox pago.FormaDePagoP
            MsgBox pago.CadPago
            MsgBox pago.CertPago
            MsgBox pago.CtaBeneficiario
            MsgBox pago.CtaOrdenante
            MsgBox pago.MonedaP
            MsgBox pago.Monto
            MsgBox pago.NomBancoOrdExt
            MsgBox pago.NumOperacion
            MsgBox pago.RfcEmisorCtaBen
            MsgBox pago.RfcEmisorCtaOrd
            MsgBox pago.SelloPago
            MsgBox pago.TipoCadPago
            MsgBox pago.TipoCambioP
            
            'Comprobamos que el pago contenga nodos DoctoRelacionado
            If Not pago.DoctoRelacionado Is Nothing Then
            
                'Obtenemos los datos de cada DoctoRelacionado
                For ii = 0 To pago.DoctoRelacionado.Count - 1
                    
                    MsgBox pago.DoctoRelacionado.Value(ii).IdDocumento
                    MsgBox pago.DoctoRelacionado.Value(ii).Serie
                    MsgBox pago.DoctoRelacionado.Value(ii).Folio
                    MsgBox pago.DoctoRelacionado.Value(ii).MetodoDePagoDR
                    MsgBox pago.DoctoRelacionado.Value(ii).MonedaDR
                    MsgBox pago.DoctoRelacionado.Value(ii).TipoCambioDR
                    MsgBox pago.DoctoRelacionado.Value(ii).NumParcialidad
                    MsgBox pago.DoctoRelacionado.Value(ii).ImpSaldoAnt
                    MsgBox pago.DoctoRelacionado.Value(ii).ImpPagado
                    MsgBox pago.DoctoRelacionado.Value(ii).ImpSaldoInsoluto
                    
                Next ii
                
            End If
            
            'Comprobamos que el pago contenga nodo Impuestos
            If Not pago.impuestos Is Nothing Then
            
                'Comprobamos que contenga impuestos retenidos
                If Not pago.impuestos.retenciones.retencion Is Nothing Then
                    
                    'Obtenemos los datos de cada impuesto retenido
                    For ii = 0 To pago.impuestos.retenciones.retencion.Count - 1
                    
                        'Asignamos el impuesto para facilitar la lectura
                        Dim retencion10 As NodoRetencionPagos10
                        Set retencion10 = pago.impuestos.retenciones.retencion.Value(ii)
                        
                        MsgBox retencion10.Impuesto
                        MsgBox retencion10.Importe
                        
                    Next ii
                    
                End If
                
                'Comprobamos que contenga impuestos trasladados
                If Not pago.impuestos.traslados Is Nothing Then
                    
                    'Obtenemos los datos de cada impuesto trasladado
                    For ii = 0 To pago.impuestos.traslados.traslado.Count - 1
                    
                        'Asignamos el impuesto para facilitar la lectura
                        Dim traslado10 As NodoTrasladoPagos10
                        Set traslado10 = pago.impuestos.traslados.traslado.Value(ii)
                        
                        MsgBox traslado10.Impuesto
                        MsgBox traslado10.TipoFactor
                        MsgBox traslado10.TasaOCuota
                        MsgBox traslado10.Importe
                        
                    Next ii
                    
                End If
                
            End If
            
        Next i
        
    End If
    
    'Comprobamos que exista complemento de Pagos 2.0
    If Not res.Comprobante.Complemento.Pagos20 Is Nothing Then
    
        'Obtenemos los datos del complemento Pagos 2.0
        MsgBox res.Comprobante.Complemento.Pagos20.Version
        
        'Asignamos una variable al nodo Totales para facilitar la lectura
        Dim totales As NodoTotalesPagos20
        Set totales = res.Comprobante.Complemento.Pagos20.totales
        
        MsgBox totales.MontoTotalPagos
        MsgBox totales.TotalRetencionesIEPS
        MsgBox totales.TotalRetencionesISR
        MsgBox totales.TotalRetencionesIVA
        MsgBox totales.TotalTrasladosBaseExento
        MsgBox totales.TotalTrasladosBaseIVA0
        MsgBox totales.TotalTrasladosImpuestoIVA0
        MsgBox totales.TotalTrasladosBaseIVA8
        MsgBox totales.TotalTrasladosImpuestoIVA8
        MsgBox totales.TotalTrasladosBaseIVA16
        MsgBox totales.TotalTrasladosImpuestoIVA16
       
       
        'Obtenemos los datos de todos los nodos de Pago
        For i = 0 To res.Comprobante.Complemento.Pagos20.pago.Count - 1
        
            'Asignamos una variable de tipo Pago para facilitar la lectura
            Dim pago20 As NodoPago20
            Set pago20 = res.Comprobante.Complemento.Pagos20.pago.Value(i)
            
            MsgBox pago20.FechaPago
            MsgBox pago20.FormaDePagoP
            MsgBox pago20.CadPago
            MsgBox pago20.CertPago
            MsgBox pago20.CtaBeneficiario
            MsgBox pago20.CtaOrdenante
            MsgBox pago20.MonedaP
            MsgBox pago20.Monto
            MsgBox pago20.NomBancoOrdExt
            MsgBox pago20.NumOperacion
            MsgBox pago20.RfcEmisorCtaBen
            MsgBox pago20.RfcEmisorCtaOrd
            MsgBox pago20.SelloPago
            MsgBox pago20.TipoCadPago
            MsgBox pago20.TipoCambioP
            
            'Comprobamos que el pago contenga nodos DoctoRelacionado
            If Not pago20.DoctoRelacionado Is Nothing Then
            
                'Obtenemos los datos de cada DoctoRelacionado
                For ii = 0 To pago20.DoctoRelacionado.Count - 1
                    
                    MsgBox pago20.DoctoRelacionado.Value(ii).IdDocumento
                    MsgBox pago20.DoctoRelacionado.Value(ii).Serie
                    MsgBox pago20.DoctoRelacionado.Value(ii).Folio
                    MsgBox pago20.DoctoRelacionado.Value(ii).MonedaDR
                    MsgBox pago20.DoctoRelacionado.Value(ii).EquivalenciaDR
                    MsgBox pago20.DoctoRelacionado.Value(ii).NumParcialidad
                    MsgBox pago20.DoctoRelacionado.Value(ii).ImpSaldoAnt
                    MsgBox pago20.DoctoRelacionado.Value(ii).ImpPagado
                    MsgBox pago20.DoctoRelacionado.Value(ii).ImpSaldoInsoluto
                    MsgBox pago20.DoctoRelacionado.Value(ii).ObjetoImpDR
                    
                    'Comprobamos si el documento relacionado tiene impuestos
                    If Not pago20.DoctoRelacionado.Value(ii).ImpuestosDR Is Nothing Then
                    
                        'Asignamos una variable de impuestos para facilitar la lectura
                        Dim impdr As NodoImpuestosDRPagos20
                        impdr = pago20.DoctoRelacionado.Value(ii).ImpuestosDR
                        
                        'Confirmamos que existan impuestos retenidos
                        If Not impdr.RetencionesDR Is Nothing Then
                            
                            For iii = 0 To impdr.RetencionesDR.RetencionDR.Count - 1
                            
                                MsgBox impdr.RetencionesDR.RetencionDR.Value(iii).BaseDR
                                MsgBox impdr.RetencionesDR.RetencionDR.Value(iii).ImpuestoDR
                                MsgBox impdr.RetencionesDR.RetencionDR.Value(iii).TipoFactorDR
                                MsgBox impdr.RetencionesDR.RetencionDR.Value(iii).TasaOCuotaDR
                                MsgBox impdr.RetencionesDR.RetencionDR.Value(iii).ImporteDR
                                
                            Next iii
                            
                        End If
                        
                        'Confirmamos que existan impuestos trasladados
                        If Not impdr.TrasladosDR Is Nothing Then
                            
                            For iii = 0 To impdr.TrasladosDR.TrasladoDR.Count - 1
                            
                                MsgBox impdr.TrasladosDR.TrasladoDR.Value(iii).BaseDR
                                MsgBox impdr.TrasladosDR.TrasladoDR.Value(iii).ImpuestoDR
                                MsgBox impdr.TrasladosDR.TrasladoDR.Value(iii).TipoFactorDR
                                MsgBox impdr.TrasladosDR.TrasladoDR.Value(iii).TasaOCuotaDR
                                MsgBox impdr.TrasladosDR.TrasladoDR.Value(iii).ImporteDR
                                
                            Next iii
                            
                        End If
                        
                    End If
                    
                Next ii
                
            End If
            
            'Comprobamos que el pago contenga nodo Impuestos
            If Not pago20.ImpuestosP Is Nothing Then
            
                'Comprobamos que contenga impuestos retenidos
                If Not pago20.ImpuestosP.RetencionesP Is Nothing Then
                    
                    'Obtenemos los datos de cada impuesto retenido
                    For ii = 0 To pago20.ImpuestosP.RetencionesP.RetencionP.Count - 1
                    
                        'Asignamos el impuesto para facilitar la lectura
                        Dim retencion20 As NodoRetencionPPagos20
                        Set retencion20 = pago20.ImpuestosP.RetencionesP.RetencionP.Value(ii)
                        
                        MsgBox retencion20.ImpuestoP
                        MsgBox retencion20.ImporteP
                        
                    Next ii
                    
                End If
                
                'Comprobamos que contenga impuestos trasladados
                If Not pago20.ImpuestosP.TrasladosP Is Nothing Then
                    
                    'Obtenemos los datos de cada impuesto trasladado
                    For ii = 0 To pago20.ImpuestosP.TrasladosP.TrasladoP.Count - 1
                    
                        'Asignamos el impuesto para facilitar la lectura
                        Dim traslado20 As NodoTrasladoPPagos20
                        Set traslado20 = pago20.ImpuestosP.TrasladosP.TrasladoP.Value(ii)
                        
                        MsgBox traslado20.BaseP
                        MsgBox traslado20.ImpuestoP
                        MsgBox traslado20.TipoFactorP
                        MsgBox traslado20.TasaOCuotaP
                        MsgBox traslado20.ImporteP
                        
                    Next ii
                    
                End If
                
            End If
            
        Next i
        
    End If
    
    
    'Comprobamos que exista complemento Nómina
    If Not res.Comprobante.Complemento.Nomina Is Nothing Then
    
        'Asignamos una variable del nodo Nómina para facilitar la lectura
        Dim Nomina As NodoNomina
        Set Nomina = res.Comprobante.Complemento.Nomina
        
        MsgBox Nomina.Version
        MsgBox Nomina.TipoNomina
        MsgBox Nomina.FechaPago
        MsgBox Nomina.FechaInicialPago
        MsgBox Nomina.FechaFinalPago
        MsgBox Nomina.NumDiasPagados
        
        'Comprobamos que existan percepciones en el complemento
        If Not Nomina.Percepciones Is Nothing Then
        
            'Obtenemos los datos de las percepciones
            MsgBox Nomina.Percepciones.TotalSueldos
            MsgBox Nomina.Percepciones.TotalSeparacionIndemnizacion
            MsgBox Nomina.Percepciones.TotalJubilacionPensionRetiro
            MsgBox Nomina.Percepciones.TotalExento
            MsgBox Nomina.Percepciones.TotalGravado
            
            'Comprobamos que exista nodo JubilacionPensionRetiro
            If Not Nomina.Percepciones.JubilacionPensionRetiro Is Nothing Then
                
                'Obtenemos los datos del nodo JubilacionPensionRetiro
                MsgBox Nomina.Percepciones.JubilacionPensionRetiro.TotalUnaExhibicion
                MsgBox Nomina.Percepciones.JubilacionPensionRetiro.TotalParcialidad
                MsgBox Nomina.Percepciones.JubilacionPensionRetiro.MontoDiario
                MsgBox Nomina.Percepciones.JubilacionPensionRetiro.IngresoAcumulable
                MsgBox Nomina.Percepciones.JubilacionPensionRetiro.IngresoNoAcumulable
                
            End If
            
            'Comprobamos que exista nodo SeparacionIndemnizacion
            If Not Nomina.Percepciones.SeparacionIndemnizacion Is Nothing Then
                
                'Obtenemos los datos del nodo JubilacionPensionRetiro
                MsgBox Nomina.Percepciones.SeparacionIndemnizacion.UltimoSueldoMensOrd
                MsgBox Nomina.Percepciones.SeparacionIndemnizacion.TotalPagado
                MsgBox Nomina.Percepciones.SeparacionIndemnizacion.NumAñosServicio
                MsgBox Nomina.Percepciones.SeparacionIndemnizacion.IngresoAcumulable
                MsgBox Nomina.Percepciones.SeparacionIndemnizacion.IngresoNoAcumulable
                
            End If
            
            'Obtenemos todos los nodos de percepción
            For i = 0 To Nomina.Percepciones.Percepcion.Count - 1
                
                MsgBox Nomina.Percepciones.Percepcion.Value(i).TipoPercepcion
                MsgBox Nomina.Percepciones.Percepcion.Value(i).Clave
                MsgBox Nomina.Percepciones.Percepcion.Value(i).concepto
                MsgBox Nomina.Percepciones.Percepcion.Value(i).ImporteExento
                MsgBox Nomina.Percepciones.Percepcion.Value(i).ImporteGravado
                
                'Comprobamos que existan horas extras en la percepción
                If Not Nomina.Percepciones.Percepcion.Value(i).HorasExtra Is Nothing Then
                    
                    'Obtenemos los datos de las horas extra
                    For ii = 0 To Nomina.Percepciones.Percepcion.Value(i).HorasExtra.Count - 1
                        
                        MsgBox Nomina.Percepciones.Percepcion.Value(i).HorasExtra.Value(ii).Dias
                        MsgBox Nomina.Percepciones.Percepcion.Value(i).HorasExtra.Value(ii).HorasExtra
                        MsgBox Nomina.Percepciones.Percepcion.Value(i).HorasExtra.Value(ii).ImportePagado
                        MsgBox Nomina.Percepciones.Percepcion.Value(i).HorasExtra.Value(ii).TipoHoras
                        
                    Next ii
                    
                End If
                
                'Comprobamos que exista nodo AccionesOTitulos
                If Not Nomina.Percepciones.Percepcion.Value(i).AccionesOTitulos Is Nothing Then
                
                    'Obtenemos todos los datos del nodo AccionesOTitulos
                    MsgBox Nomina.Percepciones.Percepcion.Value(i).AccionesOTitulos.PrecioAlOtorgarse
                    MsgBox Nomina.Percepciones.Percepcion.Value(i).AccionesOTitulos.ValorMercado
                    
                End If
                
            Next i
            
        End If
        
        'Comprobamos que existan deducciones en el complemento
        If Not Nomina.Deducciones Is Nothing Then
            
            'Obtenemos los datos de las deducciones
            MsgBox Nomina.Deducciones.TotalImpuestosRetenidos
            MsgBox Nomina.Deducciones.TotalOtrasDeducciones
            
            'Obtenemos todos los nodos de deducción
            For i = 0 To Nomina.Deducciones.Deduccion.Count - 1
            
                MsgBox Nomina.Deducciones.Deduccion.Value(i).TipoDeduccion
                MsgBox Nomina.Deducciones.Deduccion.Value(i).Clave
                MsgBox Nomina.Deducciones.Deduccion.Value(i).concepto
                MsgBox Nomina.Deducciones.Deduccion.Value(i).Importe
                
            Next i
            
        End If
        
        'Comprobamos que existan otros pagos en el complemento
        If Not Nomina.OtrosPagos Is Nothing Then
            
            'Obtenemos todos los nodos de otros pagos
            For i = 0 To Nomina.OtrosPagos.OtroPago.Count - 1
            
                MsgBox Nomina.OtrosPagos.OtroPago.Value(i).TipoOtroPago
                MsgBox Nomina.OtrosPagos.OtroPago.Value(i).Clave
                MsgBox Nomina.OtrosPagos.OtroPago.Value(i).concepto
                MsgBox Nomina.OtrosPagos.OtroPago.Value(i).Importe
                
                'Comprobamos que exista nodo SubsidioAlEmpleo
                If Not Nomina.OtrosPagos.OtroPago.Value(i).SubsidioAlEmpleo Is Nothing Then
                                    
                    'Obtenemos todos los datos del nodo SubsidioAlEmpleo
                    MsgBox Nomina.OtrosPagos.OtroPago.Value(i).SubsidioAlEmpleo.SubsidioCausado
                    
                End If
                
                'Comprobamos que exista el nodo CompensacionSaldosAFavor
                If Not Nomina.OtrosPagos.OtroPago.Value(i).CompensacionSaldosAFavor Is Nothing Then
                
                    'Obtenemos todos los datos del nodo CompensacionSaldosAFavor
                    MsgBox Nomina.OtrosPagos.OtroPago.Value(i).CompensacionSaldosAFavor.Año
                    MsgBox Nomina.OtrosPagos.OtroPago.Value(i).CompensacionSaldosAFavor.RemanenteSalFav
                    MsgBox Nomina.OtrosPagos.OtroPago.Value(i).CompensacionSaldosAFavor.SaldoAFavor
                    
                End If
                
            Next i
            
        End If
        
        'Comprobamos que existan incapacidades en el complemento
        If Not Nomina.Incapacidades Is Nothing Then
        
            'Obtenemos todos los nodos de incapacidad
            For i = 0 To Nomina.Incapacidades.Incapacidad.Count - 1
            
                MsgBox Nomina.Incapacidades.Incapacidad.Value(i).TipoIncapacidad
                MsgBox Nomina.Incapacidades.Incapacidad.Value(i).DiasIncapacidad
                MsgBox Nomina.Incapacidades.Incapacidad.Value(i).ImporteMonetario
                
            Next i
            
        End If
        
    End If
    
    'Comprobamos que exista complemento Carta porte 2.0
    If Not res.Comprobante.Complemento.CartaPorte Is Nothing Then
    
        'Asignamos una variable al complemento para facilitar la lectura
        Dim CartaPorte As NodoCartaPorte
        Set CartaPorte = res.Comprobante.Complemento.CartaPorte
        
        'Obtenemos los datos del nodo CartaPorte
        MsgBox CartaPorte.Version
        MsgBox CartaPorte.EntradaSalidaMerc
        MsgBox CartaPorte.PaisOrigenDestino
        MsgBox CartaPorte.TotalDistRec
        MsgBox CartaPorte.TranspInternac
        MsgBox CartaPorte.ViaEntradaSalida
        
        'Comprobamos que exista nodo Ubicaciones
        If Not CartaPorte.Ubicaciones Is Nothing Then
            
            'Obtenemos los datos de cada nodo Ubicaciones
            For i = 0 To CartaPorte.Ubicaciones.Ubicacion.Count - 1
            
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).RFCRemitenteDestinatario
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).NombreRemitenteDestinatario
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).NumRegIdTrib
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).ResidenciaFiscal
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).TipoUbicacion
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).IDUbicacion
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).FechaHoraSalidaLlegada
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).TipoEstacion
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).DistanciaRecorrida
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).NavegacionTrafico
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).NumEstacion
                MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).NombreEstacion
                
                'Comprobamos que exista el nodo Domicilio
                If Not CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio Is Nothing Then
                
                    'Obtenemos todos los datos del nodo Domicilio
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.Calle
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.NumeroExterior
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.NumeroInterior
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.Colonia
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.CodigoPostal
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.Referencia
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.Localidad
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.Municipio
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.Estado
                    MsgBox CartaPorte.Ubicaciones.Ubicacion.Value(i).Domicilio.Pais
                    
                End If
                
            Next i
            
        End If
        
        'Comprobamos que exista nodo Mercancias
        If Not CartaPorte.Mercancias Is Nothing Then
        
            'Obtenemos todos los datos del nodo Mercancias
            MsgBox CartaPorte.Mercancias.CargoPorTasacion
            MsgBox CartaPorte.Mercancias.NumTotalMercancias
            MsgBox CartaPorte.Mercancias.PesoBrutoTotal
            MsgBox CartaPorte.Mercancias.PesoNetoTotal
            MsgBox CartaPorte.Mercancias.UnidadPeso
            
            'Obtenemos todos los nodos de Mercancia
            For i = 0 To CartaPorte.Mercancias.mercancia.Count - 1
                
                'Asignamos una variable por cada mercancía para facilitar la lectura
                Dim MercanciaCP As New NodoMercanciaCartaPorte
                Set MercanciaCP = CartaPorte.Mercancias.mercancia.Value(i)
                
                MsgBox MercanciaCP.BienesTransp
                MsgBox MercanciaCP.Cantidad
                MsgBox MercanciaCP.ClaveSTCC
                MsgBox MercanciaCP.ClaveUnidad
                MsgBox MercanciaCP.CveMaterialPeligroso
                MsgBox MercanciaCP.Descripcion
                MsgBox MercanciaCP.DescripEmbalaje
                MsgBox MercanciaCP.Dimensiones
                MsgBox MercanciaCP.Embalaje
                MsgBox MercanciaCP.FraccionArancelaria
                MsgBox MercanciaCP.MaterialPeligroso
                MsgBox MercanciaCP.Moneda
                MsgBox MercanciaCP.PesoEnKg
                MsgBox MercanciaCP.Unidad
                MsgBox MercanciaCP.UUIDComercioExt
                MsgBox MercanciaCP.ValorMercancia
                
                'Comprobamos que existan los nodos GuiasIdentificacion
                If Not MercanciaCP.GuiasIdentificacion Is Nothing Then
                
                    'Obtenemos todos los datos de los nodos GuiasIdentificacion
                    For ii = 0 To MercanciaCP.GuiasIdentificacion.Count - 1
                    
                        MsgBox MercanciaCP.GuiasIdentificacion.Value(ii).DescripGuiaIdentificacion
                        MsgBox MercanciaCP.GuiasIdentificacion.Value(ii).NumeroGuiaIdentificacion
                        MsgBox MercanciaCP.GuiasIdentificacion.Value(ii).PesoGuiaIdentificacion
                        
                    Next ii
                    
                End If
                
                'Comprobamos que exista el nodo DetalleMercancia
                If Not MercanciaCP.DetalleMercancia Is Nothing Then
                
                    'Obtenemos todos los datos del nodo DetalleMercancia
                    MsgBox MercanciaCP.DetalleMercancia.NumPiezas
                    MsgBox MercanciaCP.DetalleMercancia.PesoBruto
                    MsgBox MercanciaCP.DetalleMercancia.PesoNeto
                    MsgBox MercanciaCP.DetalleMercancia.PesoTara
                    MsgBox MercanciaCP.DetalleMercancia.UnidadPesoMerc
                    
                End If
                
                'Comprobamos que exista el nodo CantidadTransporta
                If Not MercanciaCP.CantidadTransporta Is Nothing Then
                
                    'Obtenemos todos los nodos CantidadTransporta
                    For ii = 0 To MercanciaCP.CantidadTransporta.Count - 1
                    
                        MsgBox MercanciaCP.CantidadTransporta.Value(ii).Cantidad
                        MsgBox MercanciaCP.CantidadTransporta.Value(ii).IDOrigen
                        MsgBox MercanciaCP.CantidadTransporta.Value(ii).IDDestino
                        MsgBox MercanciaCP.CantidadTransporta.Value(ii).CvesTransporte
                        
                    Next ii
                    
                End If
                
                'Comprobamos que existan Pedimentos
                If Not MercanciaCP.Pedimentos Is Nothing Then
                    
                    'Obtenemos todos los Pedimentos
                    For ii = 0 To MercanciaCP.Pedimentos.Count - 1
                    
                        MsgBox MercanciaCP.Pedimentos.Value(ii).Pedimento
                        
                    Next ii
                    
                End If
                
            Next i
            
            'Comprobamos que exista el nodo Autotransporte
            If Not CartaPorte.Mercancias.Autotransporte Is Nothing Then
            
                'Obtenemos todos los datos del nodo Autotransporte
                MsgBox CartaPorte.Mercancias.Autotransporte.PermSCT
                MsgBox CartaPorte.Mercancias.Autotransporte.NumPermisoSCT
                
                'Comprobamos que exista el nodo Seguros
                If Not CartaPorte.Mercancias.Autotransporte.Seguros Is Nothing Then
                    
                    'Obtenemos los datos del nodo Seguros
                    MsgBox CartaPorte.Mercancias.Autotransporte.Seguros.AseguraCarga
                    MsgBox CartaPorte.Mercancias.Autotransporte.Seguros.PolizaCarga
                    MsgBox CartaPorte.Mercancias.Autotransporte.Seguros.AseguraMedAmbiente
                    MsgBox CartaPorte.Mercancias.Autotransporte.Seguros.PolizaMedAmbiente
                    MsgBox CartaPorte.Mercancias.Autotransporte.Seguros.AseguraRespCivil
                    MsgBox CartaPorte.Mercancias.Autotransporte.Seguros.PolizaRespCivil
                    MsgBox CartaPorte.Mercancias.Autotransporte.Seguros.PrimaSeguro
                    
                End If
                
                'Comprobamos que exista el nodo IdentificacionVehicular
                If Not CartaPorte.Mercancias.Autotransporte.IdentificacionVehicular Is Nothing Then
                
                    'Obtenemos todos los datos del nodo IdentificacionVehicular
                    MsgBox CartaPorte.Mercancias.Autotransporte.IdentificacionVehicular.PlacaVM
                    MsgBox CartaPorte.Mercancias.Autotransporte.IdentificacionVehicular.ConfigVehicular
                    MsgBox CartaPorte.Mercancias.Autotransporte.IdentificacionVehicular.AnioModeloVM
                    
                End If
                
                'Comprobamos que exista el nodo IdentificacionVehicular
                If Not CartaPorte.Mercancias.Autotransporte.Remolques Is Nothing Then
                
                    'Obtenemos todos los datos del nodo Remolques
                    For ii = 0 To CartaPorte.Mercancias.Autotransporte.Remolques.Remolque.Count - 1
                    
                        MsgBox CartaPorte.Mercancias.Autotransporte.Remolques.Remolque.Value(ii).Placa
                        MsgBox CartaPorte.Mercancias.Autotransporte.Remolques.Remolque.Value(ii).SubTipoRem
                        
                    Next ii
                    
                End If
                
            End If
            
        End If
        
        
        'Comprobamos que exista el nodo FiguraTransporte
        If Not CartaPorte.FiguraTransporte Is Nothing Then
        
            'Recorremos todos los nodos TiposFigura
            For i = 0 To CartaPorte.FiguraTransporte.TiposFigura.Count - 1
            
                'Obtenemos los datos del nodo
                MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).RFCFigura
                MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).NombreFigura
                MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).NumLicencia
                MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).TipoFigura
                MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).NumRegIdTribFigura
                MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).ResidenciaFiscalFigura
                
                'Comprobamos que el nodo Domicilio exista
                If Not CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio Is Nothing Then
                
                    'Obtenemos los datos del domicilio
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.Calle
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.NumeroExterior
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.NumeroInterior
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.Colonia
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.CodigoPostal
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.Referencia
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.Localidad
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.Municipio
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.Estado
                    MsgBox CartaPorte.FiguraTransporte.TiposFigura.Value(i).Domicilio.Pais
                    
                End If
                
            Next i
            
        End If
        
        
    End If
    
    
    'Comprobamos que el nodo TimbreFiscalDigital exista
    If Not res.Comprobante.Complemento.TimbreFiscalDigital Is Nothing Then
    
        'Obtenemos todos los datos del TimbreFiscalDigital
        MsgBox res.Comprobante.Complemento.TimbreFiscalDigital.Version
        MsgBox res.Comprobante.Complemento.TimbreFiscalDigital.FechaTimbrado
        MsgBox res.Comprobante.Complemento.TimbreFiscalDigital.UUID
        MsgBox res.Comprobante.Complemento.TimbreFiscalDigital.SelloSAT
        MsgBox res.Comprobante.Complemento.TimbreFiscalDigital.SelloCFD
        MsgBox res.Comprobante.Complemento.TimbreFiscalDigital.leyenda
        MsgBox res.Comprobante.Complemento.TimbreFiscalDigital.NoCertificadoSAT
        MsgBox res.Comprobante.Complemento.TimbreFiscalDigital.RfcProvCertif
        
    End If
    
   
End If

                                        

using tagcode.ReadCFDI;
using static tagcode.ReadCFDI.ResultadosLecturaCancelacion.NodoAcuse;


//Configuración general para el uso de servicios (Obligatorio para poder el uso de las funciones)
ConfiguracionesReadCFDI config = new ConfiguracionesReadCFDI();

//Establece los parametros de la cuenta de timbre que se usará para la lectura.
config.EstablecerPIN("CFx45...Hg", "micontraseña");

//Mostramos información mas detallada en caso de recibir un error a la hora de generar la lectura.
config.MostrarDetallesEnErrores = true;


//Clase para lectura de comprobantes fiscales y cancelaciones
Lectura lectura = new Lectura();

//Función para obtener los datos del Acuse de cancelación
ResultadosLecturaCancelacion res = lectura.LeerAcuseCancelacion("C:\\Cancelaciones\\AcuseCancelacion.xml");

//Obtenemos los datos del Acuse de cancelación
Console.WriteLine(res.Acuse.Fecha);
Console.WriteLine(res.Acuse.RfcEmisor);
Console.WriteLine(res.Acuse.Sello);

//Comprobamos que existan los nodos Folios
if (res.Acuse.Folios != null)
{
    //Recorremos todos los nodos Folios
    foreach (NodoFolios folio in res.Acuse.Folios)
    {
        //Obtenemos los datos de cada nodo Folios
        Console.WriteLine(folio.UUID);
        Console.WriteLine(folio.EstatusUUID);
    }
}
'Configuración general para el uso de servicios (Obligatorio para poder el uso de las funciones)
Dim config As New ConfiguracionesReadCFDI

'Establece los parametros de la cuenta de timbre que se usará para la lectura.
config.EstablecerPIN "CFx45...Hg", "micontraseña"

'Mostramos información mas detallada en caso de recibir un error a la hora de generar la lectura.
config.MostrarDetallesEnErrores = True


'Clase para lectura de comprobantes fiscales y cancelaciones
Dim lectura As New lectura
Dim res As New ResultadosLecturaCancelacion

'Función para obtener los datos del Acuse de cancelación
Set res = lectura.LeerAcuseCancelacion("C:\Cancelaciones\AcuseCancelacion.xml")

'Obtenemos los datos del Acuse de cancelación
MsgBox res.Acuse.Fecha
MsgBox res.Acuse.RfcEmisor
MsgBox res.Acuse.Sello

'Comprobamos que existan los nodos Folios
If Not res.Acuse.Folios Is Nothing Then

    'Recorremos todos los nodos Folios
    For i = 0 To res.Acuse.Folios.Count - 1
        
        'Obtenemos los datos de cada nodo
        MsgBox res.Acuse.Folios.Value(i).UUID
        MsgBox res.Acuse.Folios.Value(i).EstatusUUID
        
    Next i
    
End If

                                        

//Configuración general para el uso de servicios (Obligatorio para poder el uso de las funciones)
using tagcode.ReadCFDI;


ConfiguracionesReadCFDI config = new ConfiguracionesReadCFDI();

//Establece los parametros de la cuenta de timbre que se usará para la lectura.
config.EstablecerPIN("CFx45...Hg", "micontraseña");

//Mostramos información mas detallada en caso de recibir un error a la hora de generar la lectura.
config.MostrarDetallesEnErrores = true;


//Clase para lectura de catálogos del SAT
CatalogosSAT catalogos = new CatalogosSAT();

//Mostramos algunas de las funciones disponibles en la clase CatalogosSAT

//Catálogo ClaveUnidad a partir de un código (Conceptos)
ResultadosCatalogos resUnico = catalogos.ObtenerClaveUnidadPorClave("E48");
Console.WriteLine(resUnico.Codigo + " - " + resUnico.Descripcion);

//Catálogo ClaveProdServ a partir de una descripción (Conceptos)
ResultadosCatalogos[] resArreglo = catalogos.ObtenerClaveProdServPorDescripcion("leche");
foreach (ResultadosCatalogos r in resArreglo)
{
    Console.WriteLine(r.Codigo + " - " + r.Descripcion);
}

//Catálogo Estado a partir de una clave (Varios)
resUnico = catalogos.ObtenerEstadoPorClave("MEX");
Console.WriteLine(resUnico.Codigo + " - " + resUnico.Descripcion);

//Catálogo bancos a partir del nombre (Nómina)
resArreglo = catalogos.ObtenerBancoPorNombre("bbva");
foreach (ResultadosCatalogos r in resArreglo)
{
    Console.WriteLine(r.Codigo + " - " + r.Descripcion);
}

//Catálogo de moneda a partir de un código (Varios)
ResultadosCatalogosDecimales resDecimales = catalogos.ObtenerMonedaPorClave("MXN");
Console.WriteLine(resDecimales.Codigo + " - " + resDecimales.Descripcion);
Console.WriteLine(resDecimales.CantidadDecimales);


//Catálogo de colonia a partir de clave y código postal (Varios)
ResultadosCatalogosCodigoPostal resCodigoPostal = catalogos.ObtenerColoniaPorClave("0347", "25350");
Console.WriteLine(resCodigoPostal.Codigo + " - " + resCodigoPostal.Descripcion);
Console.WriteLine(resCodigoPostal.CodigoPostal);

//Catálogo de colonia a partir de nombre (Varios)
ResultadosCatalogosCodigoPostal[] resCodigoPostalArreglo = catalogos.ObtenerColoniaPorNombre("centro", "25350");
foreach (ResultadosCatalogosCodigoPostal r in resCodigoPostalArreglo)
{
    Console.WriteLine(r.Codigo + " - " + r.Descripcion);
    Console.Write(r.CodigoPostal);
}

//Catálogo de régimen fiscal a partir de tipo de persona fiscal
ResultadosCatalogosPersonaFiscal[] resPersonaArreglo = catalogos.ObtenerRegimenFiscalPorTipoPersona(opTipoPersonaFiscalReadCFDI.PersonaFisica);
foreach (ResultadosCatalogosPersonaFiscal r in resPersonaArreglo)
{
    Console.WriteLine(r.Codigo + " - " + r.Descripcion);
    if (r.PersonaFisica) Console.WriteLine("Física");
    if (r.PersonaMoral) Console.WriteLine("Moral");
}

//Muchos más catalogos dentro de la clase CatalogosSAT

//ResultadosCatalogos res = catalogos.Obtener...(...);
//Console.WriteLine(res.Codigo);
//Console.WriteLine(res.Descripcion);
'Configuración general para el uso de servicios (Obligatorio para poder el uso de las funciones)
Dim config As New ConfiguracionesReadCFDI

'Establece los parametros de la cuenta de timbre que se usará para la lectura.
config.EstablecerPIN "CFx45...Hg", "micontraseña"

'Mostramos información mas detallada en caso de recibir un error a la hora de generar la lectura.
config.MostrarDetallesEnErrores = True


'Clase para lectura de catálogos del SAT
Dim catalogos As New CatalogosSAT

'Mostramos algunas de las funciones disponibles en la clase CatalogosSAT

'Catálogo ClaveUnidad a partir de un código (Conceptos)
Dim resUnico As ResultadosCatalogos
Set resUnico = catalogos.ObtenerClaveUnidadPorClave("E48")
MsgBox resUnico.Codigo & " - " & resUnico.Descripcion

'Catálogo ClaveProdServ a partir de una descripción (Conceptos)
Dim resArreglo As ResultadosCatalogosCollection
Set resArreglo = catalogos.ObtenerClaveProdServPorDescripcion("leche")
For i = 0 To resArreglo.Count - 1
    MsgBox resArreglo.Value(i).Codigo & " - " & resArreglo.Value(i).Descripcion
Next i

'Catálogo Estado a partir de una clave (Varios)
Set resUnico = catalogos.ObtenerEstadoPorClave("MEX")
MsgBox resUnico.Codigo & " - " & resUnico.Descripcion

'Catálogo bancos a partir del nombre (Nómina)
Set resArreglo = catalogos.ObtenerBancoPorNombre("bbva")
For i = 0 To resArreglo.Count - 1
    MsgBox resArreglo.Value(i).Codigo & " - " & resArreglo.Value(i).Descripcion
Next i

'Catálogo de moneda a partir de un código (Varios)
Dim resDecimales As ResultadosCatalogosDecimales
Set resDecimales = catalogos.ObtenerMonedaPorClave("MXN")
MsgBox resDecimales.Codigo & " - " & resDecimales.Descripcion
MsgBox resDecimales.CantidadDecimales

'Catálogo de colonia a partir de clave y código postal (Varios)
Dim resCodigoPostal As ResultadosCatalogosCodigoPostal
Set resCodigoPostal = catalogos.ObtenerColoniaPorClave("0347", "25350")
MsgBox resCodigoPostal.Codigo & " - " & resCodigoPostal.Descripcion
MsgBox resCodigoPostal.CodigoPostal

'Catálogo de colonia a partir de nombre (Varios)
Dim resCodigoPostalArreglo As ResultadosCatalogosCodigoPostalCollection
Set resCodigoPostalArreglo = catalogos.ObtenerColoniaPorNombre("centro", "25350")
For i = 0 To resCodigoPostalArreglo.Count - 1
    MsgBox resCodigoPostalArreglo.Value(i).Codigo & " - " & resCodigoPostalArreglo.Value(i).Descripcion
    MsgBox resCodigoPostalArreglo.Value(i).CodigoPostal
Next i

'Catálogo de régimen fiscal a partir de tipo de persona fiscal
Dim resPersonaArreglo As ResultadosCatalogosPersonaFiscalCollection
Set resPersonaArreglo = catalogos.ObtenerRegimenFiscalPorTipoPersona(opTipoPersonaFiscalReadCFDI_PersonaFisica)
For i = 0 To resPersonaArreglo.Count - 1
    MsgBox resPersonaArreglo.Value(i).Codigo & " - " & resPersonaArreglo.Value(i).Descripcion
    If resPersonaArreglo.Value(i).PersonaFisica Then MsgBox "Física"
    If resPersonaArreglo.Value(i).PersonaMoral Then MsgBox "Moral"
Next i

'Muchos más catalogos dentro de la clase CatalogosSAT

'Dim res As ResultadosCatalogos
'Set res = catalogos.Obtener...(...)
'MsgBox res.Codigo
'MsgBox res.Descripcion

El manejo de errores de esta biblioteca, te permitirá mostrar el mensaje de error específico de la información que no obtuvo el resultado esperado.
try
{
    //Configuración general para el uso de servicios (Obligatorio para el uso de funciones avanzadas)
    ConfiguracionesReadCFDI config = new ConfiguracionesReadCFDI("CFx45...Hg", "micontraseña");

    //...
    //...
    //...
    //...

}
catch (Exception ex)
{
    //Aquí controlamos nuestro código en caso de un error en el procedimiento de lectura
    Console.WriteLine(ex.Message);
}
On Error GoTo Errores

'Configuración general para el uso de servicios (Obligatorio para el uso de funciones avanzadas)
Dim config As New ConfiguracionesReadCFDI

'...
'...
'...
'...
Exit Sub

Errores:
'Aquí controlamos nuestro código en caso de un error en el procedimiento de lectura
MsgBox Err.Description