Looking at your code snippet, I am assuming that you are using fullscreen mode.
One way of solving it would be to store user command in global variable and firing next ALV in START-OF-SELECTION block, and not from inside existing ALV.
In START-OF-SELECTION, you can set user status and do this:
DO.
CASE g_ucomm.
WHEN 'DEMO'.
PERFORM display_alv_output USING it_demo[] 'D'.
WHEN 'EMPL'.
PERFORM display_alv_output USING it_empl[] 'EM'.
WHEN 'ERROR'.
PERFORM display_alv_output USING it_error[] 'ER'.
ENDCASE.
IF sy-ucomm EQ '&F03'. "exit infinite loop on back button
EXIT.
ENDIF.
ENDDO.
The infinite loop will end when Back button is pressed. When EMPL button is pressed, exiting ALV processing will end, and then next ALV will be called.
In subroutine user_command, you can just store ucomm to global variable.
FORM user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.
CASE g_ucomm.
WHEN 'DEMO' OR 'EMPL' OR 'ERROR'.
g_ucomm = r_ucomm.
LEAVE TO SCREEN 0.
WHEN OTHERS.
CLEAR g_ucomm.
ENDCASE.
ENDFORM. "user_command