Buenas prácticas al programar en ABAP

Programar en ABAP no es solo hacer que algo funcione… también es hacer que sea entendible, fácil de mantener y sin dolores de cabeza para el próximo que lo toque (o tú mismo dentro de dos meses). Aquí te dejo buenas prácticas esenciales que todo ABAPer debería aplicar.

🧠 Nombres claros > nombres cortos

Usar nombres significativos para variables, clases y métodos es fundamental para que cualquier persona (o tú mismo en el futuro) entienda el código sin esfuerzo.

ObjetoIncorrectoCorrecto
ProgramaZR1ZSD_LISTADO_PEDIDOS
ClaseZCL1ZCL_GESTION_FACTURAS
VariableLV1LV_TOTAL_IMPORTE

Claves:
✔ Usa nombres descriptivos.
✔ Siempre con prefijo Z / Y si es objeto Z.
✔ El idioma da igual, pero sé consistente (todo en español o todo en inglés).

Convenciones recomendadas:

  • Variables locales: lv_*
  • Variables globales: gv_*
  • Constantes: lc_*
  • Estructuras: ls_*
  • Tablas internas: lt_*
  • Clases: lcl_* (locales), zcl_* (globales)
  • Métodos: get_*, process_*, validate_*

🏗️ Usa el Diccionario ABAP (SE11) siempre que sea posible

Definir tipos de datos, estructuras y tablas en el Diccionario ABAP en lugar de hacerlo directamente en el programa promueve la reutilización y consistencia.

❌ Evita:

DATA: BEGIN OF ls_customer,
        id TYPE i,
        name TYPE string,
      END OF ls_customer.

✅ Mejor:
Crea una estructura ZSTR_CUSTOMER en SE11 y úsala:

DATA ls_customer TYPE zstr_customer.

🚫 No uses números mágicos

Los «números mágicos» son valores literales sin explicación. Usa constantes para darles significado.

❌ Evita:

IF lv_status = 'A'.
  " ... 
ENDIF.

✅ Mejor:

CONSTANTS: lc_status_active TYPE c VALUE 'A'.

IF lv_status = lc_status_active.
  " ...
ENDIF.

📏 Modulariza tu código

Divide programas grandes en módulos de función, clases o métodos. Esto hace el código más testeable y mantenible. Evita programas de 1000 líneas con todo en un solo bloque.

Optimiza el acceso a bases de datos

Las operaciones de base de datos son costosas. Sigue estas reglas:

  • Usa SELECT con WHERE en lugar de leer toda la tabla (a ser posible por los campos claves).
  • Nunca hacer INSERT, MODIFY o UPDATE por cada registro en un LOOP salvo que sea estrictamente necesario. Mejor añadir a una tabla interna y hacer INSERT ztab FROM TABLE it_tab. o MODIFY ztab FROM TABLE it_tab.
  • Evita SELECT dentro de bucles.
  • Evita LOOP dentro de otro LOOP. Sustituir por READ TABLE ... WITH KEY sobre tablas hashed/sorted o usar índices en tablas internas.
  • Usa FOR ALL ENTRIES con precaución (verifica que la tabla no esté vacía), o si tu versión de SAP lo permite INNER JOIN
  • Prefiere JOIN sobre múltiples SELECT simples.
  • No uses SELECT * salvo que necesites todas las columnas.

❌ Evita:

LOOP AT lt_orders INTO ls_order.
  SELECT SINGLE * FROM vbap INTO ls_vbap 
    WHERE vbeln = ls_order-vbeln.
ENDLOOP.

✅ Mejor:

IF lt_orders IS NOT INITIAL.
SELECT * FROM vbap INTO TABLE lt_vbap
FOR ALL ENTRIES IN lt_orders
WHERE vbeln = lt_orders-vbeln.
ENDIF.

⚡ FOR ALL ENTRIES vs INNER JOIN (¿cuál es mejor y cuándo?)

Opción¿Cuándo usarla?VentajasProblemas
INNER JOINSiempre que las tablas tengan relación directa y estés en SAP 7.4+Más rápido, menos memoria, se ejecuta en la base de datosNo puedes hacer lógica compleja entre tablas
FOR ALL ENTRIESCuando no puedes usar joins (tablas sin relación en diccionario)Flexible⚠️ Si la tabla está vacía → devuelve TODOS los registros. Más lenta.
LEFT OUTER JOINMostrar datos de tabla principal aunque no haya correspondencia (ej: pedidos sin posiciones)Lo más usado en SAPMejor que FOR ALL ENTRIES en la mayoría de escenarios

🛑 Verifica siempre sy-subrc después de READ TABLE

Cuando trabajas con tablas internas, nunca asumas que el registro que buscas va a existir. Siempre verifica el código de retorno sy-subrc para evitar errores en tiempo de ejecución.

❌ No hagas esto:

READ TABLE lt_customers INTO ls_customer WITH KEY id = lv_customer_id.
lv_name = ls_customer-name. " ¡Posible dump!

✅ Mejor haz esto:

READ TABLE lt_customers INTO ls_customer WITH KEY id = lv_customer_id.
IF sy-subrc <> 0.
" Registro NO encontrado - maneja el error
MESSAGE e001(z_custom) WITH lv_customer_id.
RETURN.
ENDIF.
" Registro encontrado - procede con seguridad
lv_name = ls_customer-name.

🧹 Limpia tu código: elimina código comentado y muerto

El código comentado o que nunca se ejecuta solo genera confusión. Intenta eliminarlo para dejar el código lo más limpio posible.

✔ Elimina código comentado que ya no se utiliza
✔ Indenta correctamente
✔ No dejes BREAK-POINT ni WRITE en productivo
✔ Usa SLIN o ATC para detectar errores y mejoras

💬 Mensajes y textos (no hardcodear)

  • Usa Message Classes (SE91) y Text Elements. Esto facilita traducción, cambios y consistencia.
  • Para textos en programas: TEXT-001 o TEXT-010 (Text Symbols) según convenga.

Ejemplo:

MESSAGE e001(zmm_mensajes) WITH lv_pedido.

🛡️ Manejo de errores

Usa bloques de manejo de excepciones y comprueba los resultados de las operaciones críticas.

❌ Evita:

CALL FUNCTION 'Z_FUNCION_IMPORTANTE'.

✅ Mejor:

CALL FUNCTION 'Z_FUNCION_IMPORTANTE'
  EXCEPTIONS
    error_occurred = 1
    OTHERS         = 2.

IF sy-subrc <> 0.
  " Manejar el error
ENDIF.

Para clases, usa el manejo de excepciones orientado a objetos:

TRY.
    lo_object->process_data( ).
  CATCH zcx_my_exception INTO lo_ex.
    " Manejar excepción
ENDTRY.

📋 Documenta, pero no exageres

La documentación debe explicar el «porqué», no el «qué». El código ya dice lo que hace. Usa comentarios para:

  • Explicar decisiones técnicas complejas
  • Documentar parámetros en métodos y funciones
  • Indicar por qué se hace algo de cierta manera

⚙️Estructura recomendada para reportes

En programas con SE38:

IncludePara…
ZPROG_TOPData, types, constantes
ZPROG_SELPantalla de selección (PARAMETERS, SELECT-OPTIONS)
ZPROG_F01Subrutinas o formularios

Esto mantiene el programa limpio y escalable.

Estas prácticas no son teoría, son cosas que evitan dumps, descuadres en productivo y llamadas de madrugada. Si las aplicas, tu código será:

✔ Más rápido
✔ Más fácil de mantener
✔ Más profesional

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *