Cualquier usuario que se haya adentrado en el mundo de las macros o del VBA (Visual Basic for Applications) habrá comprobado como es necesario convivir con los errores que se producen al ejecutar determinado código.
A veces, que ocurra un error es comprensible, natural y en ocasiones inevitable. Lo que sí debemos evitar es que nuestra macro o procedimiento se bloquee, apareciendo el típico mensaje de error:
Pero comencemos desde el principio. En el ámbito del VBA, hay tres tipos de error:
- Los errores de compilación (sintaxis inadecuada). Estos errores de compilación son detectados por el editor de VBA al compilar el código, antes de comenzar a ejecutarse el procedimiento:
- Por escribir inadecuadamente una expresión. Es decir, escribir una palabra inexistente en VBA
- Por omitir una expresión donde debería estar escrita
- Por escribir una expresión en un lugar que no corresponde
- Los errores lógicos. Estos errores son más bien de planteamiento del código, no de sintaxis. El código está bien escrito y no se producen errores que bloqueen la ejecución. Aunque el programa funciona, no realiza las funciones para las que se diseñó o las realiza de forma errónea.
- Los errores en tiempo de ejecución. Estos son detectados por Excel cuando ya se está ejecutando el código y pueden ser motivados por múltiples causas. En cualquier caso, siempre hay algo en común: Excel no puede ejecutar la acción que nosotros pretendemos con el código porque se produce una incoherencia (el resultado es un error, una condición que nunca se cumple, un valor que es imposible de asignar, un límite sobrepasado, etc.)
En la imagen anterior, vemos un error en tiempo de ejecución. Concretamente, Excel no ha podido encontrar el archivo que el código solicitaba abrir. En adelante, en este post, nos referiremos a este último tipo de errores (los errores en tiempo de ejecución).
¿Qué podemos hacer ante la posibilidad de que se produzca un error en la ejecución de nuestro código?
En Visual Basic tenemos la instrucción "On Error" para decidir lo que queremos que ocurra si se produjera un error en nuestro código. Tenemos 3 opciones para complementar la instrucción "On Error":
- On error Resume Next (traducido sería: si hay un error, reanudar el código en la siguiente línea). Con esta opción, cuando se detecta el error, no aparece ningún cuadro de diálogo para "Finalizar" o "Depurar". La ejecución continua en la siguiente línea de código. Podemos ver un ejemplo aquí:
- On Error GoTo MiEtiqueta (traducido sería: si hay un error, ir a MiEtiqueta). Con esta opción, al detectarse un error, obligamos a que la ejecución de código continúe en una línea marcada por nosotros con una etiqueta*. De esta forma y a continuación de esa etiqueta, podemos escribir un código que se ejecute en el caso de existencia de error:
Vemos en el ejemplo anterior que, en caso de error (al no encontrar el archivo Libro2.xlsm), enviamos la ejecución a la etiqueta ControlErrores para que se ejecute el código a partir de ahí (un MsgBox).
(*) Las etiquetas pueden ser textos (sin espacios), pero también pueden ser números (excepto el 0 (cero)). En el siguiente punto de este artículo quedará explicado por qué no se debe poner un cero como etiqueta..
Cuando nombramos una etiqueta después de las instrucciones "On Error GoTo ...." , la etiqueta no debe llevar dos puntos al final, pero al etiquetar la linea (a la que enviamos la ejecución del código), la etiqueta SÍ debe llevar dos puntos al final (ver imagen anterior).
Es conveniente utilizar una instrucción Exit Sub antes del control de errores (que se suele colocar al final del procedimiento) para evitar que sea leído el código si no es necesario (si no existe error). Por ejemplo:
- On Error Goto 0 (traducido sería: si hay un error, deshabilitamos el control de errores). Con esta opción, si habíamos utilizado en el procedimiento la instrucción "On Error..." quedará deshabilitada y los errores de nuevo bloquearán Excel si se producen.
En la imagen de arriba vemos como se produce un error, puesto que "On Error GoTo 0" deshabilita el anterior "On Error GoTo ControlErrores"
Es importante resaltar que "On Error.." habilita el control de errores sólo para un ámbito de procedimiento. En otras palabras:
- Cuando se termina de ejecutar un procedimiento, termina el efecto de "On Error"
- "On Error..." utilizado en un procedimiento x , no afecta a ningún otro procedimiento.
- On Error Goto -1 (traducido sería: si hay un error, se reinicia la posibilidad de detectar y controlar un error)**. Es necesario saber que si en un momento dado hay una instrucción "On Error.." controlando un error (está en pleno trabajo)... si ocurriera otro error en ese instante, no podría ser controlado. Para restablecer "On Error..." y que pueda volver a detectar errores (quede libre de trabajo), se utiliza On Error GoTo -1.
** Es importante tener en cuenta la diferencia entre "On Error GoTo 0" y "On Error GoTo -1":
- "On Error GoTo 0", se utiliza para dejar de detectar errores
- "On Error GoTo -1", se utiliza para volver a detectar errores, durante el control de un error
¿Cómo puedo comprobar si hay un error en algún rango o expresión y decidir lo que ocurrirá después?
También podemos controlar el comportamiento de Visual Basic en el caso de que se produzca un error, de otra forma distinta a las ya conocidas. Es el caso de la función de comprobación IsError. La forma de utilizarla es:
IsError(expresión)
Veamos un ejemplo en este fragmento de código:
Podemos apreciar como, después de declarar la variable "Edad" y de asignarle como valor lo introducido en un cuadro de entrada de datos (InputBox), el código comprueba...:
- Con una estructura condicional If...Then...Else, si la edad es < 18
- Con la función de comprobación IsError, si la variable contiene un error (este se podría producir si el usuario no introduce un número, pues la variable se declaró como numérica)
Si desea llevar a la práctica todo lo que le hemos ofrecido en este artículo, puede asistir a nuestros cursos prácticos de Excel o puede solicitarlos in company:
Gracias miles yo pense que andaba algo mal con mi office y a cambiar de versiones y cd's jejeje habia que cambiar al programador (yo) gracias gracias
ResponderEliminarBuenas! Necesito ayuda. Quise abrir un formulario de VBA desde una imagen en un Excel a través de la cual se abría normalmente. Ayer quise abrirlo y me saltó el siguiente error: "No se puede ejecutar la macro 'LibroX'. Puede que la macro no esté disponible en este libro o que hayan deshabilitado todas las macros" y sólo el botón de Aceptar... Qué está pasando? Cómo se soluciona?
ResponderEliminarPues está pasando justo lo que dice el cuadro de diálogo. Que la macro que estaba asignada al botón ya no está: o bien porque se ha eliminado, o bien porque la macro no se grabó para este libro y por lo tanto no está alojada en este libro.
EliminarTambién podría haber alguna que otra razón más extraña...pero posible.
Hola, necesito ayuda. Quisiera crear una macro que cerrase Word cuando detecta que el archivo esta corrupto o dañado. He conseguido hacer una que cierra la aplicación cuando se produce un error en el codigo de la macro, pero eso no me sirve, ya que la macro no arranca si no acepto las ventanas de aviso de archivo corrupto. Saludos y gracias.
ResponderEliminarHola, necesito ayuda. Busco como hacer una macro para que cierre Word o la aplicación de Office que corresponda cuando al abrir el archivo lo detecte como corrupto o dañado. He conseguido hacer una macro que cierra la aplicación si aparace algún error en el código de la macro, pero no me sirve del todo ya que si no acepto las ventanas de aviso de archivo dañado la macro no se ejecuta. Saludos y gracias.
ResponderEliminarPrueba con Application.DisplayAlerts = False
ResponderEliminarSaludos
MIRA MI CÓDIGO ES EL SIGUIENTE:
ResponderEliminarPrivate Sub CommandButton1_Click()
On Error GoTo ERROR
Dim Myconm As New Connection
Dim rm As String
Dim X As Integer
X = 0
Myconm.Open "ConexionMantenimiento"
Set rsrc = New Recordset
rm = "Select CODIGO, APELLIDO, NOMBRE FROM FAM_OFI"
rsrc.Open rm, Myconm
listfo.Clear
Do While rsrc.EOF = False
listfo.AddItem
listfo.List(X, 0) = rsrc!CODIGO
listfo.List(X, 1) = rsrc!APELLIDO
listfo.List(X, 2) = rsrc!NOMBRE
X = X + 1
rsrc.MoveNext
Loop
ERROR:
MsgBox "ALGO INESPERADO SUCEDIO"
End Sub
cuando lo ejecuto así no exista algún error igual me muestra el mensaje, cosa que no debería ser ya que no existe ningún error.
Un poco mas arriba pone lo siguiente, lo cual no has aplicado...
ResponderEliminarEs conveniente utilizar una instrucción Exit Sub antes del control de errores (que se suele colocar al final del procedimiento) para evitar que sea leído el código si no es necesario (si no existe error).
me pueden ayudar con el siguiente error:
ResponderEliminarSelect method of Range class failed
El codigo es el siguiente:
Set wbDestino = Workbooks.Open(ActiveWorkbook.Path & "\CargaBibanking.xlsx")
ThisWorkbook.Activate
Set wsOrigen = Worksheets("CARGA BIBANKING")
Set wsDestino = wbDestino.Worksheets("CARGA BIBANKING")
Const celdaOrigen = "A1"
Const celdaDestino = "A1"
Set rngOrigen = wsOrigen.Range(celdaOrigen)
Set rngDestino = wsDestino.Range(celdaDestino)
rngOrigen.Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
rngDestino.PasteSpecial xlPasteValues
Application.CutCopyMode = False
wbDestino.Save
wbDestino.Close
y el error lo muestra en la linea que dice "rngOrigen.Select"
Gracias.
Probablemente es porque en el momento de requerir la selección de "rngOrigen" no esté activo an pantalla ese objeto (wsOrigen ... o lo que es lo mismo, la hoja CARGA BIBANKING)
ResponderEliminarPreviamente habría que introducir un código que activara esa hoja
Espero haber ayudado
Muy buena información!! Gracias. Sólo no se entiende lo de GoTo -1.
ResponderEliminarESTOY INGRESANDO EN EXCEL VBA NUEVOS CAMPOS EN UN FORMULARIO PERO ME SALE ERROR DE COMPILACION NO SE HA ENCONTRADO LA VARIABLE COMO LO PUEDO SOLUCIONAR ME PODRÍAN AYUDAR ENVIANDO LA RPTA A MI EMAIL miguelafan@hotmail.com
ResponderEliminarMuchas gracias
ResponderEliminarHola.
ResponderEliminarTe cuento el caso, hice una macro con la grabadora de macros para actualizar varias tablas de datos desde la web. El problema es que hasta el hacerlo manualmente requiere, a veces, tener que detener la ejecucion de la actualizacion presionando "ESC" y volver a actualizar para evitar el largo tiempo de espera en el que cae, haciendo eso la actualizacion se ejecuta en menos de 15 segundos, esto puede pasar con cualquier tabla al hacer la seguidilla de actualizaciones.
El pedido es, qué codigo me permitiria que en caso de demorar la actualizacion en mas de 10 segundos sobre una tabla, que suspenda y vuelva a ejecutar el mismo codigo dos veces más y recien luego seguir con el siguiente, ya sea que se pudo o no actualizar (por error o tiempo de espera).
gracias!
Buenos dias yo tengo el siguiente error, Private Sub CommandButton1_Click() me podrias ayudar a corregirlo la misma quedo asi
ResponderEliminarPrivate Sub CommandButton2_Click()
Unload Me
End Sub
Private Sub CommandButton1_Click()
GuardarInformacion()
End Sub
Sub GuardarInformacion()
Rem Declación de variables
Dim contFilas As Long
Dim hoja As Worksheets
Set hoja = Worksheets(1)
'Validamos que los campos de texto correspondientes a los datos del container esten dilingenciados totalmente
If Trim$(TextBox1.Text) = Empty Or Trim$(TextBox2.Text) = Empty Or Trim$(TextBox3.Text) = Empty Or Trim$(TextBox4.Text) = Empty Or Trim$(TextBox5.Text) = Empty Or Trim$(TextBox6.Text) = Empty Or Trim$(TextBox7.Text) = Empty Or Trim$(TextBox8.Text) = Empty Or Trim$(TextBox9.Text) = Empty Or Trim$(TextBox10.Text) = Empty Or Trim$(TextBox11.Text) = Empty Then
MsgBox "Por Favor Ingrese Todos Los Datos!", "Datos Incompletos"
Exit Sub
End If
' Validamos la fila siguiente en la hoja donde se deben ingresar los datos'
ConFila = hoja.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
hoja .Cells(ContFila, 1).Value = TextBox1
hoja .Cells(ContFila, 2).Value = TextBox2
hoja .Cells(ContFila, 3).Value = TextBox3
hoja .Cells(ContFila, 4).Value = TextBox4
hoja .Cells(ContFila, 5).Value = TextBox5
hoja .Cells(ContFila, 6).Value = TextBox6
hoja .Cells(ContFila, 7).Value = TextBox7
hoja .Cells(ContFila, 8).Value = TextBox8
hoja .Cells(ContFila, 9).Value = TextBox9
hoja .Cells(ContFila, 10).Value = TextBox10
hoja .Cells(ContFila, 11).Value = TextBox11
'Se limpia o borran los datos de los campos de texto del formulario
TextBox1.Value = ""
TextBox2.Value = ""
TextBox3.Value = ""
TextBox4.Value = ""
TextBox5.Value = ""
TextBox6.Value = ""
TextBox7.Value = ""
TextBox8.Value = ""
TextBox9.Value = ""
TextBox10.Value = ""
TextBox11.Value = ""
TextBox1.SetFocus
End Sub
No entiendo la pregunta ni el problema.
EliminarPuedes explicarlo de otra forma?
Saludos
Hola.. quisiera que me ayudaran..
ResponderEliminarTengo una macro que me crea hyperlinks en el nombre del producto de mi base de datos.. que al darle clic me habre la imagen de este mismo con el mismo nombre guardada en una carpeta ... ok esa parte esta bien.. el problema es que quisiera saber si hay algun codigo que cuando la foto no exista (o este mal el nombre) entonces que automaticamente que valla a la o las celdas del error y que quite el hyperlink...
Digo que lo quite por que cuando corro mi macro hasta al producto que no tengo guardado con foto le pone hyperlink... solo que cuando le doy clic dice que no se puede encontrar el archivo... por tal razon quisiera el codigo de que si se produce el error en alguna celda le quite el hyperlink.. de antemano muchas gracias
Si, si es posible hacerlo.
Eliminar:)
buenas, a ver si me pueden ayudar soy nuevo en esto, meda error 13 y no se como arreglarlo. mi correo es palacios347@gmail.com
ResponderEliminarSub GuardarInformacion()
Rem Declaración de Variables
Dim ContFila As Long
Dim hoja As Worksheets
Set hoja = Worksheets(1)
Rem buscamos la fila donde se deben escribir los datos
ContFila = hoja.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
hoja.Cells(ContFila, 1).Value = Me.TextFecha.Value
hoja.Cells(ContFila, 2).Value = Me.TextNombre.Value
hoja.Cells(ContFila, 3).Value = Me.TextCurso.Value
hoja.Cells(ContFila, 4).Value = Me.Texttlf.Value
hoja.Cells(ContFila, 5).Value = Me.TextTutor.Value
hoja.Cells(ContFila, 6).Value = Me.TextTlfTutor.Value
hoja.Cells(ContFila, 7).Value = Me.Textasign1.Value
hoja.Cells(ContFila, 8).Value = Me.TextAsign2.Value
hoja.Cells(ContFila, 9).Value = Me.TextAsign3.Value
hoja.Cells(ContFila, 10).Value = Me.Texthorsem.Value
hoja.Cells(ContFila, 11).Value = Me.TextInsti.Value
hoja.Cells(ContFila, 12).Value = Me.TextComent.Value
Rem Se limpia el formulario
Me.TextFecha.Value = ""
Me.TextNombre.Value = ""
Me.TextCurso.Value = ""
Me.Texttlf.Value = ""
Me.TextTutor.Value = ""
Me.TextTlfTutor.Value = ""
Me.Textasign1.Value = ""
Me.TextAsign2.Value = ""
Me.TextAsign3.Value = ""
Me.Texthorsem.Value = ""
Me.TextInsti.Value = ""
Me.TextComent.Value = ""
End Sub
Buenas noches,
ResponderEliminarQuisiera que me colaboraran por favor con este error:
Sub botonproductos()
'
' botonproductos Macro
'
'
("Productos").Delete
Range("C5").Delete
("Menú").Delete
ActiveSheet.Shapes.Range(Array("Group 6")).Select
. = "botonproductos"
Range("M6").Delete
End Sub
Al tratar de abrir el boton me sale
error de compilacion error de sintaxis
y se sombrea de azul
("Productos").Delete
agradezco de antemano su colaboración