Cómo hacer editable o no un campo en ALV según su contenido

A veces necesitas que el usuario pueda editar un campo del ALV solo si está vacío, pero que quede bloqueado una vez tiene un valor (o viceversa). En ALV Grid, esto se consigue definiendo estilos por celda mediante el campo stylefname del layout y una tabla interna de estilos.

Paso 1: Estructura de datos con campo de estilos

Tu tabla interna debe incluir un campo adicional de tipo LVC_T_STYL (tabla de estilos por celda).

TYPES: BEGIN OF gs_data,
matnr TYPE matnr, " Campo a controlar
cellstyles TYPE lvc_t_styl, " ← campo para estilos
END OF gs_data.

DATA: gt_data TYPE TABLE OF gs_data.

Paso 2: Configurar el layout del ALV

Indica al ALV qué campo contiene los estilos. Importante que esté en mayúsculas.

DATA: ls_layout TYPE lvc_s_layo.

ls_layout-stylefname = 'CELLSTYLES'. " Nombre del campo de estilos

Paso 3: Definir la lógica de edición

En un formulario, recorre la tabla y asigna el estilo a cada celda según el valor del campo.

FORM set_cell_styles.
DATA: ls_style TYPE lvc_s_styl,
lt_styles TYPE lvc_t_styl.

LOOP AT gt_data ASSIGNING FIELD-SYMBOL(<ls_data>).
CLEAR lt_styles.

ls_style-fieldname = 'MATNR'.
IF <ls_data>-matnr IS INITIAL.
ls_style-style = cl_gui_alv_grid=>mc_style_enabled. " Editable
ELSE.
ls_style-style = cl_gui_alv_grid=>mc_style_disabled. " No editable
ENDIF.

APPEND ls_style TO lt_styles.
<ls_data>-cellstyles = lt_styles.
ENDLOOP.
ENDFORM.

Paso 4: Activar los estilos en el ALV

Después de llenar la tabla y antes de mostrarla, llama al formulario:

PERFORM set_cell_styles.

" Mostrar ALV (con CL_GUI_ALV_GRID)

Si el usuario edita datos y cambia el valor de MATNR (por ejemplo, lo rellena), deberás refrescar los estilos para que el campo quede bloqueado. Para ello, vuelve a llamar a set_cell_styles y luego actualiza la visualización:

CALL METHOD alv_grid->refresh_table_display.

Aunque una buena práctica sería no recorrer la tabla entera cada vez que se refresca si tiene muchos registros. Podemos optimizarlo actualizando solo las filas modificadas.

Controlar la edición de una celda según su contenido es muy útil para evitar que el usuario modifique datos ya establecidos. Con un campo de estilos y la lógica adecuada, puedes habilitar o deshabilitar la edición dinámicamente en tiempo de ejecución.