DOMINA-BACH Básico common mistakes
DOMINA-BACH Básico · Understand the traps and how to avoid them.
Escribir código ejecutable directamente en el módulo de la hoja (Sheet1) o en ThisWorkbook en lugar de crear un módulo estándar, y luego no encontrar el procedimiento en la lista de macros (Alt+F8).
El candidato confunde el lugar donde se almacena el código con el lugar donde se ejecuta; los módulos de objeto están asociados a eventos y sus procedimientos públicos con argumentos o Private no aparecen en el cuadro de macros.
What to do instead
Insertar siempre un módulo estándar (Insertar > Módulo) para los procedimientos generales; reservar ThisWorkbook y los módulos de hoja para controladores de eventos. Verificar que el procedimiento sea Public y sin argumentos obligatorios para que aparezca en Alt+F8.
Usar Range("A1:B10").Value sin saber si devuelve un escalar o una matriz, y luego asignarlo a una variable String o compararlo directamente con un número, provocando errores de tipo o resultados inesperados.
El candidato no interioriza que .Value de un rango multicelda devuelve un Variant que contiene un array bidimensional base 1, mientras que un rango de una sola celda devuelve un escalar.
What to do instead
Declarar la variable como Variant y asignar el rango completo de una vez (vDatos = Range("A1:B10").Value), o recorrer con Cells(fila, columna). Comprobar siempre las dimensiones con UBound/LBound antes de indexar y reservar el acceso celda a celda para casos puntuales.
Recorrer un rango con For Each celda In Range(...) y modificar el valor de celda dentro del bucle, o usar ActiveCell/Selection como referencia implícita en lugar de un objeto Range explícito.
El candidato aprende el patrón de iteración pero no distingue entre leer y escribir en la colección, y confía en que la selección del usuario será la esperada en el momento de ejecutar la macro.
What to do instead
Asignar el rango a una variable de objeto (Set rng = Worksheets("Datos").Range("A1:A100")) y cualificar siempre la hoja y el libro (ThisWorkbook.Worksheets). Para escritura masiva, cargar en un array y volcar con un solo Range.Value = arr.
Declarar variables sin Option Explicit y reutilizar nombres con erratas (por ejemplo fila y filas), de modo que el código compila pero una variable nueva vale Empty y el bucle no termina o produce resultados vacíos.
VBA crea variables al vuelo cuando no hay Option Explicit; el error no se detecta en compilación y solo aparece como comportamiento silencioso en ejecución.
What to do instead
Activar Option Explicit al inicio de cada módulo (Herramientas > Opciones > Editor > Requerir declaración de variables) y compilar con Depuración > Compilar antes de ejecutar. Usar tipos explícitos (Long para filas, Double para cálculos, String para texto) y no reutilizar nombres parecidos.
Usar Integer para contadores de filas o para índices de hojas y desbordar en 32.767, o comparar fechas y números como texto porque se concatenan o se leen de celdas con formato.
El candidato traslada hábitos de otros lenguajes y desconoce que Integer en VBA es de 16 bits y que las fechas son Double internamente; además, el formato de celda no cambia el tipo del valor leído.
What to do instead
Declarar contadores de filas como Long (hasta 1.048.576 en Excel moderno) y fechas como Date o Double. Convertir explícitamente con CLng, CDbl o CDate, y usar IsDate/IsNumeric antes de convertir. Recordar que las constantes de color y de Excel (vbRed, xlUp, xlCalculationManual) están predefinidas y no requieren declaración.
Construir bucles Do While o For sin una condición de salida que realmente cambie dentro del cuerpo, o usar For Each sobre una colección que se modifica (eliminar filas) y saltarse elementos o entrar en bucle infinito.
El candidato escribe la condición pensando en el estado inicial, pero no verifica que la variable de control se actualice en todas las rutas, incluidas las que contienen Exit For o GoTo.
What to do instead
Para borrar filas, recorrer de abajo hacia arriba con Step -1 (For i = ultimaFila To 1 Step -1) o acumular el rango con Union y borrar una sola vez. Añadir una salvaguarda de iteraciones máximas en bucles Do y probar con conjuntos de datos pequeños y vacíos.
Llamar a un procedimiento con paréntesis cuando no se usa Call ni se asigna el resultado, o pasar argumentos ByRef esperando que el original no cambie.
El candidato confunde la sintaxis de Function con la de Sub y desconoce que en VBA los argumentos son ByRef por defecto, por lo que el procedimiento llamado puede modificar la variable del llamador.
What to do instead
Usar Call MiSub(a, b) o MiSub a, b sin paréntesis en Sub; con paréntesis solo al asignar el valor de una Function. Declarar explícitamente ByVal en los argumentos que no deban modificarse y ByRef cuando se quiera devolver un valor por referencia.
Omitir On Error y dejar que un error de ejecución (por ejemplo, división por cero o una hoja inexistente) detenga la macro con el cuadro de diálogo modal, o usar On Error Resume Next de forma global y ocultar fallos reales.
El candidato escribe el camino feliz y no planifica los fallos; además, Resume Next sin comprobar Err.Number después de cada operación crítica enmascara el problema en lugar de gestionarlo.
What to do instead
Estructurar con On Error GoTo Manejador, etiquetar el bloque de salida con Exit Sub/Function y en el manejador registrar Err.Number y Err.Description. Si se usa Resume Next, comprobar If Err.Number <> 0 Then justo después y limpiar con Err.Clear. Restaurar On Error GoTo 0 al final.
No limpiar el estado al depurar: dejar activado el modo interrumpido, no restablecer Application.ScreenUpdating, EnableEvents o Calculation al salir, y no poder reproducir el error porque la macro se detiene en un punto distinto.
El candidato usa F8 y puntos de interrupción pero no cierra la sesión de depuración con Restablecer; los cambios de estado global de Excel persisten y afectan a ejecuciones posteriores.
What to do instead
Guardar los valores originales en variables al inicio y restaurarlos en el manejador de errores y en la salida normal (ScreenUpdating = True, EnableEvents = True, Calculation = xlCalculationAutomatic). Pulsar Restablecer (F5 con el botón de detener) antes de cada prueba y usar Debug.Print o la ventana Inmediato para trazar valores.
Escribir controladores de eventos en el módulo equivocado o con la firma incorrecta (por ejemplo Private Sub Worksheet_Change sin el parámetro Target, o en un módulo estándar), y luego extrañarse de que no se disparen.
El candidato no distingue entre eventos de hoja, de libro y de controles de formulario, ni sabe que la firma y el módulo de objeto son obligatorios para que Excel enlace el evento.
What to do instead
Seleccionar la hoja o ThisWorkbook en el Explorador de proyectos, elegir el objeto en la lista izquierda del editor y el evento en la derecha para que VBA genere la firma correcta. En Worksheet_Change, desactivar EnableEvents antes de escribir en la hoja y reactivarlo después para evitar recursión; validar Target con Intersect.