Archivo
GOS – Crear Anexo/URL en MIR7/MIRO
Caso: Se desea grabar una URL en documentos factura de la MIR7 o MIRO, utilizando la función del botón GOS (Generic Object Services).
Solución: obtenido del blog que indico abajo, definimos una función que contiene la lógica.
1. Ingresar a la SE37 y crear la función:
- attc1c1a
- attc1c1b
FUNCTION zbc_gos_create_url. *"---------------------------------------------------------------------- *"*"Interfase local *" IMPORTING *" REFERENCE(I_OBJECTTYPE) LIKE BORIDENT-OBJTYPE *" REFERENCE(I_OBJECTKEY) LIKE BORIDENT-OBJKEY *" REFERENCE(I_URL) LIKE SOLI-LINE *" REFERENCE(I_URLDES) LIKE SOOD1-OBJDES *" REFERENCE(I_NOCOMMIT) TYPE XFELD *" TABLES *" OT_RETURN STRUCTURE BAPIRET2 *"---------------------------------------------------------------------- * *local data definitions. DATA: l_owner LIKE soud-usrnam, l_folderid LIKE soodk, l_obj_id LIKE soodk, l_objdata LIKE sood1, lt_objcont TYPE TABLE OF soli WITH HEADER LINE, lt_objhead TYPE TABLE OF soli WITH HEADER LINE, l_object LIKE borident, l_reldoc LIKE borident, l_syst LIKE syst. *----------------------------------------------------------------------- * *1.GET folder id. l_owner = sy-uname. CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET' EXPORTING owner = l_owner region = 'B' IMPORTING folder_id = l_folderid EXCEPTIONS communication_failure = 1 owner_not_exist = 2 system_failure = 3 x_error = 4 OTHERS = 5. IF sy-subrc <> 0. l_syst = syst. PERFORM collect_message USING ot_return l_syst '1.FolderRoot'. APPEND ot_return. EXIT. ENDIF. *2. INSERT object l_objdata-objla = sy-langu. l_objdata-objdes = i_urldes. l_objdata-objsns = 'O'. CONCATENATE '&KEY&' i_url INTO lt_objcont. APPEND lt_objcont. CALL FUNCTION 'SO_OBJECT_INSERT' EXPORTING folder_id = l_folderid object_type = 'URL' object_hd_change = l_objdata owner = l_owner IMPORTING object_id = l_obj_id TABLES objcont = lt_objcont objhead = lt_objhead EXCEPTIONS active_user_not_exist = 1 communication_failure = 2 component_not_available = 3 dl_name_exist = 4 folder_not_exist = 5 folder_no_authorization = 6 object_type_not_exist = 7 operation_no_authorization = 8 owner_not_exist = 9 parameter_error = 10 substitute_not_active = 11 substitute_not_defined = 12 system_failure = 13 x_error = 14 OTHERS = 15. IF sy-subrc <> 0. l_syst = syst. PERFORM collect_message USING ot_return l_syst '2.ObjectInsert'. APPEND ot_return. EXIT. ENDIF. *3. CREATE binary relation l_object-objkey = i_objectkey. l_object-objtype = i_objecttype. CONCATENATE l_folderid l_obj_id INTO l_reldoc-objkey. l_reldoc-objtype = 'MESSAGE'. CALL FUNCTION 'BINARY_RELATION_CREATE' EXPORTING obj_rolea = l_object obj_roleb = l_reldoc relationtype = 'URL' EXCEPTIONS no_model = 1 internal_error = 2 unknown = 3 OTHERS = 4. IF sy-subrc <> 0. l_syst = syst. PERFORM collect_message USING ot_return l_syst '3.BinaryRelationCreate'. APPEND ot_return. EXIT. ENDIF. *4. commit luw * all successful, sent success message. CLEAR: l_syst-msgid, l_syst-msgno. l_syst-msgty = 'S'. l_syst-msgv1 = 'Like creado OK'. PERFORM collect_message USING ot_return l_syst '4. URLLinkCreated'. APPEND ot_return. IF i_nocommit IS INITIAL. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'. ENDIF. ENDFUNCTION.
- Creamos un include en el grupo de funciones donde creamos la función y agregamos la visualización del mensaje:
*----------------------------------------------------------------------* ***INCLUDE LZMM_FACT_PROVEEDORESF01 . *----------------------------------------------------------------------* *&---------------------------------------------------------------------* *& Form COLLECT_MESSAGE *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* FORM collect_message USING o_return LIKE bapiret2 i_syst LIKE syst i_callpoint LIKE bapiret2-parameter. * CLEAR o_return. o_return-type = i_syst-msgty. IF i_syst-msgty IS INITIAL. o_return-type = 'E'. i_syst-msgty = 'E'. ENDIF. o_return-id = i_syst-msgid. o_return-number = i_syst-msgno. o_return-message_v1 = i_syst-msgv1. o_return-message_v2 = i_syst-msgv2. o_return-message_v3 = i_syst-msgv3. o_return-message_v4 = i_syst-msgv4. o_return-parameter = i_callpoint. MESSAGE ID i_syst-msgid TYPE i_syst-msgty NUMBER i_syst-msgno INTO o_return-message. * ENDFORM. " collect_message
- Finalmente la llamada es:
*&---------------------------------------------------------------------* *& Form CREAR_URL_ADJUNTA *&---------------------------------------------------------------------* * Crea la URL para cada uno de los registros procesados *----------------------------------------------------------------------* FORM crear_url_adjunta. DATA: lv_objecttype LIKE borident-objtype, lv_objectkey LIKE borident-objkey, lv_url LIKE soli-line, lv_urldes LIKE sood1-objdes, lv_nocommit TYPE xfeld, lt_return LIKE bapiret2 OCCURS 0, l_url TYPE smen_buffi-url. * The object type is the same as you are used to in SWO1 (BKPF for FI documents, BUS2081 for incoming invoices (MIROs), BUS2012 for POs and so on. * The object key is the full key of the object (For FI documents, it is the document, company code and year) * The URL is the actual URL that you wish to attach. * The URL description is the name for the URL you see when you display attachments of the object. * The last input parameter controls whether you wish to commit( blank) or not(X). * Messages are returned in tables parameter OT_RETURN. lv_objecttype = 'BUS2081'. CONCATENATE lv_belnr lv_gjahr INTO lv_objectkey. lv_url = 'www.sap.com'. " URL CONCATENATE 'FACTURA #' lv_belnr lv_gjahr INTO lv_urldes SEPARATED BY space. lv_nocommit = space. CALL FUNCTION 'ZBC_GOS_CREATE_URL' EXPORTING i_objecttype = lv_objecttype i_objectkey = lv_objectkey i_url = lv_url i_urldes = lv_urldes i_nocommit = lv_nocommit TABLES ot_return = lt_return. ENDFORM. " CREAR_URL_ADJUNTA
4. En la MIR7, podemos ver el resultado del link agregado:
Fuente: http://subrc0.wordpress.com/2012/11/13/gos-adding-an-external-link-to-an-object/
Encontrar una ampliación a partir del módulo de funciones
Caso: se requiere encontrar una ampliación a partir del módulo de funciones (dato conocido).
Solución:
1. Por la SE16, vamos a la tabla MODSAP y en el campo "MEMBER" indicamos el módulo de funciones
- image0011
- image0021
y vamos a la transacción SMOD con la ampliación encontrada:
2. Sino, por la CMOD,
Ahi ir arriba al menú UTILIDADES – Ampliaciones SAP
Ponemos el Nombre del Paquete (ML)
Lista los EXITs
Texto largo en DYNPRO (TEXTEDIT)
Caso: se requiere crear un POPUP en donde pueda agregar un texto largo, similar al texto libre usado en MM (ej: texto de cabecera en Solicitudes de Pedido, ME51n).
Solución: Usando la clase cl_gui_textedit, vamos a crear una DYNPRO como la de la figura siguiente, que contiene un Custom Container, un botón de volver y otro de grabar datos, además de unos botones estándar que contiene un importar/exportar texto y las funciones de copiar, pegar, etc.
1. Creamos la DYNPRO
Creamos en el Screen Painter una DYNPRO con un Control Custom Container llamado TEXTEDITOR1 y con un botón para volver a la pantalla anterior (VOLVER) y otro para grabar los datos (GRABAR).
2. Armamos el código asociado
CLASS cl_gui_cfw DEFINITION LOAD. DATA: g_editor TYPE REF TO cl_gui_textedit, g_editor_container TYPE REF TO cl_gui_custom_container, g_mytable(line_length) TYPE c OCCURS 0, g_mycontainer(30) TYPE c VALUE 'TEXTEDITOR1'. En la DYNPRO creada (la mía era la 0020): PROCESS BEFORE OUTPUT. MODULE pbo_0020. * PROCESS AFTER INPUT. MODULE user_command_0020. *&---------------------------------------------------------------------* *& Module PBO_0020 OUTPUT *&---------------------------------------------------------------------* MODULE pbo_0020 OUTPUT. IF g_editor IS INITIAL. * Crea el control container CREATE OBJECT g_editor_container EXPORTING container_name = g_mycontainer EXCEPTIONS cntl_error = 1 cntl_system_error = 2 create_error = 3 lifetime_error = 4 lifetime_dynpro_dynpro_link = 5. IF sy-subrc NE 0. * add your handling ENDIF. * TextEdit Control CREATE OBJECT g_editor EXPORTING parent = g_editor_container wordwrap_mode = * cl_gui_textedit=>wordwrap_off cl_gui_textedit=>wordwrap_at_fixed_position * cl_gui_textedit=>WORDWRAP_AT_WINDOWBORDER wordwrap_position = line_length wordwrap_to_linebreak_mode = cl_gui_textedit=>true. REFRESH g_mytable. " Para inicializar la tabla ENDIF. ENDMODULE. " PBO_0020 OUTPUT *&---------------------------------------------------------------------* *& Module PAI_0020 INPUT *&---------------------------------------------------------------------* module user_command_0020 input. g_okcode = sy-ucomm. CLEAR sy-ucomm. CASE g_okcode. WHEN 'BACK' OR 'CANCEL' OR 'EXIT' or 'VOLVER'. CLEAR g_okcode. LEAVE TO SCREEN 0. WHEN 'GRABAR'. * Obtengo la tabla desde el control CALL METHOD g_editor->get_text_as_r3table IMPORTING table = g_mytable. CALL METHOD cl_gui_cfw=>flush EXCEPTIONS OTHERS = 1. IF sy-subrc NE 0. * ENDIF. WHEN 'CARGAR'. * Devuelvo la tabla al control CALL METHOD g_editor->set_text_as_r3table EXPORTING table = g_mytable. ENDCASE. endmodule. " PAI_0020 INPUT
3. Grabamos y recuperamos la info a la base de datos.
En el GRABAR, la tabla con los resultados está en g_mytable, que es una tabla interna char de 256 (luego tendría que grabar eso en la base de datos), asimismo en el CARGAR vemos que levanto el texto para visualizarlo en pantalla.
Algunas funciones útiles SE37
Caso/Solución: listado de funciones útiles en SAP.
|
Enviar Mail simple con SO_DOCUMENT_SEND_API1
Caso: Se desea enviar un mail en formato HTML.
Solución: se define un form ENVIAR_MAIL, que recibe como parámetros una lista de destinatarios y un texto adicional para incluir en el cuerpo del mensaje.
*&———————————————————————*
*& Form ENVIAR_MAIL
*&———————————————————————*
* Envía un aviso al usuario que ejecutó el reporte indicando que el proceso terminó
*———————————————————————-*
FORM enviar_mail USING p_mails TYPE char100 » Destinatarios
p_texto TYPE char255. » Texto dinámico para el cuerpo del mail
DATA: lt_docs TYPE TABLE OF docs,
ls_doc_chng LIKE sodocchgi1,
ld_tab_lines LIKE sy-tabix,
lt_objtxt LIKE solisti1 OCCURS 0 WITH HEADER LINE,
lt_objpack LIKE sopcklsti1 OCCURS 6 WITH HEADER LINE,
ls_body TYPE solisti1,
lt_body TYPE TABLE OF solisti1,
lt_recipients TYPE TABLE OF somlreci1 WITH HEADER LINE,
ls_recipients TYPE somlreci1.
DATA ld_subject(50) TYPE c VALUE ‘Asunto del mail!!!’.
DATA ld_body(255) TYPE c.
DATA lv_sender TYPE soextreci1-receiver.
DATA lv_len TYPE i.
DATA lv_ofset TYPE i.
DATA lv_char(1).
CLEAR: ls_doc_chng, ls_body, lt_recipients, ld_tab_lines, lv_sender.
REFRESH: lt_body, lt_recipients, lt_objpack, lt_objtxt.
*———————————————————————-*
* CONTROL DATA (Datos de cabecera del mail)
*———————————————————————-*
ls_doc_chng-obj_name = ‘URGENT’.
ls_doc_chng-sensitivty = ‘P’.
ls_doc_chng-no_change = ‘X’.
ls_doc_chng-priority = ‘1’.
ls_doc_chng-obj_prio = ‘1’.
ls_doc_chng-obj_langu = sy-langu.
ls_doc_chng-no_change = ‘X’.
*———————————————————————-*
* SUBJECT (Asunto del mail)
*———————————————————————-*
** Email Subject
ls_doc_chng-obj_descr = ld_subject. » Ver variable definida con valor constante arriba
*———————————————————————-*
* BODY (Cuerpo del mail, en HTML)
*———————————————————————-*
CLEAR ls_body.
MOVE ‘<html><body>’ TO ls_body-line.
APPEND ls_body TO lt_body.
CLEAR ls_body.
CONCATENATE ‘<p>’ ‘Resultados de la ejecución del reporte</p>’
INTO ls_body-line.
APPEND ls_body TO lt_body.
CLEAR ls_body.
APPEND ls_body TO lt_body.
CLEAR ls_body.
CONCATENATE ‘<p>’ p_texto ‘</p>’
INTO ls_body-line SEPARATED BY space.
APPEND ls_body TO lt_body.
CLEAR ls_body.
APPEND ls_body TO lt_body.
CLEAR ls_body.
CONCATENATE ‘<p>’ ‘Este correo se ha generado en forma automática, por favor no responder</p>’
INTO ls_body-line SEPARATED BY space.
APPEND ls_body TO lt_body.
CLEAR ls_body.
MOVE ‘</body></html>’ TO ls_body-line.
APPEND ls_body TO lt_body.
* Armo el HTML
lt_objtxt[] = lt_body[].
CLEAR lt_objtxt.
DESCRIBE TABLE lt_objtxt LINES ld_tab_lines.
IF ld_tab_lines GT 0.
READ TABLE lt_objtxt INDEX ld_tab_lines.
ls_doc_chng-doc_size = ( ld_tab_lines – 1 ) * 255 + STRLEN( lt_objtxt ).
CLEAR lt_objpack-transf_bin.
lt_objpack-head_start = 1.
lt_objpack-head_num = 0.
lt_objpack-body_start = 1.
lt_objpack-body_num = ld_tab_lines.
lt_objpack-doc_type = ‘HTM’.
APPEND lt_objpack.
ENDIF.
*———————————————————————-*
*RECIPIENTS (Destinatarios del mail separados por 😉
*———————————————————————-*
lv_sender = ‘aaaa@aaaaa.com’. » Indicar el mail origen
CLEAR lt_recipients.
lv_len = STRLEN( p_mails ). » p_mails tiene direcciones de correo separadas por «;»
DO lv_len TIMES.
lv_ofset = sy-index – 1.
lv_char = p_mails+lv_ofset(1).
CHECK lv_char IS NOT INITIAL.
IF lv_char = ‘;’.
CONDENSE lt_recipients-receiver.
lt_recipients-rec_type = ‘U’.
lt_recipients-rec_date = sy-datum.
APPEND lt_recipients.
CLEAR lt_recipients.
CONTINUE.
ENDIF.
CONCATENATE lt_recipients-receiver lv_char INTO lt_recipients-receiver.
IF lv_len = sy-index.
CONDENSE lt_recipients-receiver.
lt_recipients-rec_type = ‘U’.
lt_recipients-rec_date = sy-datum.
APPEND lt_recipients.
ENDIF.
ENDDO.
CALL FUNCTION ‘SO_DOCUMENT_SEND_API1’
EXPORTING
document_data = ls_doc_chng
put_in_outbox = ‘X’
sender_address = lv_sender
sender_address_type = ‘SMTP’
commit_work = ‘X’
TABLES
packing_list = lt_objpack
contents_txt = lt_objtxt
receivers = lt_recipients
EXCEPTIONS
too_many_receivers = 1
document_not_sent = 2
document_type_not_exist = 3
operation_no_authorization = 4
parameter_error = 5
x_error = 6
enqueue_error = 7
OTHERS = 8.
IF sy-subrc EQ 0.
FORMAT: COLOR COL_POSITIVE, INTENSIFIED ON.
WRITE: /1 ‘El mail fue enviado con éxito’.
ELSE.
FORMAT: COLOR COL_NEGATIVE, INTENSIFIED ON.
WRITE: /1 ‘No se pudo enviar mail’.
ENDIF.
ENDFORM. » ENVIAR_MAIL
[end]
SE16N – Otra forma de Modificar registros en Tablas SAP
Caso: se busca modificar los registros de una tabla estándar o Z en producción.
Previamente vemos que NO FUNCIONA mediante:
§ la utilización de &SAP_EDIT en la SE16N (luego de la aplicación de una nota de seguridad)
§ el post publicado anteriormente para hacerlo debuggueando y modificando las variables gd-sapedit y gd-edit.
Otra forma de hacerlo (y hasta ahora la que uso yo) es la siguiente:
1. Ingresar a la SE37
2. Ejecutar el módulo de funciones SE16N_INTERFACE.
3. Darle valor ‘X’ a las siguientes variables (siempre apretando el lapicito para grabar el cambio):
· I_TAB (nombre de la tabla a modificar)
· I_EDIT (valor = ‘X’)
· I_SAPEDIT (valor = ‘X’)
4. Ejecutar