using System.Data; using System.Data.OleDb; using System.Text; using System.Xml.Linq; using static System.Net.Mime.MediaTypeNames; class Program { static readonly DataTable dados = new(); static void ObterDadosAccess(string connectionString, string query) { using OleDbConnection connection = new(connectionString); OleDbCommand command = new(query, connection); connection.Open(); var reader = command.ExecuteReader(); dados.Load(reader); //reader.Close(); //command.Dispose(); //connection.Close(); } static async Task Main() { string pasta = @"X:\Back\Controle NFs\NFs"; var arquivosXML = Directory.GetFiles(pasta, "*.xml"); var arquivosPDF = Directory.GetFiles(pasta, "*.pdf"); var arquivos = arquivosXML.Concat(arquivosPDF); var tarefas = new List>(); // Obter dados do banco de dados Access string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=X:/Middle/Informativo Setorial/Modelo Word/BD1_dados cadastrais e faturas.accdb;Jet OLEDB:Database Password=gds21"; string query = "SELECT * FROM Dados_TE LEFT JOIN Dados_Cadastrais ON Dados_TE.Cod_smart_unidade = Dados_Cadastrais.Cod_smart_unidade"; ObterDadosAccess(connectionString, query); // Processar arquivosXML em paralelo foreach (string arquivo in arquivos) { tarefas.Add(ProcessarXMLAsync(arquivo)); } var linhas = await Task.WhenAll(tarefas); // Gerar CSV StringBuilder csv = new(); foreach (string linha in linhas) { csv.AppendLine(linha); } //StringBuilder csv = new(); //foreach (string arquivo in arquivos) //{ // csv.AppendLine(await ProcessarXMLAsync(arquivo)); //} // Escrever CSV no StdOut (VBA vai capturar) //Console.OutputEncoding = Encoding.UTF8; Console.Write(csv.ToString()); //dados.Dispose(); } static string ProcessarArquivo(string caminhoArquivo) { string nomeArquivo = Path.GetFileName(caminhoArquivo); string tipoArquivo = Path.GetExtension(caminhoArquivo).TrimStart('.'); string referencia = nomeArquivo.Split(" - ").FirstOrDefault() ?? ""; // Formatar como CSV (com proteção contra vírgulas) return $"\"{caminhoArquivo}\";\"{nomeArquivo}\";\"{tipoArquivo}\";\"{referencia}\""; } static async Task ProcessarXMLAsync(string caminhoArquivo) { string? CNPJ_Comprador = ""; string? CNPJ_Vendedor = ""; float? Montante_operação = null; float? Valor_unitário = null; float? Valor_final_c_impostos = null; string? RS_Comprador = ""; string? RS_Vendedor = ""; int? Numero_NF = null; float? ICMS_NF = null; string? UF_NF = ""; string? UF_Vend = ""; string? Cod_TE = ""; if (Path.GetExtension(caminhoArquivo).Equals(".xml", StringComparison.CurrentCultureIgnoreCase)) { if (caminhoArquivo == "X:\\Back\\Controle NFs\\NFs\\581556552,910625 - NFE31250317155730000164550010000669361412505682.XML") { ICMS_NF = 0; } XDocument xml = XDocument.Load(caminhoArquivo); XNamespace ns = "http://www.portalfiscal.inf.br/nfe"; // Namespace do XML CNPJ_Comprador = xml.Descendants(ns + "dest").Elements(ns + "CNPJ").FirstOrDefault()?.Value ?? xml.Descendants(ns + "dest").Elements(ns + "CPF").FirstOrDefault()?.Value; CNPJ_Comprador = Convert.ToInt64(CNPJ_Comprador).ToString(@"00000000000000"); CNPJ_Vendedor = xml.Descendants(ns + "emit").Elements(ns + "CNPJ").FirstOrDefault()?.Value; CNPJ_Vendedor = Convert.ToInt64(CNPJ_Vendedor).ToString(@"00000000000000"); RS_Comprador = xml.Descendants(ns + "dest").Elements(ns + "xNome").FirstOrDefault()?.Value; RS_Vendedor = xml.Descendants(ns + "emit").Elements(ns + "xNome").FirstOrDefault()?.Value; float soma1 = xml.Descendants(ns + "prod").Sum(prod => (float?)prod.Element(ns + "qCom") ?? 0); float soma2 = xml.Descendants(ns + "prod").Sum(prod => ((float?)prod.Element(ns + "qCom") ?? 0) * ((float?)prod.Element(ns + "vUnCom") ?? 0)); if (CNPJ_Vendedor == "06981176000158" || CNPJ_Vendedor == "06981176002100" || CNPJ_Vendedor == "17155730000164") { soma1 /= 1000; } Montante_operação = soma1; if (soma1 != 0) { Valor_unitário = soma2 / soma1; } else { Valor_unitário = 0; } Valor_final_c_impostos = float.TryParse(xml.Descendants(ns + "pag").Elements(ns + "detPag").Elements(ns + "vPag").FirstOrDefault()?.Value.Replace(".",","), out float valor) ? valor : 0; if (Valor_final_c_impostos == 0) { Valor_final_c_impostos = float.TryParse(xml.Descendants(ns + "cobr").Elements(ns + "fat").Elements(ns + "vLiq").FirstOrDefault()?.Value.Replace(".", ","), out float valor2) ? valor2 : 0; } Numero_NF = int.Parse(xml.Descendants(ns + "ide").Elements(ns + "nNF").FirstOrDefault()?.Value ?? "0"); ICMS_NF = (float.TryParse(xml.Descendants(ns + "imposto").Elements(ns + "ICMS").Elements(ns + "ICMS00").Elements(ns + "pICMS").FirstOrDefault()?.Value.Replace(".", ","), out float valor1) ? valor1 : 0)/100; if (ICMS_NF == 0 && Valor_final_c_impostos != 0) { ICMS_NF = 1 - (soma2 / Valor_final_c_impostos); } UF_NF = xml.Descendants(ns + "dest").Elements(ns + "enderDest").Elements(ns + "UF").FirstOrDefault()?.Value; UF_Vend = xml.Descendants(ns + "emit").Elements(ns + "enderEmit").Elements(ns + "UF").FirstOrDefault()?.Value; if (UF_NF == "SP" && UF_Vend == "SP") { Valor_unitário *= (1 - ICMS_NF); } Cod_TE = Id_operacao(CNPJ_Comprador, CNPJ_Vendedor, Montante_operação ?? 0, Valor_unitário ?? 0, Valor_final_c_impostos ?? 0); } return await Task.Run(() => { // Formatar como CSV (com proteção contra vírgulas) return $"{ProcessarArquivo(caminhoArquivo)};\"{ CNPJ_Comprador}\";\"{ CNPJ_Vendedor}\";\"{ Montante_operação.ToString()?.Replace(',','.')}\";\"{ Valor_unitário.ToString()?.Replace(',', '.')}\";\"{ Valor_final_c_impostos.ToString()?.Replace(',','.')}\";\"{ RS_Comprador}\";\"{ RS_Vendedor}\";\"{ Numero_NF}\";\"{ ICMS_NF.ToString()?.Replace(',','.')}\";\"{ UF_NF}\""; //Cod_TE}\""; }); } static string Id_operacao(string CNPJ_Comprador, string CNPJ_Vendedor, float Montante_operação, float Valor_unitário, float Valor_final_c_impostos) { float tolerancia_montante = 0.01f; float tolerancia_valor_unitario = 0.005f; float tolerancia_valor_final = 0.01f; try { var selecao = dados.Select($"CNPJ_comp = {CNPJ_Comprador} AND CNPJ_vend = {CNPJ_Vendedor}", $"Mes DESC"); foreach (var row in selecao) { double mont_LO = row.Field("Mont_LO"); double prec_LO = row.Field("Prec_LO"); double NF_c_ICMS = row.Field("NF_c_ICMS"); bool montDentroDaTolerancia = Math.Abs(mont_LO - Montante_operação) / Montante_operação < tolerancia_montante; bool unitDentroDaTolerancia = Math.Abs(prec_LO - Valor_unitário) / Valor_unitário < tolerancia_valor_unitario; bool valorDentroDaTolerancia = Math.Abs(NF_c_ICMS - Valor_final_c_impostos) / Valor_final_c_impostos < tolerancia_valor_final; if (montDentroDaTolerancia && unitDentroDaTolerancia) { return row.Field("Cod_TE")!; } else if (valorDentroDaTolerancia) { return row.Field("Cod_TE")!; } } } catch (Exception) { return "NAO IDENTIFICADA"; } return "NAO IDENTIFICADA"; } }