sábado, 23 de janeiro de 2010
FONTES DA DANFE EM VB.NET
Para maiores informações, gentileza entrar em
contato através do meu e-mail:
leo_florindo@hotmail.com
Sorte a todos e sucesso em 2010!
quinta-feira, 18 de junho de 2009
ENVIANDO E-MAIL VIA VB.NET
para uma conta no gmail.
As contas de e-mail abaixo são fictícias. Você deve alterá-las para contas reais.
O código abaixo foi colocado dentro de um timer programado para ser executado a cada cinco minutos (suas propriedades são timer4.Interval = 300000; timer4.Enabled = True).
Quando o tempo de cinco minutos é atingido, o código é então disparado.
Private Sub Timer4_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer4.Tick
If ExisteConexaoInternet() = True Then
'------------ MANDANDO E-MAILS PELO GMAIL
Dim NumeroFigura As String = "C:\temp\winnt" + "imagem1.jpg"
Const destino As String = "teresaflorindo@hotmail.com"
Const Body As String = "Teste de e-mail. Dê uma olhada!!"
Dim respostaEnvioLabel As String
Dim remetenteEmail As String = "leoflorindo@gmail.com" '; //O e-mail do remetente
Dim mail As MailMessage = New MailMessage()
mail.To.Add(destino)
mail.From = New MailAddress(remetenteEmail, "Teresa Florindo", System.Text.Encoding.UTF8)
mail.Subject = "Assunto: Imagens do computador em uso"
mail.SubjectEncoding = System.Text.Encoding.UTF8
mail.Body = Body
mail.BodyEncoding = System.Text.Encoding.UTF8
mail.IsBodyHtml = True
mail.Priority = MailPriority.High
mail.Attachments.Add(New Attachment(NumeroFigura))
Dim client As SmtpClient = New SmtpClient() '//Adicionando as credenciais do seu e-mail e senha:
client.Credentials = New System.Net.NetworkCredential(remetenteEmail, "jeovaedeus")
client.Port = 25
client.Host = "smtp.gmail.com" '; //Definindo o provedor que irá disparar o e-mail
client.EnableSsl = True '; //Gmail trabalha com Server Secured Layer
Try
client.Send(mail)
respostaEnvioLabel = "Envio do E-mail com sucesso"
'MsgBox(respostaEnvioLabel)
Catch ex As Exception
respostaEnvioLabel = "Ocorreu um erro ao enviar:" + ex.Message
'MsgBox(respostaEnvioLabel)
End Try
'-------------------- FIM DO CÓDIGO PARA O GMAIL------------------------------
End If
End Sub
Aqui está somente descrito o envio de um e-mail simples via internet. A porta de acesso é a 25. O servirdor smtp.gmail.com é informado como host.
Verifique que uma simples imagem está sendo enviada em anexo com a mensagem.
Para usar este exemplo, você deve criar uma conta no gmail para uso.
A função ExisteConexaoInternet() verifica se o computador está no caso logado a internet. Se estiver, é possível passar o e-mail sem que o usuário tenha qualquer conhecimento disso.
O código da função está descrito abaixo:
Private Function ExisteConexaoInternet() As Boolean
'Define uma URL válida para consultar
Dim url As New System.Uri("http://www.globo.com/")
'Monta a requisição HTTP
Dim req As System.Net.WebRequest
req = System.Net.WebRequest.Create(url)
'Tenta fazer a requisição
Try
Dim resp As System.Net.WebResponse
resp = req.GetResponse()
resp.Close()
req = Nothing
'Tudo certo... Temos conexão com a Internet
Return True
Catch ex As Exception
'Não deu... Conexão não dispon¡vel
req = Nothing
Return False
End Try
End Function
A função simplesmente verifica se é possível acessar com sucesso um site na internet (no caso o site da Globo). Se for possível, então há a possibilidade de se enviar e-mail via internet e o código de envio de e-mail é liberado.
sexta-feira, 12 de junho de 2009
NF-E: COLETANDO DADOS DO ARQUIVO DE SITUAÇÃO
Em alguns momentos, seja por erro no retorno do web service, seja por algo que impossibilite o acesso, os arquivos -proc-rec.xml para uma nfe enviada normalmente ao servido da sefaz poderão ser perdidos. Ao consultar o site da sefaz você constatará que a mesma já se encontra autorizada para uso, mas não possui ainda o arquivo -pro-rec.xml com número do protocolo informado no site.
Para alguns aplicativos de ERP isso pode significar um problema se de maneira normal estes aplicativos aguardam a recepção do arquivo -pro-rec.xml para validar no banco de dados da empresa a numeração do protocolo de autorização de uso e o status da nf-e no site da Sefaz.
Se o seu ERP move os arquivos de num-lot.xml, -rec.xml e -pro-rec.xml para uma outra pasta quando os mesmos são detectados e um deles não retorna - como o -pro-rec.xml - o trabalho do seu ERP estará comprometido. Você terá que criar um arquivo de pedido de situação da nf-e que enviou à Sefaz e atualizar os dados do protocolo de uso, hora de recepção e status da nf-e na mão... trabalho inglório!!!
Nessa caso, será preciso obter de um outro modo o número do protocolo de autorização da nf-e. Para obter os dados novamente, pode gerar um arquivo de pedido de status e deixar o retorno na mesma pasta onde deveria estar o arquivo -pro-rec.xml não recebido e dessa forma forçar seu ERP a ler o arquivo -sit.XML para resolver por si mesmo essa situação.
Um pedido de situação da nf-e enviado a Sefaz está listado abaixo. O arquivo é pequeno e bem simples de ser gerado:
<
?xml version="1.0" encoding="UTF-8"?><
conssitnfe xsi="http://www.w3.org/2001/XMLSchema-instance" xsd="http://www.w3.org/2001/XMLSchema" versao="1.07" xmlns="http://www.portalfiscal.inf.br/nfe"><
tpamb>1</tpamb>
<xserv>CONSULTA</xserv>
<chnfe
>13090604672291000115550110000000380000000494</chnfe>
</consSitNFe>
O nome do arquivo de pedido de situação é nfe-sit.xml.
Exemplo: 13090604672291000115550110000000380000000494-ped-sit.xml
O arquivo de retorno gerado por um pedido de situação traz em conjunto em seu interior o próprio número da nf-e, o número do protocolo de uso e o status da nf-e no site da sefaz:
< ?xml version="1.0" encoding="UTF-8"?>
<retConsSitNFe versao="1.07" xmlns="http://www.portalfiscal.inf.br/nfe"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.portalfiscal.inf.br/nfe retConsSitNFe_v1.07.xsd">
<infProt>Id="ID113090003033468">
<tpamb>1</tpamb>
<verAplic>1</verAplic>
<cStat>100</cStat>
<xMotivo>Autorizado o uso da NF-e</xMotivo
<cUF>13</cUF>
<chNFe>13090604672291000115550110000000400000000514</chNFe>
<dhRecbto>2009-06-12T08:50:58</dhRecbto>
<nProt>113090003033468</nProt>
<digVal>roFtqwdm/MZJQEmiXms/u3hwEe4=</digVal>
</infProt>
Para coletar a informação do número de protocolo para ser usado na impressão da DANFE, um simples IF a mais precisa ser acrescentado ao código de impressão da DANFE.
Você pode checar antes da impressão da DANFE se há a existência de um arquivo de pedidido de situação ou o arquivo pro-rec.xml de retorno do recibo.
Eis um código em VB.NET para isso:
Dim NomeArquivoRecibo As String
NomeArquivoRecibo = "F:\SisWin\IAM\NFE\RETORNO\PROCESSADOS\" + IdNfe + "-pro-rec.xml"
'Danfe Normal. Pega os dados dos recibos e do protocolo de uso
If TipodeEmissao = "1" Then
'Verifica se já houve retorno do arquivo selecionado
If IO.File.Exists(NomeArquivoRecibo) = False Then
Dim NomeArquivoRecibo5 As String
'Algo errado com o retorno do recibo. Procurar pelo arquivo de situação
'da NF-e. Necessário para os erros de falta de dados do arquivo -pro-rec.xml
'Ler dados do arquivo de retorno de situação, caso o status do
'recibo de retorno esteja diferente de 104
NomeArquivoRecibo5 = "F:\SisWin\NFE\RETORNO\PROCESSADOS" + IdNfe + "-sit.xml"
'Abrir o arquivo de retorno situação de status
Dim reader_5 As XmlTextReader = New XmlTextReader(NomeArquivoRecibo5)
If IO.File.Exists(NomeArquivoRecibo5) = False Then
MsgBox("Impressão da DANFE Cancelada!!! Sem Recibo de Retorno! Envie a NF-e primeiro a SEFAZ!!", MsgBoxStyle.Critical, "DANFE Coplast")
Exit Sub
Else
Do While (reader_5.Read())
Select Case reader_5.NodeType
Case XmlNodeType.Element
If reader_5.Name = "nProt" Then
LProtocolo2 = reader_5.ReadString
If LProtocolo2 <> "" Then
myRow2.NumProtocolo = LProtocolo2
End If
End If
End Select
Loop
reader_5.Close()
End If
(...)
Esse pequeno trecho fará a leitura do dado do Protocolo diretamente do arquivo -sit.xml gerado.
O trecho também pode ser utilizado para gravar o registro de protocolo no banco de dados a fim de evitar problemas quando não se consegue obter o -pro-rec.xml de modo correto no retorno do site da Sefaz.
Sorte a todos!
segunda-feira, 25 de maio de 2009
MANTENDO A MENTE ABERTA PARA O APRENDIZADO
Já foi-se o tempo em que os programadores possuíam suas linguagens
preferidas para trabalho em empresas.
Nos tempos modernos de nossos dias é crucial e necessário ter o domínio de mais de uma linguagem de programação e manter sempre a mente aberta para novos aprendizados.
Foi reunindo os melhores desenvolvedores em VB, ASP e C# que a Microsoft desenvolveu a plataforma .NET. Interligar em uma mesma ferramenta de desevolvimento várias linguagens promove o conhecimento e gera o crescimento entre os desenvolvedores, expandindo seus horizontes para outras áreas como internet e trabalhos em modo cliente servidor.
Aprender deve estar no âmago de todo o bom desenvolvedor de software e deve possibilitar saltos de tecnologia. Por mais que seja bem cômodo ocupar uma vaga em uma empresa que usa somente a mesma linguagem de programação e que faça com que se acomode é importante participar de treinamentos e realizar cursos para se manter inteirado das novas soluções corporativas existentes no mercado. Além de ser algo inteligente investir em si mesmo, você pode estar preparado para mudanças em novas áreas, como a NF-e e seus requisitos para a RFB.
Entender isso é saber que as milhares de linha que você gastará em VB 6 e Delphi para desenvolver a solução são quase nada em comparação no VB.Net. Para isso as linguagens de programação evoluem: permitir que novas soluções e maior interatividade sejam ganhas e tornar as áreas de TI melhor equipadas não somente com um bom hardware, mas com o que de melhor há no mercado no momento.
É cômodo para algumas empresas não desenvolver de VB 6 para VB.NET por motivos de investimentos altos em tecnologia. Mas grandes empresas vêem nesse caminho um ramo natural para a evolução e ganhos de mercado. Se as áreas de TI se tornam cômodas com o que desenvolvem não aproveitam as novas tecnologias e, com o tempo, caem na armadilha de desenvolver grandes códigos para soluções que são fáceis de realizar em novas linguagens de programação.
Não é constragedor verificar que se pensa em desenvolver e se fazer atualizações na área de segurança - como alterar o Linux do firewall - mas não se pensa em atualizar as aplicações internas de Visual Basic 6 para Vb.Net aprimorando com isso todo o ganho possível que se terá com o uso da nova linguagem e de suas companheiras??
Quem se envolve em TI deve estar pronto para aprender o novo e para ser confrotado com o novo. Manter a mente aberta e renovar seus conhecimentos é se fazer apto em vários oportundades que surgirem no mercado.
Saber somente o Visual Basic 6 e o Delphi já não atendem tanto quem necessita criar soluções para uma Nf-e até setembro de 2009.
E se nas próximas atualizações se fizer necessário o uso de tecnologias mais atuais somente disponíves na plataforma .NET??
Evoluir é preciso.
Trabalhe nesse sentido.
segunda-feira, 18 de maio de 2009
MANUAL 3.0 - CÓDIGO DE BARRAS PARA A CONTINGÊNCIA EM VB.NET
Uma das novas alterações diz respeito a impressão da DANFE no modo de contigência que, com esse novo manual, pedirá a emissão de um código de barras próprio para os dados da DANFE em contigência.
Esse novo código de barras deverá ser impresso abaixo do código de
barras da nf-e, conforme mostrado na figura abaixo:
O campo responsável pela emissão desse código de barras será a tag TpEmis dentro do XML da Nf-e. Se o campo TpEmis for diferente de 1 indicará a emissão de uma DANFE em modo de Contingência.
O campo DADOS DA NF-e contêm a composição da chave em código de barras. Ao passar a leitora sobre o segundo código de barras, o resultado de valor esperado deverá ser o que está contido dentro do campo DADOS da NF-e. Quando a DANFE foi emitida em modo normal, o nome desse campo deverá ser PROTOCOLO DE AUTORIZAÇÃO DE USO e deverá conter o referido protocolo de autorização da Nf-e.
A composição do campo DADOS DA NF-e pode ser vista no código VB.Net abaixo:
'Compõe a chave para o código de barras da Danfe em Contigência, se for necessário
DiadaEmissao = Mid(myRow2.dEmi, 1, 2)
TipodeEmissao = myRow2.tpEmis
CodigoUF = DigitoUF(myRow2.destUF)
DadosdaNfe = Trim(CodigoUF + TipodeEmissao + myRow2.destCNPJ + ValorvNF + "2" + "2" + DiadaEmissao)
DigitoDadosNfe = Calculo_DV11(DadosdaNfe)
'Inserção do dígito verificador do módulo 11 para a Nf-e
DadosdaNfe = DadosdaNfe + Trim(DigitoDadosNfe)
A função Calculo_DV11 retorna o cálculo em módulo 11 para o digito verificador dos dados da NF-e e é apresentada abaixo:
Function Calculo_DV11(ByVal strNumero As String) As String
'declara As variáveis
Dim intContador As Integer
Dim intNumero As Integer
Dim intTotalNumero As Integer
Dim intMultiplicador As Integer
Dim intResto As Integer
Dim ValorDigito As Integer
' se nao for um valor numerico sai da função
If Not IsNumeric(strNumero) Then
Calculo_DV11 = ""
Exit Function
End If
'inicia o multiplicador
intMultiplicador = 2
'pega cada caracter do numero a partir da direita
For intContador = Len(strNumero) To 1 Step -1
'extrai o caracter e multiplica pelo multiplicador
intNumero = Val(Mid(strNumero, intContador, 1)) * intMultiplicador
intMultiplicador = intMultiplicador + 1
' se o resultado for maior que nove soma os algarismos do resultado
If intMultiplicador > 9 Then
intMultiplicador = 2
End If
'soma o resultado para totalização
intTotalNumero = intTotalNumero + intNumero
Next
'calcula o resto da divisao do total por 11
intResto = intTotalNumero Mod 11
ValorDigito = 11 - intResto
'verifica as exceções ( 0 -> DV=0 1 -> DV=0 e retorna o DV
Select Case ValorDigito
Case 0
Calculo_DV11 = "0"
Case 1
Calculo_DV11 = "0"
Case Else
Calculo_DV11 = Str(ValorDigito)
End Select
End Function
Após a chave ser composta, a geração do código de barras poderá então ser realizada, com um código simples de chamada para a geração do código de barras:
'Nf-e em contingência / Gerar código de Barras dos dadosdaNFE
If TipodeEmissao <> "1" Then
'Cria o código de barras para a Danfe em Contingência, se houver
'Pôr o código de barras em oculto, se não houver o que gerar
myRow2.DadosNfe = DadosdaNfe
Dim Barcode2 As New BarcodeLib.Barcode(DadosdaNfe, BarcodeLib.TYPE.CODE128C)
PictureBox3.Image = Barcode2.Encode(BarcodeLib.TYPE.CODE128C, DadosdaNfe, 300, 150)
Barcode2.SaveImage("C:\NF-E\Barras\BARRAS2.JPG", BarcodeLib.SaveTypes.JPG)
Dim fs As New FileStream("C:\NF-E\Barras\BARRAS2.JPG", FileMode.Open)
Dim br As New BinaryReader(fs)
myRow2.Imagem2 = br.ReadBytes(br.BaseStream.Length)
br.Close()
fs.Close()
br = Nothing
fs = Nothing
Else
myRow2.Imagem2 = Nothing
End If
O campo Imagem2 deverá ser criado para receber o código de Barras da DANFE impressa em contigência.
Sorte a todos!!
sexta-feira, 15 de maio de 2009
NF-e: Criando um validador para a NF-e em VB.NET
Vamos criar um pequeno aplicativo de validação da Nf-e, executável
em uma chamada por parâmetro. Para executar esse aplicativo, simplesmente
você deverá clicar no botão Iniciar no Windows e selecionar a opção Executar
no menu, informando o seguinte comando:
C:\ValidarNfe.exe C:\NF-E\13090404672291000115550040000000270000000730-nfe.xml
Veja o o exemplo na figura abaixo:
1) Inicie um novo projeto no Vb.NET.
2) Defina nas referências do projeto (Menu Projects - ValidarNfe Properties - aba References) os seguintes namespaces:
System
System.Data
System.Deployment
System.Drawing
System.Security
System.Web.Services
System.Windows.Forms
System.Xml
3) Inclua no formulário uma timer, uma label, um listbox e um botão.
A tela deve ficar como o mostrado abaixo:
4) Defina a propriedade interval do timer em 1000, e dê dois cliques sobre ele. Informe o seguinte código para o Timer:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Show()
End Sub
5) Dentro do código do formulário (form1.vb), no início do mesmo, inclua as seguintes referências:
Imports System.Collections.Generic
Imports System.Text
Imports System.Xml
Imports System.Xml.Schema
Imports System.IO
Imports System.Windows.Forms
Imports System.Security.Cryptography.Xml
Imports System.Security.Cryptography.X509Certificates
6) No evento Load do formulário, acrescente este código:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Valor As String
Me.Show()
If Command() <> "" Then
Valor = Command()
ValidaNfe(Valor)
Me.Focus()
Me.Show()
Me.WindowState = FormWindowState.Normal
End If
End Sub
7) O código do botão Fechar deve ser o que segue abaixo:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
End
End Sub
8) A função ValidaNfe é a que segue abaixo:
Private Sub ValidaNfe(ByVal NfeAler As String)
Try
'Abrir agora o arquivo XML criado e inserir o Protocolo encontrado!!
Dim arquivo2 As String = NfeAler
Dim xDoc As New XmlDocument : xDoc.Load(arquivo2)
Dim Tamanho As String
Dim Nfe As String
Nfe = arquivo2
Tamanho = Replace(Nfe, "C:\", "")
Tamanho = Replace(Tamanho, "F:\SisWin\NFE\BACKUP\200905\", "")
Tamanho = Replace(Tamanho, "F:\SisWin\NFE\BACKUP", "")
Tamanho = Replace(Tamanho, "F:\SisWin\NFE\AENVIAR", "")
Tamanho = Replace(Tamanho, "F:\SisWin\NFE\AENVIAR", "")
Tamanho = Replace(Tamanho, "\", "")
Tamanho = Replace(Tamanho, "\NF-E", "")
Tamanho = Replace(Tamanho, "NF-E", "")
Tamanho = Replace(Tamanho, "SisWin", "")
Tamanho = Replace(Tamanho, "SisWin", "")
'Fazer uma cópia d arquivo XML para gerar a assinatura
Dim CaminhoArquivo As String = "C:\NF-E\XML\" + Tamanho
'Salva o Arquivo
xDoc.Save(CaminhoArquivo)
'Selecionar certificado
SelecionarCertificado()
'Assinar o XML
Dim OAd As New AssinaturaDigitalClass()
Dim pDadosNfe As String
Dim vStringNfe As String
'Dim msgResultado As String
OAd.Assinar(CaminhoArquivo, "infNFe", oCertificado)
If OAd.vResultado = 0 Then 'Assinado corretamente
pDadosNfe = OAd.vXMLStringAssinado
vStringNfe = pDadosNfe.Substring(pDadosNfe.IndexOf("<
NFe"), pDadosNfe.Length - pDadosNfe.IndexOf("<NFe"))Else 'Ocorreu algum erro na assinatura
MessageBox.Show(OAd.vResultadoString, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
'Validar o XML
Dim TxtXSD As String
TxtXSD = "C:\tmp\Schemas NF-e\nfe_v1.10.xsd"
If Not CaminhoArquivo = String.Empty And Not TxtXSD = String.Empty Then
Resultado = True
Dim settings As New XmlReaderSettings()
AddHandler settings.ValidationEventHandler, AddressOf Me.ValidationEventHandler
'Valida o arquivo XML com o seu Schema XSD
lstValida.Items.Add("Validando o arquivo XML " & CaminhoArquivo & " com o arquivo de Schema : " & TxtXSD)
Try
settings.ValidationType = ValidationType.Schema
settings.Schemas.Add("http://www.portalfiscal.inf.br/nfe",xmlReader.Create(TxtXSD))
Using XmlValidatingReader As XmlReader = XmlReader.Create(CaminhoArquivo, settings)
While XmlValidatingReader.Read()
End While
End Using
Catch ex As Exception
lstValida.Items.Add(ex.Message)
Exit Sub
End Try
lstValida.Items.Add("Status Validação -> " & IIf(Resultado = True, "Arquivo validado com SUCESSO", "Validação FALHOU"))
Else
MsgBox("Informe o arquivo XML e o arquivo XSD.")
End If
Catch ex As Exception
'se ocorrer uma exceção exibe a mensagem
lstValida.Items.Add(ex.Message)
End Try
End Sub
A função ValidaNfe chama outras duas funções em seu início: uma que seleciona o certificado automaticamente e outra que assina o documento. O código da função SelecionarCertificado() é que segue abaixo:
Function SelecionarCertificado() As Boolean
Dim vRetorna As Boolean
Dim oX509Cert As New X509Certificate2
Dim store As New X509Store
Dim collection As New X509Certificate2Collection
Dim collection1 As New X509Certificate2Collection
Dim collection2 As New X509Certificate2Collection
Dim scollection As New X509Certificate2Collection
Dim msgResultado As String
Dim xnome As String
xnome = "CN=CERTIFICADOTESTE:09999991000115, OU=Autenticado por AR Fenacon, OU=RFB e-CNPJ A1, OU=Secretaria da Receita Federal do Brasil - RFB, L=Manaus, S=AM, O=ICP-Brasil, C=BR"
oX509Cert = New X509Certificate2()
store = New X509Store("MY", StoreLocation.CurrentUser)
store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
collection = store.Certificates
collection1 = collection.Find(X509FindType.FindByTimeValid, DateTime.Now, False)
collection2 = collection.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, False)
'Encontra o certificado digital pelo nome do mesmo, se precisar pergunta por isso
'Resolvido em 13/05/2009 às 15:05h
scollection = collection.Find(X509FindType.FindBySubjectDistinguishedName, xnome, False)
'Para selecionar o certificado de uma lista
'scollection = X509Certificate2UI.SelectFromCollection(collection2, "Certificado(s) Digital(is) disponível(is)", "Selecione o certificado digital para uso no aplicativo", X509SelectionFlag.SingleSelection)
If (scollection.Count = 0) Then
msgResultado = "Nenhum certificado digital foi selecionado ou o certificado selecionado está com problemas."
MessageBox.Show(msgResultado, "Advertência", MessageBoxButtons.OK, MessageBoxIcon.Warning)
vRetorna = False
Else
oX509Cert = scollection.Item(0) 'Para selecionar o item em Vb.NET
oCertificado = oX509Cert
vRetorna = True
'msgResultado = "Certificado Selecionado."
'MessageBox.Show(msgResultado, "Advertência", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Return vRetorna
End If
End Function
-----------------
Voce deve informar em xnome o nome por extenso do Certificado que irá usar para validar a XML a ser assinado. Para obter o nome por extenso do seu certificado você pode usar a próprioa função acima habilitando a que pede a seleção de certicados de uma lista e colocando o seguinte comando no Else da função acima:
xnome = oCertificado.Subject.ToString
Esse comando colocará o nome do certificado na variável xnome. Se você debugar, pode pegar o nome extenso do certificado que deve usar para validar o XML e colocar dentro da váriavel, como fiz no início do código:
xnome = "CN=CERTIFICADOTESTE:09999991000115, OU=Autenticado por AR Fenacon, OU=RFB e-CNPJ A1, OU=Secretaria da Receita Federal do Brasil - RFB, L=Manaus, S=AM, O=ICP-Brasil, C=BR"
Para a assinatura digital uma classe é acrescentada totalmente no final da classe do formulário. Essa classe é responsável pela assinatura do XML. Eis o código abaixo:
Public Class AssinaturaDigitalClass
Public vResultado As Integer
Public vResultadoString As String
Public vXMLStringAssinado As String
Public XmlDoc As XmlDocument
Sub Assinar(ByVal pArqXMLAssinar As String, ByVal pUri As String, ByVal pCertificado As X509Certificate2)
'Abrir o arquivo XML a ser assinado e ler o seu conteúdo
Dim SR As StreamReader
Dim vXMLString As String
SR = File.OpenText(pArqXMLAssinar)
vXMLString = SR.ReadToEnd()
SR.Close()
' //Atualizar atributos de retorno com conteúdo padrão
vResultado = 0
vResultadoString = "Assinatura realizada com sucesso"
Try
'Verifica o certificado a ser utilizado na assinatura
Dim _xnome As String
Dim _X509Cert As X509Certificate2
Dim store As X509Store
Dim collection As X509Certificate2Collection
Dim collection1 As X509Certificate2Collection
_xnome = ""
_xnome = pCertificado.Subject.ToString()
_X509Cert = New X509Certificate2()
store = New X509Store("MY", StoreLocation.CurrentUser)
store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
collection = store.Certificates
collection1 = collection.Find(X509FindType.FindBySubjectDistinguishedName, _xnome, False)
If (collection1.Count = 0) Then
vResultado = 2
vResultadoString = "Problemas no certificado digital"
Else
' certificado ok
'oX509Cert = scollection.Item(0)
_X509Cert = collection1.Item(0)
Dim x As String
x = _X509Cert.GetKeyAlgorithm().ToString()
' Create a new XML document.
Dim doc As New XmlDocument
doc = New XmlDocument()
'Format the document to ignore white spaces.
doc.PreserveWhitespace = False
' Load the passed XML file using it’s name.
Try
doc.LoadXml(vXMLString)
' Verifica se a tag a ser assinada existe é única
Dim qtdeRefUri As Integer
qtdeRefUri = doc.GetElementsByTagName(pUri).Count
If (qtdeRefUri = 0) Then
' a URI indicada não existe
vResultado = 4
vResultadoString = "A tag de assinatura " + pUri.Trim() + " não existe"
Else
' Existe mais de uma tag a ser assinada
If (qtdeRefUri > 1) Then
' existe mais de uma URI indicada
vResultado = 5
vResultadoString = "A tag de assinatura " + pUri.Trim() + " não é unica"
Else
Try
' Create a SignedXml object.
Dim signedXml As SignedXml
signedXml = New SignedXml(doc)
' Add the key to the SignedXml document
signedXml.SigningKey = _X509Cert.PrivateKey
' Create a reference to be signed
Dim reference As New Reference
reference = New Reference()
'--------- RETIRAR COMENTÁRIOS DAS LINHAS ABAIXO
' pega o uri que deve ser assinada
Dim _Uri As XmlAttributeCollection
Dim _atributo As XmlAttribute
_Uri = doc.GetElementsByTagName(pUri).Item(0).Attributes
For Each _atributo In _Uri
If (_atributo.Name = "Id") Then
reference.Uri = "#" + _atributo.InnerText
End If
Next
' Add an enveloped transformation to the reference.
Dim env As New XmlDsigEnvelopedSignatureTransform
env = New XmlDsigEnvelopedSignatureTransform()
reference.AddTransform(env)
Dim c14 As New XmlDsigC14NTransform
c14 = New XmlDsigC14NTransform()
reference.AddTransform(c14)
' Add the reference to the SignedXml object.
signedXml.AddReference(reference)
' Create a new KeyInfo object
Dim keyinfo As New KeyInfo
keyinfo = New KeyInfo()
' Load the certificate into a KeyInfoX509Data object
' and add it to the KeyInfo object.
keyinfo.AddClause(New KeyInfoX509Data(_X509Cert))
' Add the KeyInfo object to the SignedXml object.
signedXml.KeyInfo = keyinfo
signedXml.ComputeSignature()
' Get the XML representation of the signature and save
' it to an XmlElement object.
Dim xmlDigitalSignature As XmlElement
xmlDigitalSignature = signedXml.GetXml()
' Gravar o elemento no documento XML
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
XmlDoc = New XmlDocument()
XmlDoc.PreserveWhitespace = False
XmlDoc = doc
' Atualizar a string do XML já assinada
vXMLStringAssinado = XmlDoc.OuterXml
' Gravar o XML no HD
' abre um stream para escrita e cria um StreamWriter para implementar o stream
Dim fs As New FileStream(pArqXMLAssinar, FileMode.OpenOrCreate, FileAccess.Write)
Dim SW_2 As New StreamWriter(fs)
SW_2.Flush()
SW_2.BaseStream.Seek(0, SeekOrigin.Begin)
SW_2.Write(vXMLStringAssinado)
SW_2.Flush()
SW_2.Close()
Catch ex As Exception
vResultado = 6
vResultadoString = "Erro ao assinar o documento - " + ex.Message
End Try
End If
End If
Catch ex As Exception
vResultado = 3
vResultadoString = "XML mal formado - " + ex.Message
End Try
End If
Catch ex As Exception
vResultado = 1
vResultadoString = "Problema ao acessar o certificado digital" + ex.Message
End Try
End Sub
End Class
9) Dentro do botão que faz a validação é repassado o código do arquivo XSD que faz a validação:
TxtXSD = "C:\tmp\Schemas NF-e\nfe_v1.10.xsd"
Um EventHandler se faz necessário para a leitura da validação do XSD.
Abaixo, vemos o código da função de validação do EventHandler:
Public Sub ValidationEventHandler(ByVal sender As Object, ByVal args As ValidationEventArgs)
Resultado = False
'lstValida.Items.Add(vbTab + "Erro de Validação : " + args.Message)
If args.Severity = XmlSeverityType.Warning Then
MsgBox("Nenhum arquivo de Schema foi encontrado para efetuar a validação...")
ElseIf args.Severity = XmlSeverityType.Error Then
lstValida.Items.Add(args.Message)
'MsgBox("Ocorreu um erro durante a validação....")
End If
If Not (args.Exception Is Nothing) Then ' Erro na validação do schema XSD
'lstValida.Items.Add(args.Exception.SourceUri + "," & args.Exception.LinePosition & "," & args.Exception.LineNumber)
'MsgBox(args.Exception.SourceUri + "," & args.Exception.LinePosition & "," & args.Exception.LineNumber)
End If
End Sub
Essa função será chamada para retornar o erro que possa estar acontecendo com algum ponto do arquivo XML.
Pronto!!
Cada passo de uma validação para a Nf-e foi descrita acima.
Posto o código completo do arquivo form1.VB abaixo para dirrimir quaisquer dúvidas:
'Validador para arquivos Nf-e
'Data de criação: 12/05/2009
'Para ser utilizado com o Visual Basic 6
'A aplicação funciona com chamada de parâmetro na linha digitável
'Para executar esse aplicativo, use a linha de comando do Windwos
'clicando no botão iniciar de depois em Executar:
'Exemplo de chamada: C:\ValidarNfe.exe C:\NF-E\13090404672291000115550040000000270000000730-nfe.xml
'Desenvolvedor: Manoel Leonardo Metelis Florindo
Imports System.Collections.Generic
Imports System.Text
Imports System.Xml
Imports System.Xml.Schema
Imports System.IO
Imports System.Windows.Forms
Imports System.Security.Cryptography.Xml
Imports System.Security.Cryptography.X509Certificates
Public Class Form1
Private Resultado As Boolean = True
Public oCertificado As New X509Certificate2
Public vStrXmlRetorno As String
Public vArqERRRetorno As String
Public vPastaXMLErro As String
Public vPastaXMLEnvio As String
Public vArqXMLRetorno As String
Public vPastaXMLRetorno As String
Public vXmlNfeDadosMsg As String
Public vAmbiente As Integer
Public vUF As Integer
Private Sub ValidaNfe(ByVal NfeAler As String)
Try
'Abrir agora o arquivo XML criado e inserir o Protocolo encontrado!!
Dim arquivo2 As String = NfeAler
Dim xDoc As New XmlDocument : xDoc.Load(arquivo2)
Dim Tamanho As String
Dim Nfe As String
Nfe = arquivo2
Tamanho = Replace(Nfe, "C:\", "")
Tamanho = Replace(Tamanho, "F:\SisWin\NFE\BACKUP\200905\", "")
Tamanho = Replace(Tamanho, "F:\SisWin\NFE\BACKUP", "")
Tamanho = Replace(Tamanho, "F:\SisWin\NFE\AENVIAR", "")
Tamanho = Replace(Tamanho, "F:\SisWin\NFE\AENVIAR", "")
Tamanho = Replace(Tamanho, "\", "")
Tamanho = Replace(Tamanho, "\NF-E", "")
Tamanho = Replace(Tamanho, "NF-E", "")
Tamanho = Replace(Tamanho, "SisWin", "")
Tamanho = Replace(Tamanho, "SisWin", "")
'Fazer uma cópia d arquivo XML para gerar a assinatura
Dim CaminhoArquivo As String = "C:\NF-E\XML\" + Tamanho
'Salva o Arquivo
xDoc.Save(CaminhoArquivo)
'Selecionar certificado
SelecionarCertificado()
'Assinar o XML
Dim OAd As New AssinaturaDigitalClass()
Dim pDadosNfe As String
Dim vStringNfe As String
'Dim msgResultado As String
OAd.Assinar(CaminhoArquivo, "infNFe", oCertificado)
If OAd.vResultado = 0 Then 'Assinado corretamente
pDadosNfe = OAd.vXMLStringAssinado
vStringNfe = pDadosNfe.Substring(pDadosNfe.IndexOf("<
NFe"), pDadosNfe.Length - pDadosNfe.IndexOf("<NFe"))Else 'Ocorreu algum erro na assinatura
MessageBox.Show(OAd.vResultadoString, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
'Validar o XML
Dim TxtXSD As String
TxtXSD = "C:\tmp\Schemas NF-e\nfe_v1.10.xsd"
If Not CaminhoArquivo = String.Empty And Not TxtXSD = String.Empty Then
Resultado = True
Dim settings As New XmlReaderSettings()
AddHandler settings.ValidationEventHandler, AddressOf Me.ValidationEventHandler
'Valida o arquivo XML com o seu Schema XSD
lstValida.Items.Add("Validando o arquivo XML " & CaminhoArquivo & " com o arquivo de Schema : " & TxtXSD)
Try
settings.ValidationType = ValidationType.Schema
settings.Schemas.Add("http://www.portalfiscal.inf.br/nfe", XmlReader.Create(TxtXSD))
Using XmlValidatingReader As XmlReader = XmlReader.Create(CaminhoArquivo, settings)
While XmlValidatingReader.Read()
End While
End Using
Catch ex As Exception
lstValida.Items.Add(ex.Message)
Exit Sub
End Try
lstValida.Items.Add("Status Validação -> " & IIf(Resultado = True, "Arquivo validado com SUCESSO", "Validação FALHOU"))
Else
MsgBox("Informe o arquivo XML e o arquivo XSD.")
End If
Catch ex As Exception
'se ocorrer uma exceção exibe a mensagem
lstValida.Items.Add(ex.Message)
End Try
End Sub
Function SelecionarCertificado() As Boolean
Dim vRetorna As Boolean
Dim oX509Cert As New X509Certificate2
Dim store As New X509Store
Dim collection As New X509Certificate2Collection
Dim collection1 As New X509Certificate2Collection
Dim collection2 As New X509Certificate2Collection
Dim scollection As New X509Certificate2Collection
Dim msgResultado As String
Dim xnome As String
xnome = "CN=COPLAST INDUSTRIA E COMERCIO DE RESIDUOS PLASTICO:04672291000115, OU=Autenticado por AR Fenacon, OU=RFB e-CNPJ A1, OU=Secretaria da Receita Federal do Brasil - RFB, L=Manaus, S=AM, O=ICP-Brasil, C=BR"
oX509Cert = New X509Certificate2()
store = New X509Store("MY", StoreLocation.CurrentUser)
store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
collection = store.Certificates
collection1 = collection.Find(X509FindType.FindByTimeValid, DateTime.Now, False)
collection2 = collection.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, False)
'Encontra o certificado digital pelo nome do mesmo, se precisar pergunta por isso
'Resolvido em 13/05/2009 às 15:05h
scollection = collection.Find(X509FindType.FindBySubjectDistinguishedName, xnome, False)
'Para selecionar o certificado de uma lista
'scollection = X509Certificate2UI.SelectFromCollection(collection2, "Certificado(s) Digital(is) disponível(is)", "Selecione o certificado digital para uso no aplicativo", X509SelectionFlag.SingleSelection)
If (scollection.Count = 0) Then
msgResultado = "Nenhum certificado digital foi selecionado ou o certificado selecionado está com problemas."
MessageBox.Show(msgResultado, "Advertência", MessageBoxButtons.OK, MessageBoxIcon.Warning)
vRetorna = False
Else
oX509Cert = scollection.Item(0) 'Para selecionar o item em Vb.NET
oCertificado = oX509Cert
xnome = oCertificado.Subject.ToString
vRetorna = True
'msgResultado = "Certificado Selecionado."
'MessageBox.Show(msgResultado, "Advertência", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Return vRetorna
End If
End Function
Public Sub ValidationEventHandler(ByVal sender As Object, ByVal args As ValidationEventArgs)
Resultado = False
'lstValida.Items.Add(vbTab + "Erro de Validação : " + args.Message)
If args.Severity = XmlSeverityType.Warning Then
MsgBox("Nenhum arquivo de Schema foi encontrado para efetuar a validação...")
ElseIf args.Severity = XmlSeverityType.Error Then
lstValida.Items.Add(args.Message)
'MsgBox("Ocorreu um erro durante a validação....")
End If
If Not (args.Exception Is Nothing) Then ' Erro na validação do schema XSD
'lstValida.Items.Add(args.Exception.SourceUri + "," & args.Exception.LinePosition & "," & args.Exception.LineNumber)
'MsgBox(args.Exception.SourceUri + "," & args.Exception.LinePosition & "," & args.Exception.LineNumber)
End If
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
End
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Valor As String
Me.Show()
'Valor = "F:\SisWin\NFE\BACKUP\200905\13090504672291000115550040000001520000002017-nfe.XML"
'ValidaNfe(Valor)
If Command() <> "" Then
Valor = Command()
ValidaNfe(Valor)
Me.Focus()
Me.Show()
Me.WindowState = FormWindowState.Normal
End If
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Show()
End Sub
End Class
Public Class AssinaturaDigitalClass
Public vResultado As Integer
Public vResultadoString As String
Public vXMLStringAssinado As String
Public XmlDoc As XmlDocument
Sub Assinar(ByVal pArqXMLAssinar As String, ByVal pUri As String, ByVal pCertificado As X509Certificate2)
'Abrir o arquivo XML a ser assinado e ler o seu conteúdo
Dim SR As StreamReader
Dim vXMLString As String
SR = File.OpenText(pArqXMLAssinar)
vXMLString = SR.ReadToEnd()
SR.Close()
' //Atualizar atributos de retorno com conteúdo padrão
vResultado = 0
vResultadoString = "Assinatura realizada com sucesso"
Try
'Verifica o certificado a ser utilizado na assinatura
Dim _xnome As String
Dim _X509Cert As X509Certificate2
Dim store As X509Store
Dim collection As X509Certificate2Collection
Dim collection1 As X509Certificate2Collection
_xnome = ""
_xnome = pCertificado.Subject.ToString()
_X509Cert = New X509Certificate2()
store = New X509Store("MY", StoreLocation.CurrentUser)
store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
collection = store.Certificates
collection1 = collection.Find(X509FindType.FindBySubjectDistinguishedName, _xnome, False)
If (collection1.Count = 0) Then
vResultado = 2
vResultadoString = "Problemas no certificado digital"
Else
' certificado ok
'oX509Cert = scollection.Item(0)
_X509Cert = collection1.Item(0)
Dim x As String
x = _X509Cert.GetKeyAlgorithm().ToString()
' Create a new XML document.
Dim doc As New XmlDocument
doc = New XmlDocument()
'Format the document to ignore white spaces.
doc.PreserveWhitespace = False
' Load the passed XML file using it’s name.
Try
doc.LoadXml(vXMLString)
' Verifica se a tag a ser assinada existe é única
Dim qtdeRefUri As Integer
qtdeRefUri = doc.GetElementsByTagName(pUri).Count
If (qtdeRefUri = 0) Then
' a URI indicada não existe
vResultado = 4
vResultadoString = "A tag de assinatura " + pUri.Trim() + " não existe"
Else
' Existe mais de uma tag a ser assinada
If (qtdeRefUri > 1) Then
' existe mais de uma URI indicada
vResultado = 5
vResultadoString = "A tag de assinatura " + pUri.Trim() + " não é unica"
Else
Try
' Create a SignedXml object.
Dim signedXml As SignedXml
signedXml = New SignedXml(doc)
' Add the key to the SignedXml document
signedXml.SigningKey = _X509Cert.PrivateKey
' Create a reference to be signed
Dim reference As New Reference
reference = New Reference()
'--------- RETIRAR COMENTÁRIOS DAS LINHAS ABAIXO
' pega o uri que deve ser assinada
Dim _Uri As XmlAttributeCollection
Dim _atributo As XmlAttribute
_Uri = doc.GetElementsByTagName(pUri).Item(0).Attributes
For Each _atributo In _Uri
If (_atributo.Name = "Id") Then
reference.Uri = "#" + _atributo.InnerText
End If
Next
' Add an enveloped transformation to the reference.
Dim env As New XmlDsigEnvelopedSignatureTransform
env = New XmlDsigEnvelopedSignatureTransform()
reference.AddTransform(env)
Dim c14 As New XmlDsigC14NTransform
c14 = New XmlDsigC14NTransform()
reference.AddTransform(c14)
' Add the reference to the SignedXml object.
signedXml.AddReference(reference)
' Create a new KeyInfo object
Dim keyinfo As New KeyInfo
keyinfo = New KeyInfo()
' Load the certificate into a KeyInfoX509Data object
' and add it to the KeyInfo object.
keyinfo.AddClause(New KeyInfoX509Data(_X509Cert))
' Add the KeyInfo object to the SignedXml object.
signedXml.KeyInfo = keyinfo
signedXml.ComputeSignature()
' Get the XML representation of the signature and save
' it to an XmlElement object.
Dim xmlDigitalSignature As XmlElement
xmlDigitalSignature = signedXml.GetXml()
' Gravar o elemento no documento XML
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
XmlDoc = New XmlDocument()
XmlDoc.PreserveWhitespace = False
XmlDoc = doc
' Atualizar a string do XML já assinada
vXMLStringAssinado = XmlDoc.OuterXml
' Gravar o XML no HD
' abre um stream para escrita e cria um StreamWriter para implementar o stream
Dim fs As New FileStream(pArqXMLAssinar, FileMode.OpenOrCreate, FileAccess.Write)
Dim SW_2 As New StreamWriter(fs)
SW_2.Flush()
SW_2.BaseStream.Seek(0, SeekOrigin.Begin)
SW_2.Write(vXMLStringAssinado)
SW_2.Flush()
SW_2.Close()
Catch ex As Exception
vResultado = 6
vResultadoString = "Erro ao assinar o documento - " + ex.Message
End Try
End If
End If
Catch ex As Exception
vResultado = 3
vResultadoString = "XML mal formado - " + ex.Message
End Try
End If
Catch ex As Exception
vResultado = 1
vResultadoString = "Problema ao acessar o certificado digital" + ex.Message
End Try
End Sub
End Class
quarta-feira, 29 de abril de 2009
NF-E: UM CAMINHO PARA O CÓDIGO DE BARRAS EM VB6
Para isto, basta compilar uma aplicação Windows Form que simplesmente gere o código de barras e utilizar uma chamada call no Visual Basic 6 para esta simples aplicação.
1. Inicie um novo projeto Windows Form Applicattion no VB.Net
2. Chame este projeto de GerBarras
3. Quando os arquivos forem criados, vá ao menu Project -> GerBarras Properties. Clique na opção References na tela que se abre.
A tela será como a que segue abaixo:
Clique no botão Add e indique o caminho do diretório onde se encontra o Barcodelib.dll, conforme a figura.
Usaremos esta dll para fazer a geração do código de barras, recebendo como parâmetro de chamada a numeração que deve ser transformada em código de barras. O aplicativo deverá então gerar uma imagem da numeração do código de barras na pasta C:\NF-e\barras.
Após incluir o barcodelib.dll, clique na pasta Debug e na opção Command Line Arguments digite "parametro", conforme a tela mostrada abaixo:
Agora, nos resta informar o código para geração do código de barras.
4. No modo design do form1, inclua uma objeto Picture. Para isso, clique no menu View e depois em ToolBox. Do lado esquerdo, será aberto a barra de ferramentas. Procure no Common Controls pelo PictureBox. Pressione o mouse sobre ele e arraste-o para o formulário.
Defina as propriedades do PictureBox1 como segue:
Width: 361
Size: 104
5. Em seguida, informe o código abaixo para o form1:
Código na imagem:
Imports System.IO
Imports System.Text
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing.Text
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Valor As String
If Command() <> "" Then
Valor = Command()
Dim Barcode As New BarcodeLib.Barcode(Valor, BarcodeLib.TYPE.CODE128C)
PictureBox1.Image = Barcode.Encode(BarcodeLib.TYPE.CODE128C, Valor, 300, 150)
PictureBox1.Visible = True
Barcode.SaveImage("C:\NF-E\Barras\BARRAS.JPG", BarcodeLib.SaveTypes.JPG)
'MsgBox("Gerado com Sucesso")
End
End If
End Sub
End Class
Clique no menu Build na opção Build GerBarras.
A aplicação será gerada. Se não houverem erros, teste o executável gerado:
6. Encontre o diretório Bin\Release dentro dos fontes do projeto GerBarras. O caminho dos fontes no VB.NET sempre fica identificado com o nome do seu projeto. Exemplo:
C:\Vb.NEt Fontes\GeraBarras\GerBarras\GerBarras\bin\Release
Dentro do diretório Release está o GerBarras.exe que você acaba de criar.
7. Copie o GerBarras.exe para o C:\ da sua máquina.
8. Após isso, clique no botão Iniciar do Windows XP Professional (estou supondo que o sistema operacional na sua máquina é o Windows XP. Fiz este exemplo em uma máquina com o Windows XP), e selecione a opção Executar no Menu:
Na caixa Abrir, digite C:\GerBarras.exe 123456895
Pronto!
Um arquivo jpg apresentando o código de barras do número 123456895 será criado na pasta C:\Nfe-e\Barras.
É só ir até lá e conferir.
Você pode mudar o diretório mudando a linha:
Barcode.SaveImage("C:\NF-E\Barras\BARRAS.JPG", BarcodeLib.SaveTypes.JPG)
Para o diretório que achar mais apropriado.
Para chamar este pequeno aplicativo no Visual Basic 6, use o comando Call:
'Código de Barras a ser gerado
CodigoNfe = Right(TxtID, 44)
'Gerar Código de barras
Call Shell("C:\GerBarras.exe " & CodigoNfe)
Abraço a todos!!
UM APLICATIVO PARA LEITURA DEVOCIONAL ANUAL DA BIBLIA EM ANDROID
Olá, pessoal! Este novo projeto foi criado em Visual Studio 2019 em C#.Net com o Xamarin. Já está disponível no Google Play para vocês baix...
-
O GLPI é um dos muitos tipos de aplicativos helpdesk free existentes na internet. O fórum do mesmo pode ser encontrado neste link: ...
-
A Danfe pode ser gerada em Crystal 8.5 e depois migrada para dentro do Vb.NET ou, se você preferir, totalmente criada dentro do VB.NET 2008 ...
-
Olá, pessoal! Venho através desta informar que a DANFE desenvolvida em VB.NET está agora atualizada para a versão mais nova do Visual S...