miércoles, octubre 24, 2007

DUMP Error DBIF_RSQL_INVALID_RSQL RSQL error 13 when accessing table

El otro día me apereció en siguiente DUMP:

"Error DBIF_RSQL_INVALID_RSQL RSQL error 13 when accessing table".

Esto resulta de realizar una consulta SELECT a la Base de datos con una variable de tipo SELECT-OPTIONS muy grande. Como solución se propener dividir esta variable en partes. Para ello se crearan variables auxilixares de tipo RANGES, que son del mismo tipo que los SELECT-OPTION. De hará un bucle y se utilizará el comando APPENDING en el SELECT para ir guardando los valores.

miércoles, octubre 17, 2007

Ficheros Mostrar ventana para seleccionar fichero local

Por lo menos tenemos dos módulos de funcion que realizan la operación:

1) Ventana escogiendo local/servidor: F4_DXFILENAME_TOPRECURSION.
2) Fichero Local: método cl_gui_frontend_services=>file_open_dialog
3) Fichero Servidor: MF 'F4_DXFILENAME_TOPRECURSION' con i_location_flag = A
4) MF ISH_N2_FILENAME_GET

Los tres MF los debemos llamar en el evento:
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_path.

Además p_path ha de ser del tipo rlgrap-filename.

Ojito porque si la ruta es muy larga no se actualiza correctamente el parámetro de la pantalla de selección.

lunes, octubre 08, 2007

Debugger programa en proceso de fondo

Para debuggear un programa lanzado en fondo realizar las siguientes operaciones.
1)Ejecutar Tx. SM50
2)Seleccionar work process.
3)Menú 'Programa/Modo'->'Programa'->'Debugging'.

ALV - Trabajar con variantes de ALV

Mostrar un campo en la pantalla de selección para seleccionar una variante previamente guardada.

1) Crear variables:
DATA: ls_variant TYPE disvariant.
PARAMETERS p_dispo LIKE disvariant-variant.

2) Mostrar matchcode variantes
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_dispo.
MOVE: p_dispo TO ls_variant-variant,
sy-repid TO ls_variant-report.

CALL FUNCTION 'REUSE_ALV_VARIANT_F4'
EXPORTING
is_variant = ls_variant
IMPORTING
es_variant = ls_variant
EXCEPTIONS
not_found = 1
program_error = 2
OTHERS = 3.

MOVE ls_variant-variant TO p_dispo.

3)Indicar variante al mostrar ALV
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
is_variant = ls_variant

jueves, septiembre 20, 2007

ERROR - Capturar excepciones

Para evitar que se produzan DUMP's (casos inevitables) se utiliza el comando TRY/ENDTRY.
Ejemplo sencillo: 'Hacer una consulta a una tabla de la BD y se produzca overflow"
TRY.
SELECT .......

CATCH cx_sy_open_sql_db.
MESSAGE i098(z40pp) WITH 'Select con demasiados registros'.
EXIT.

ENDTRY.

miércoles, septiembre 19, 2007

Crear un nuevo modo

Hay la posibilidad de que cuando se este ejecutando un programa se abra un nuevo modo independiente al modo inicial (cada uno se ejecuta por separado). Tenemos que realizar 3 operaciones.

- Crear un nuevo módulo de función que contenga la lógica del programa que queremos que se ejecute en el nuevo modo.

- Modificar los atributos del módulo de función para que se pueda llamar en un nuevo modo. En el recuadro 'Forma Ejecución' seleccionar radiobutton 'Módulo de acceso remoto'.

- Realizar la llamada al módulo de función añadiendo sentencia IN NEW TASK.
CALL FUNCTION 'nombre_modulo_funcion' STARTING NEW TASK 'nombre_tarea'.
El nombre de la tarea tiene que se como máximo de 3 letras.

lunes, septiembre 03, 2007

DYNPRO - pantallas

Para volver a la pantalla inicial:
- LEAVE TO SCREEN 0.
- SET SCREEN 0. "Puntero
LEAVE SCREEN.

Para terminar programa :
- LEAVE PROGRAM.

CALL SCREEN -> va guardando ciclo. Se llega a un tope.

miércoles, julio 25, 2007

DYNPRO - Textos

La primera idea que nos viene a la cabeza cuando queremos guardar texto es crear un campo de char255 en una tabla Z. Pero no se mantendría el formato (negrita, cursiva, salta de línea). Para resolver este problema se pueden utilizar los textos de sap.

Los diferentes id de textos se guardan en la tabla TTXID.

1) Configurar Texto nuevo Tx. SE75.

Si vamos a la sm30 hay un botón donde para buscar pasos en el Customizing que trabajen con esta tabla. Debemos buscar una descripción parecida a 'Definir ID de texto'. Aquí crearemos nuestros objetos y clases nuevas. Previamente hay que buscar un tipo de objeto al que queremos añadir los nuevos ID's.

2) Inicializar variables
IF NOT cc_org IS INITIAL.
CALL METHOD cc_org->free.
ENDIF.

IF NOT txtedit_nota IS INITIAL.
CALL METHOD txtedit_nota->free.
ENDIF.

3) Recuperar Texto.

Programa Control =>
DATA: cc_nota TYPE REF TO cl_gui_custom_container.
DATA: txtedit_nota TYPE REF TO cl_gui_textedit.
************************************************************************************
PBO
************************************************************************************
* Crear CUSTOM-CONTROL
IF cc_nota IS INITIAL.

CREATE OBJECT cc_nota
EXPORTING
container_name = 'CC_TEXTO' "Nombre del custom control del Dynpro
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
others = 6.

ENDIF.

* Asignarle edición de texto
IF txtedit_nota IS INITIAL.

CREATE OBJECT txtedit_nota
EXPORTING
wordwrap_mode = 2
wordwrap_position = 72
parent = cc_nota
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
gui_type_not_supported = 5
others = 6.

* Quitar botones
CALL METHOD txtedit_nota->set_toolbar_mode.
CALL METHOD txtedit_nota->set_statusbar_mode.
PERFORM llenar_texto.
ENDIF.

* Visualizar/Modificar
IF action EQ 'DISP'.
CALL METHOD txtedit_nota->set_readonly_mode
EXPORTING
readonly_mode = '1'.
ELSE.
CALL METHOD txtedit_nota->set_readonly_mode
EXPORTING
readonly_mode = '0'.
ENDIF.

****************************************************************************
Rutina=> PERFORM llenar_texto.
****************************************************************************
DATA: w_header TYPE thead,
t_tline TYPE TABLE OF tline,
w_tline TYPE tline,
t_texto TYPE TABLE OF char255.

w_header-tdobject = 'FORMMAT'.
w_header-tdname = zwf_mat_alta_dg-formnumber.
w_header-tdspras = sy-langu.

CALL FUNCTION 'READ_TEXT'
EXPORTING
id = w_header-tdid "Tipo de texto
language = w_header-tdspras "Idioma
name = w_header-tdname "Id del texto
object = w_header-tdobject "Nombre del objeto
TABLES
lines = t_tline
EXCEPTIONS
id = 1
language = 2
name = 3
not_found = 4
object = 5
reference_check = 6
wrong_access_to_archive = 7
OTHERS = 8.

*Copiar texto con formato a sólo texto
LOOP AT t_tline INTO w_tline.
APPEND w_tline-tdline TO t_texto.
ENDLOOP.

* Guardar texto en objeto
CALL METHOD txtedit_nota->set_text_as_r3table
EXPORTING
table = t_texto
EXCEPTIONS
error_dp = 1
error_dp_create = 2
OTHERS = 3.

3) Guardar texto.
DATA: w_header TYPE thead,
t_tline TYPE TABLE OF tline,
w_tline TYPE tline,
t_texto TYPE TABLE OF char255,
w_texto TYPE char255.

CLEAR w_header.
w_header-tdobject = 'FORMMAT'.
w_header-tdname = zwf_mat_alta_dg-formnumber.
w_header-tdspras = sy-langu.
w_header-tdid = 'DG'. " texto datos generales

* Eliminar texto anterior
CALL FUNCTION 'DELETE_TEXT'
EXPORTING
id = w_header-tdid
language = w_header-tdspras
name = w_header-tdname
object = w_header-tdobject
EXCEPTIONS
not_found = 1
OTHERS = 2.

* Recuperar texto de la pantalla
CALL METHOD txtedit_nota->get_text_as_r3table
IMPORTING
table = t_texto.

LOOP AT t_texto INTO w_texto.
w_tline-tdformat = '*'.
w_tline-tdline = w_texto.
APPEND w_tline TO t_tline .
ENDLOOP.

* Guardar texto nuevo
CALL FUNCTION 'SAVE_TEXT'
EXPORTING
header = w_header
TABLES
lines = t_tline
EXCEPTIONS
id = 1
language = 2
name = 3
object = 4
OTHERS = 5.

CALL FUNCTION 'COMMIT_TEXT'.

* Para deshabilitar el scroll horitzontal al realizar el CREATE OBJECT informar         wordwrap_mode              = cl_gui_textedit=>wordwrap_off

miércoles, julio 18, 2007

TC - TABLE CONTROL

Este es un de los temas que menos me apasiona pero me gustaría hacer unos comentarios. Como ejemplo en hay los programas DEMO_DYNPRO_TABCONT_LOOP y demo_dynpro_tabcont_loop_at.

1) En un DYNPRO podemos tener varios TABLE CONTROL (TC). Comentar que a la hora de crear el segundo TC no funciona correctamente el asistente por la tanto se deberá utilizar la técnica de copy&paste. También tenemos que ir con ojo a la hora de tratar 2 TC en el PBO,
primer tratar el TC que este más abajo, y así hasta el primero.

2) Eliminar barra de SCROLL HORIZONTAL. Rellenar el atributo Col.fijas del TC en el editor de SCREEN PAINTER.

3) Eliminar barra de SCROLL VERTICAL. Ajustar tamaño TC en el editor de SCREEN PAINTER para mostrar el núm. de registros y modificar atributo del TC lines= 0.

4) Actualización de los registros del TC. El modify que automáticamente se realiza no funciona correctamente, se debe modificar la condición. Probar de modificar registro de la tabla y en caso de que no exista crearlo.

5) SY-TCODE del SCROLL. Al utilizar el SCROLL se pasa por el PAI. En la rutina se chequea el valor del ok-code (variable que le hemos asignado al DYNPRO para que nos retorna la función ejecutada). Es este caso el valor ok-code no se actualiza y tiene el valor de la última operación ejecutada, por lo tanto se debe de limpiar la variable ok-code. El scroll es realizado por el estandard.

6) Mediante las instrucciones GET CURSOR y SET CURSOR podemos movernos por el TABLE CONTROL. Esto es muy útil cuando el usuario esta utilizando el SCROLL y queremos que visualice el mismo trozo de pantalla.
-> GET CURSOR field gv_field LINE gv_line. Obtenemos la fila y columna donde tenemos el cursor. Se debe ejecutar en el PAI. Es recomendable que borremos el valor de la dos variables antes de ejecutar la sentancia
-> SET CURSOR FIELD gv_field line gv_line. Se ejecuta en el PBO. Se tendría que chequear que fueran correctos los valores de la variables.

5) A la hora de modificar el tamaño del TC hay que vigilar que el atributo resizing no esté activado. Si está activado es el propio SAP quien decide cuantos registros mostrar.

6) Para añadir un nueva linea en blanco se hace un DESCRIBE TABLE de la tabla y campo TC-lines = sy-tfill + 1. Después habría que desplazarse hasta la nueva linea.

7) Para habilitar/deshabilitar columnas realizar MODULE en el PBO después del LOOP AT ... WITH CONTROL.

8) Para habilitar/deshabilitar files, añadir código dentro del LOOP AT ... WITH CONTROL.
Por ejemplo:
LOOP AT SCREEN.
IF screen-name(3) EQ 'LIN' AND
screen-name NE 'LIN-POSTC' AND
screen-name NE 'LIN-MAKTX' AND
screen-name NE 'LIN-AGRUP' AND
screen-name NE 'LIN-CHECK'.
screen-input = 1.
ENDIF.
ENDLOOP.

9) Para indicar la selección de un registro, informar flag c.marc.col. y poner el campo que indique la marcar G_WA-CHECK.

miércoles, junio 13, 2007

Añadir botones en el Status de un Report

En un principio pensaba que para añadir botones a la barra se tenia que trabajar con DYNPROS y currartelo, pero acabo de darme cuenta que hay otra manera más rápida.
Creamos un elemento en nuestro SCREEN : SELECTION-SCREEN FUNCTION KEY 1.
Le debemos de asignar un numero de 1 al 5.

En evento de INITIALIZATION le ponemos un texto o un icono. MOVE 'My text' TO sscrfields-functxt_01.

Después captamos los captamos con el evento at selection-screen (los valores de sy-ucomm pueden ir de FC01 al FC05.

Comentario: debemos crear un work area para TABLES sscrfields (tienes los atributos).

Añadir parametros de selección en un MODUL-POOL

Cuando se trabaja con un programa del tipo report es muy fácil crearte una pantalla de selección con los comandos PARAMETERS y SELECT-OPTION. ¿Pero que pasa cuando trabajamos con DYNPROS?

Para ello tambien utilizamos comandos PARAMETERS y SELECT-OPTION. y lo asignamos a un nombre.
SELECTION-SCREEN BEGIN OF SCREEN nombre AS WINDOW TITLE text-460.

Después dentro del DYNPRO lo llamamos.
CALL SELECTION-SCREEN nombre STARTING AT 20 5.

Añadir botones estandard a nuestro STATUS

A la hora de crear un STATUS, nos puede interesar reutilizar algunos botones del estandard además de los nuestros propios, para ello deberemos seguir la siguiente ruta una vez que estemos en la TX del menu painter se41.

Detalles->Ajustar Modelo-> List Viewer ABAP

jueves, marzo 08, 2007

DYNPRO con AT EXIT-COMMAND

En la lógica de los DYNPROS, muchas veces nos puede interesar terminar la ejecución del programa al realizar una acción (como por ejemplo presionar un botón). Imaginad que tenemos un dynpro donde es obligatorio rellenar un campo. En el PAI tenemos una module que hace la comprobación. Probad a presionar el botón de cancelar de vuestro dynpro sin rellenar el campo obligatorio ¿Que pasa? Que a pesar que queremos salir del programa el PAI se ejecuta y se muestra un mensaje diciendo que es obligatorio informar el campo, pero lo que nos interesa a nosotros es salir del programa y no nos importar el valor de ningún campo. Para hacer que al apretar el botón cancele de todas formas se debe hacer dos pasos:

- Crear un module dentro del PAI que salga del programa (dentro del module hacemos LEAVE PROGRAM). En la llamada al module debemos añadir el siguiente texto AT EXIT-COMMAND.

-Asignar al botón un tipo de función 'Comando Exit'. Para esto vamos al status del dynpro y escogemos el tipo E en las características del botón.

lunes, marzo 05, 2007

Objetos locales

Nos puede interesar crear algún objeto (report, dynpro, TX) de manera temporal, es decir, no nos interesa añadirlo a una Orden de Transporte puesto que no se va a Transportar en ningún sistema (sólo pruebas) .
En este caso el objeto se guarda como objeto temporal, dentro del paquete $TMP. Si alguna vez queremos añadir a otra orden de transporte deberemos ir a la 'Entrada del catálogo de objetos y modificar su paquete por otro que si este previsto transportar. Con la Transacción SE80 se puede trabajar con los paquetes (crear, modificar, visualizar, eliminar).

martes, febrero 27, 2007

DICC - Crear ayuda F1 en un parámetro Z

Al trabajar con reports, muchas ocasiones la primera pantalla es de selección de datos. Al crear los datos de la pantalla de selección tenemos dos maneras:
1-Crear los parámetros en referencia a un tipo de dato standard de SAP.
2-Crear los parámetros en referencia a un tipo de dato Z que hayamos creado anteriormente.

En el primer caso, al llamar a la ayuda (F1) se muestra la ayuda del diccionario. En el segundo caso no hay ayuda pero nosotros la podemos crear. Para ello vamos por medio del diccionario SE11 al tipo de dato y después apretamos al botón de documentación. En la siguiente pantalla podremos añadir nuestra propia explicación del campo.

jueves, febrero 08, 2007

Modificación de valores de tablas del standard

Muchas veces nos interesa modificar algún registro que tenemos guardado en una tabla standard de SAP. Hay diferentes caminos:

1) Ver el registro en modo visualización. Después activamos el Debugguer y modificamos el valor de la varible 'CODE' con 'EDIT'.

2) Hacer una consulta desde un Report mediante OPEN SQL desde la SE38.

3) Puede darse el caso que el propio editor se38 no permita realizar modificaciones, es este caso podemos utilizar NATIVE SQL.

EXEC_SQL.
consulta/modificación
ENDEXEC.

Para acceder a las tablas de SAP utilizando NATIVE SQL ponemos 'SAPR3.Nombre_tabla'.

Conexión de SAP con el exterior

SAP tiene actualmente el Módulo XI para conectar su software con el exterior. Ya puede ser otro servidor SAP como otra aplicación NO-SAP. Anteriormente había el Business Conector, que había sido creado por otra empresa diferente de SAP. Era gratuito. Pero con el tiempo SAP decidió comercializar su producto XI y dejar el resto.

Modificaciones del standard

Alguna veces es inevitable la necesidad de modificar el standard. En estos casos haremos:

1) Si intentamos modificar un elemento standard (report, include, transacción, etc..) se abre una ventana donde el sistema nos pide un código para poder continuar con la modificación.

2) Debemos conectarnos a la página web service.sap.com con un login y un password (cliente).

3) Navegamos por la pestaña 'Keys & Request' y después por la pestaña 'SSCR Keys register objects'.

4) Al registrar el objeto en la web nos retornará una CLAVE que deberemos poner en la ventana.

Listbox

Para crear un listbox debemos insertar un campo del tipo desplegable 'Listbox' en nuestra DYNPRO. En el PBO ( o evento AT SELECTION-SCREEN OUTPUT), debemos utilizar el módulo de función VRM_SET_VALUES con la tabla que contiene los valores (ID y Texto) que se deberá haber rellenado antes. Tienes que declaro pool de tipos TYPE-POOLS: vrm. Además el campo PARAMETERS debe ser listbox y visible con una longitud ( as LISTBOX VISIBLE LENGTH 6 ).

También tenemos la función VRM_GET_VALUES para recuperar los valores o sino accediendo directamente al parámetro p_funint.


PARAMETERS: p_funint TYPE crmt_partner_fct AS LISTBOX VISIBLE LENGTH 30.
DATA: it_vrm TYPE vrm_values.
DATA: wa_vrm TYPE LINE OF vrm_values.
DATA: gv_name TYPE vrm_id VALUE 'P_FUNINT'.
*************************************************************************
AT SELECTION-SCREEN OUTPUT.
**************************************************************************
SELECT partner_fct AS key description AS text
FROM crmc_partner_ft
INTO CORRESPONDING FIELDS OF TABLE it_vrm
WHERE spras EQ sy-langu.

CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
id = gv_name
values = it_vrm.

miércoles, enero 31, 2007

Ocultar elementos dynpro según RADIOBUTTON

Al estar trabajando con dynpros nos puede interesar mostrar o ocultar algunos campos. En este caso queremos mostrar/esconder los campo dependiendo del valor del un RADIOBUTTON. Para ello primero asignamos todos los elementos que queramos mostrar/esconder a un grupo que después modificaremos recorriendo la tabla con los elemenos LOOP AT SCREEN.

Para que actualizar la pantalla sólo cambiando de radibutton (sin tener que ejecutar ENTER), debemos indicarselo de la siguiente manera:
PARAMETERS: p_rad RADIOBUTTON GROUP grupo_bloque USER-COMMAND grupo_enter.

NOTA: Si todos los elementos de un mismo bloque estan inactivos, no se muestra su recuadro.

viernes, enero 05, 2007

Creación de un rango

Hola, algunos os preguntareis ¿Qué es un rango? Es muy fácil : es un contador. La mejor manera de explicarlo es poner un caso que en que es necesario utilizarlo.

Imagina os que hacéis un report que se va a ejecutar varias veces y que en cada ejecución creáis un fichero:
1º Ejecución fichero_1,
2º Ejecución fichero_2
...
nº Ejecución fichero_n.

¿Como podemos enumerar los fichero de manera secuencial (1,2,,,n)? ¿Lo guardamos en una tabla del diccionario?
Aquí es donde surge la necesidad de crear un rango. Mediante la transacción SNUM creamos un rango.Internamente funciona como tener un campo en el diccionario de SAP donde se guarda el contador.

Después se debe crear un intervalo donde hay que indicar:

-Núm. intervalo (identificador).
-Cota inferior.
-Cota superior.
-Núm. actual del contador.

Una vez creado el rango con un intervalo realizamos la llamadas en el programa de control:

1) Bloquear el rango para nuestra utilización,
CALL FUNCTION 'NUMBER_RANGE_ENQUEUE'.
2) Obtener el siguiente número del rango,
CALL FUNCTION 'NUMBER_GET_NEXT'
3) Desbloquear rango,
CALL FUNCTION 'NUMBER_RANGE_DEQUEUE'

Ojo!!! Los intervalos son independientes de mandante.

Además existe otro módulo de función para recuperar el rango sin incrementarlo:
NUMBER_GET_INFO