Desenvolvimento - Visual Basic
Tratamento de erros no Visual Basic
Veja bem, quando ocorre um erro durante a execução de um programa Visual Basic , o controle vai para uma lógica de tratamento de erros que consiste em exibir uma men- sagem descrevendo a causa do erro e encerrando o programa a seguir...
por José Carlos MacorattiVocê terminou de desenvolver aquele super projeto e esta ansioso para mostrar para o seu chefe. Naturalmente você depurou o seu código e testou tudo antes de gerar os discos de instalação, afinal o seu emprego está em jogo.
A instalação foi um sucesso, basta agora carregar a aplicação, então você clica no ícone da aplicação e surge na tela a fatídica mensagem : Data error event hit in D:\PROJETO1\TESTES\CLIENTES.MDB isn"t a valid Path...", imediatamente você percebe que esqueceu de mudar o caminho para a abertura do banco de dados, e agora... todos os olhos se voltam para você e... bem ai você acorda suando frio, ainda bem que foi tudo um sonho ... ou um pesadelo.
Veja bem, quando ocorre um erro durante a execução de um programa Visual Basic, o controle vai para uma lógica de tratamento de erros que consiste em exibir uma men- sagem descrevendo a causa do erro e encerrando o programa a seguir.
Este é o procedimento padrão adotado pelo Visual Basic durante a execução de um programa compilado; não o leve a mal, ele apenas esta sendo gentil solicitando a sua intervenção.
Você pode, e deve, intervir neste processo construindo uma lógica de interceptação e tratamento de erros no seu código, que irá interceptar os possíveis erros e tra- tá-los de uma forma mais elegante que a adotada pelo procedimento padrão do Visual Basic.
Tudo isto se torna mais enfático quando se trabalha com banco de dados no VB, pois neste caso, teremos muitas condições de erro durante a execução da aplicação.
Lembre-se, não existem nem aplicações, nem programadores e nem usuários perfeitos.
Interceptando erros.
Para interceptar um erro no Visual Basic você usa a instrução On Error.
Quando uma instrução On Error está em vigor e ocorrer um erro o VB vai executar as ações determinadas pela instrução.
Para estar em vigor a instrução On Error deve ser executada antes da ocorrência de um erro na mesma função ou sub-rotina onde ocorreu o erro ou em uma função ou sub-rotina que tenha chamado a função ou sub-rotina onde o erro tiver ocorrido.
A instrução On Error tem a seguinte sintaxe:
On Error goto label
Traduzindo-a teremos:
Quando ocorrer um erro, transfira a execução para a linha após a etiqueta.
A etiqueta é um identificador alfanumérico que termina com dois pontos (:). (Ex: Trataerro: )
Ela tem que começar na primeira coluna e tem que estar na mesma função ou sub-rotina da instrução On Error, sendo exclusiva dentro de um módulo.
Após a etiqueta você fornece o código que vai tratar o erro ocorrido.
Vejamos um exemplo:
Public Sub Exemplo() "Inicia tratamento de erro On error Goto Trata_Erro "Ocorreu um erro, a execução é desviada para a o código que vem "após a etiqueta Trata_Erro Print 1/0 Exit sub Trata_Erro: "Exibe a mensagem e encerra a aplicação. msgbox "Não existe divisão por zero !!!!" End Sub
Obs:Note que antes da etiqueta existe a instrução Exit Sub. Sem ela o codigo após a etiqueta seria sempre executado, mesmo não havendo ocorrência de erros.
Identificando o tipo de erro.
Cada erro gerado no Visual Basic esta associado a um número e tem uma descrição.
Para identificar um erro ocorrido, informando o seu número, a mensagem de erro,
de onde o erro procede, etc. usamos o Objeto Err.
O objeto Err foi introduzido na versão 4.0 do VB e incorpora a funcionalidade da instrução Err, da função Err, da instrução e Função Error e da função Error$.
Utilizaremos então as propriedades do objeto Err para identificar o tipo de erro e fazer o seu tratamento, se for o caso.
As principais propriedades do objeto Err que utilizaremos são:
Number | Fornece Numero do erro gerado |
Description | Fornece a descrição do erro. |
Source | Identifica o nome do objeto que gerou o erro |
Raise | Gera um erro de execução, usado para testar condições de erro. |
Quando ocorre um erro o VB coloca o número do erro na propriedade Number do objeto Err, conhecendo o número do erro você pode determinar o tipo de erro e tomar a decisão quanto ao seu tratamento.
Vejamos um exemplo prático:
Vamos definir uma tabela com o nome de erro que estará armazenada no banco de dados Controle.mdb e que possuirá a seguinte estrutura:
--------------------------------------------------------- nome do campo Tipo de Dados Tamanho do Campo --------------------------------------------------------- codigo Long 04 nome Caracter 30 ---------------------------------------------------------
1-Defina um índice para o campo codigo ativando as opções: Unique, Primary index. e Requerid
Desta forma estamos criando uma chave primária para o campo codigo.
Se tentarmos gravar um registro com um número de código que já foi gravado o Jet retornará um erro, o erro de número de 3022, poderemos portando interceptá-lo e através do tratamento informar ao usuário que o código já foi utilizado permitindo a seguir ao usuário informar outro código.
Tudo se passa como se estivessemos fazendo a critica da entrada de dados do usuário, só que sem utilizar nenhum código a não ser a interceptação e o tratamento do erro.
1-Ao iniciar a aplicação teremos tela da figura 1.0 abaixo
Figura 1
2-Suponhamos que o usuário tente incluir um código que já foi utilizado, ao clicar no botão gravar ocorrerá uma mensagem de erro, pois o Jet não permite a duplicação de uma chave primária.
Prevendo tal ação iniciamos o tratamento de erros e interceptando-o retornamos ao usuário a mensagem da figura 2.0 abaixo:
Figura 2
Fazemos isto utilizando a instrução Resume Next colocada após a mensagem de aviso ao usuário.
Private Sub Command5_Click() On Error GoTo erro_mdb "inicia o tratamento de erros "verifica se esta incluindo ou editando caso contrário não faz nada If rs.EditMode = dbEditAdd Or rs.EditMode = dbEditInProgress Then grava_regs rs.Update --> linha que irá gerar o erro. limpa_regs Form1.Caption = "Tratamento de Erros " rs.Bookmark = rs.LastModified load_regs End If Exit Sub erro_mdb: MsgBox "Erro número : " & Str$(Err.Number) & " --> Codigo já utilizado !!! " Resume Next "retorna a ação para a linha de código subsequente áquela que "gerou o erro End Sub
- Código do projeto para Tratamento de erros.
Option Explicit Dim db As Database Dim rs As Recordset Dim dbname As String Private Sub Command1_Click() "Inicia processo de inclusao, limpa os controles e "foca o textbox codigo Form1.Caption = "Inclusao !!! " rs.AddNew limpa_regs Text1.SetFocus End Sub Private Sub Command2_Click() "encerra aplicação End End Sub Private Sub Command3_Click() "move para o próximo registro rs.MoveNext If rs.EOF() Then rs.MovePrevious Form1.Caption = "Tratamento de Erros " load_regs End Sub Private Sub Command4_Click() "move para o registro anterior rs.MovePrevious If rs.BOF() Then rs.MoveNext Form1.Caption = "Tratamento de Erros " load_regs End Sub Private Sub Form_Load() dbname = App.Path & "\controle.mdb" Set db = DBEngine.Workspaces(0).OpenDatabase(dbname) Set rs = db.OpenRecordset("erro") If rs.RecordCount > 0 Then load_regs Else MsgBox "Arquivo vazio" limpa_regs End If End Sub Public Sub load_regs() "carrega os dados nos controles Text1 = "" & rs("codigo") Text2 = "" & rs("nome") End Sub Public Sub limpa_regs() "limpa os controles Text1 = "" Text2 = "" End Sub Public Sub grava_regs() "descarrega o conteúdo dos controles para gravação rs("codigo") = Text1.Text rs("nome") = Text2.Text End Sub
Finalizando um tratamento de erros.
Após a interceptação do erro você faz o tratamento do mesmo e tem que terminar o tratamento de erros com uma instrução que elimine o erro, caso contrário o próprio tratamento de erros irá gerar um erro.
No caso anterior a instrução que eliminou o erro foi a instrução Resume Next, pois devolveu a ação ao usuário.
Vejamos abaixo as principais instruções utilizadas para eliminar um erro.
Resume Next | Retorna a execução na linha que vem logo após à linha que gerou o erro |
Resume | Executa mais uma vez a linha que gerou o erro. |
Resume Label | Retorna a execução da linha que vem após a etiqueta citada. |
Resume Number | Retorna a execução na linha com o número indicado. |
Exit Sub | Sai da sub rotina atual. |
Exit Function | Sai da função atual. |
Exit Property | Sai da propriedade atual. |
On Error | Redefine a lógica de tratamento de erros. |
Err.Clear | Elimina o erro sem afetar a execução do programa. |
End | Encerra a execução do programa. |
Vejamos um exemplo onde simulamos várias situações de erro e utilizamos o tratamento de erros para determinar o número do erro a linha onde ocorreu o erro e que gerou o erro.
Obs: Cuidado ao usar Resume pois você pode ficar preso num loop infinito.
Note que utilizamos números de linha em nosso código para ser possível a identificação do número da linha pelo tratamento de erros.
Private Sub Form_Load() Dim db As Database Dim dbName As String Dim rs As Recordset Dim s As String On Error GoTo TrataErro "ativa o tratamento de erros dbName = app.path & "\controle.mdb" 10 Set db = DBEngine.Workspaces(0).OpenDatabase(dbName) " Aqui ocorre um erro, pois a tabela não existe neste banco de dados 20 Set rs = db.OpenRecordset("erros", dbOpenTable) " Aqui temos a abertura correta da tabela erro 30 Set rs = db.OpenRecordset("erro", dbOpenTable) " Aqui ocorre mais um erro, pois não existe o campo endereço na " tabela erro 40 s = rs![endereço] " Aqui temos outro erro pois o código não aceita valores alfanuméricos 50 rs![código] = "XYZ" " Encerra a aplicação 60 End Exit Sub LoadError: MsgBox "Erro número #" & Str$(Err.Number) & " na Linha " & Str$(Erl) & " - "_ & Err.Description & " - gerado por " & Err.Source Resume Next "devolve a ação para a linha subsequente à que gerou o erro. End Sub
Você dever obter, ao iniciar o projeto, a mensagem da figura 3.0 e a seguir a mensagem de erro da figura 4.0, e assim por diante.
Fugura 3
Figura 4
Observe que a descrição utilizada é fornecida pela propriedade description do objeto Err.
A instrução que eliminou o erro foi a instrução Resume Next, pois devolve a ação para a linha subsequente à que gerou o erro permitindo assim que o aplicação seja executada até o seu final.
Simulando um erro
Na rotina abaixo vemos como gerar um erro fornecendo o número do erro desejado:
On error GoTo Trata_Erro_divisao Err.Raise Number:=11 "Gera um erro de divisão por zero exit sub Trata_Erro_divisao: Select Case Err.Number case 11 if MsgBox("Não Existe divisão por Zero. !!! ", vbYesNo) = vbYes Then c=inputbox("Informe o valor do denominador ! ") resume else exit sub endif End Select
Principais erros relacionados a banco de dados.
Naturalmente você deve estar preparado para prever os erros potenciais e planejar o seu tratamento, para isso devera conhecer os principais erros relacionados ao seu ambiente de trabalho.
Relacionar aqui todos os erros tratáveis do Visual Basic seria impossível, mas vamos tentar listar os principais fornecendo o seu número e descrição, vamos lá:
------------------------------------------------------------------------- número Mensagem ------------------------------------------------------------------------- Erros genéricos. 3005 Database name" isn"t a valid database name. 3006 Database "name" is exclusively locked. 3008 Table "name" is exclusively locked. 3009 Couldn"t lock table "name"; currently in use. 3010 Table "name" already exists. 3015 "Index name" isn"t an index in this table. 3019 Operation invalid without a current index. 3020 Update or CancelUpdate without AddNew or Edit. 3021 No current record. 3022 Duplicate value in index, primary key, or relationship. Changes were unsuccessful. 3023 AddNew or Edit already used. 3034 Commit or Rollback without BeginTrans. 3036 Database has reached maximum size. 3037 Can"t open any more tables or queries. 3040 Disk I/O error during read. 3044 "Path" isn"t a valid path. 3046 Couldn"t save; currently locked by another user.
Erros relacionados a bloqueio de registros
3027 Can"t update. Database or object is read-only. 3158 Couldn"t save record; currently locked by another user. 3167 Record is deleted. 3186 Couldn"t save; currently locked by user "name" on machine "name". 3187 Couldn"t read; currently locked by user "name" on machine "name". 3188 Couldn"t update; currently locked by another session on this machine. 3189 Table "name" is exclusively locked by user "name" on machine "name". 3197 Data has changed; operation stopped. 3260 Couldn"t update; currently locked by user "name" on machine "name". 3261 Table "name" is exclusively locked by user "name" on machine "name". 3356 The database is opened by user "name" on machine "name".
Erros relacionados a Permissões
3107 Record(s) can"t be added; no Insert Data permission on "name". 3108 Record(s) can"t be edited; no Update Data permission on "name". 3109 Record(s) can"t be deleted; no Delete Data permission on "name". 3110 Couldn"t read definitions; no Read Definitions permission for table or query "name". 3111 Couldn"t create; no Create permission for table or query "name". 3112 Record(s) can"t be read; no Read Data permission on "name". -------------------------------------------------------------------------
Coleção de Erros do DBEngine
O VB fornece um nível especial de proteção para erros de acesso aos dados através da geração do objeto Error, o qual armazena as informações de erro além do objeto Err. Existe portanto uma coleção Errors que armazena esses erros.
Para visualizar a coleção de erros podemos usar a rotina:
For x=0 to DBEngine.Errors.Count -1 MsgBox DBEngine.Errors(x).Description next
Acho que acabei. Ate mais ver...
- Sou programador, o mágico atende na sala ao ladoPHP
- System Tray - O seu ícone ao lado do relógio do WindowsVisual Basic
- Criando Aplicações Limitadas a Uma Única Instância (Single Instance)C#
- Criando um pacote de instalação com o INNO SETUPVisual Basic
- Nota Fiscal Eletrônica: Construindo um "Servidor de Assinatura Digital" com o NFeExpr...Visual Basic