Category Archives: SAP (ABAP, BASIS, …)

Problem installing SAP GUI on Windows 10

I just downloaded the latest SAP GUI ZIP file from http://launchpad.support.sap.com/

The installation failed with hundreds of weird errors and didn’t work at all. Checking the errors, seems that Windows BLOCKED all the DLLs and from executables from the installation. I uninstalled SAP GUI and from an administrator Power Shell Console went to the root of the install media:

PS C:\Users\MDaponte\Downloads> cd C:\Users\MDaponte\Downloads\SAP\GUI_7.50_Win\Install\PRES1
PS C:\Users\MDaponte\Downloads\SAP\GUI_7.50_Win\Install\PRES1> dir -Recurse | Unblock-File -Verbose

That command unblocked all the files in the media. Afterwards, the installation worked without a single error.

 

 

Oracle’s TRANSLATE function in SQL Server

— =======================================================================
— Author : Manuel Daponte
— Created: 2009-10-28
— Descrip:

—    Copia barata de la funcion translate de Oracle
—    Al string @expr le busca si contiene alguno de los caracteres
—    del @from y los reemplaza por el caracter en la misma del @to

—    Ejemplo:
—       translate(‘Mañana será mía’, ‘áéíóúñ’, ‘aeiou~’)
—    Retornara:
—       Ma~ana sera mia
— =======================================================================
use Exencion
go
create function translate (
   @expr  varchar(max),
   @from  varchar(50),
   @to    varchar(50)
)
returns varchar(max)
as
begin
   declare @len_expr  smallint  — largo de la expresion donde se haran los reemplazos
   declare @len_from  smallint  — largo del string con los caracteres a reemplazar
   declare @len_to    smallint  — largo del string con los caracteres de reemplazo
 
   — averiguamos los largos de los strings
   select @len_expr = len(@expr), @len_from = len(@from), @len_to = len(@to)
   — no tenemos nada que cambiar
   if @len_expr = 0 or @len_from = 0
      return @expr
 
   declare @char_from char(1)   — para guardar cada caracter que queremos reemplazar
   declare @pos_from  smallint  — en que posicion del @from esta el caracter que estamos procesando

   set @pos_from = 1

   — recorremos el @from
   while (@pos_from <= @len_from)
   begin
      — cual es el equivalente en @to de este caracter
      if @pos_from <= @len_to
      begin
         — el caracter tiene un reemplazo
         set @expr = replace(@expr, substring(@from, @pos_from, 1), substring(@to, @pos_from, 1))
      end
      else
      begin
         — el caracter no tiene un reemplazo
         set @expr = replace(@expr, substring(@from, @pos_from, 1), ”)
      end
      — pasamos al siguiente caracter del @from
      set @pos_from = @pos_from + 1
   end
   return @expr
end
 
 
…Y esta es la manera de ejecutarla:
 
select dbo.translate(‘Mañana será mía, Ñoño!’, ‘áéíóúñ’, ‘aeiou~’)
Ma~ana sera mia, ~o~o!
 
select dbo.translate(‘Mañana será mía, Ñoño!’, ‘áéíóúñ’, ‘a’)
 
Maana sera ma, oo!
 
 

 

Bloquear el acceso a un mandante de SAP

Para impedir que los usuarios se conecten a un mandante SAP, conectese con su usuario y en la SE37 ejecute la funcion SCCR_LOCK_CLIENT. Los usuarios que esten conectados podran continuar trabajando hasta que se desconecten, pero ningun usuario podra conectarse al mandante, excepto SAP* y DDIC.

Para desbloquear el mandante, use la funcion SCCR_UNLOCK_CLIENT.

Si por mala suerte, bloquea el mandante y no puede volver a conectarse a SAP para desbloquearlo, pidale al DBA que actualice T000.CCTEMPLOCK con un espacio en blanco para el mandante rebelde.  Apague y vuelva a levantar SAP y todo deberia volver a  la normalidad.

Seleccionar un archivo en el servidor o en el cliente con ABAP

*&———————————————————————*
*& Report  Z_SELECCIONA_ARCHIVO                                        *
*&                                                                     *
*&———————————————————————*
*&                                                                     *
*&                                                                     *
*&———————————————————————*

report Z_SELECCIONA_ARCHIVO.

" selecccionar un archivo en el servidor o en el cliente

data:
   L_C_S          type C,  " archivo en cliente o en servidor
   L_ARCH(255)    type C,
   L_ERROR_C      type STRING,
   L_AUX          type STRING.  " variable utilitaria

" para buscar el nombre del servidor
data:
   L_SERVER like MSXXLIST-NAME,
   L_RFCSI_EXPORT like RFCSI.

selection-screen begin of block B1 with frame.
parameters:
   R_CLT radiobutton group RAD1 default ‘X’,
   R_SRV radiobutton group RAD1.
selection-screen end of block B1.

"at selection-screen on value-request for P_PATH.
start-of-selection.

   if R_SRV = ‘X’.
      " application server (vulgo SERVIDOR SAP)
      L_C_S = ‘A’.

      " busco el nombre del servidor, para que la funcion F4_DXFILENAME_TOPRECURSION
      "    no lo pregunte
      call function ‘RFC_SYSTEM_INFO’
         importing
            RFCSI_EXPORT = L_RFCSI_EXPORT.
      move L_RFCSI_EXPORT-RFCDEST to L_SERVER.
   else.
      " presentation server (vulgo CLIENTE)
      L_C_S = ‘P’.
   endif.

   " server
   call function ‘F4_DXFILENAME_TOPRECURSION’
      exporting
         I_LOCATION_FLAG       = L_C_S
         I_SERVER              = L_SERVER
         I_PATH                = ‘C:\SAPPayroll’
         "FILEMASK              = ‘*.txt’
         "FILEOPERATION         = ‘R’
      importing
         "O_LOCATION_FLAG       =
         "O_SERVER              =
         O_PATH                = L_ARCH
         "ABEND_FLAG            =
      exceptions
         "RFC_ERROR             = 1
         "ERROR_WITH_GUI        = 2
         others                = 3
   .
   if SY-SUBRC <> 0.
      L_ERROR_C = SY-SUBRC.
      concatenate ‘Error seleccionando archivo’ L_ERROR_C into L_AUX separated by SPACE.
      message L_AUX type ‘E’.
   endif.

start-of-selection.
   if L_ARCH = SPACE.
      message ‘Archivo no seleccionado’ type ‘E’.
   else.
      concatenate ‘Archivo ‘ L_ARCH into L_AUX separated by SPACE.
      message L_AUX type ‘I’.
   endif.

* END

Como enviar un spool de SAP a un archivo PostScript en disco

Esto se puede usar, por ejemplo, para imprimir ese spool en una empresa de impresion externa

– La PC debe tener una impresora definida con nombre FILE, que escriba en el puerto FILE: y que utilice un driver PostScript de una impresora comun. En mi PC, utilice los drivers de la “Lexmark Optra T610 PS”.

La impresora se crea asi en Windows: 

– Abrir “Printers and faxes”

– Add printer 

– “Local printer attached to this computer” (no debe estar seleccionado el “Automatically detect…”)

– En ‘Use the following port” seleccione “FILE: (Print to file)” 

– Seleccione la impresora PostScript que prefiera

– En “Printer Name” coloque FILE 

– Ahora, en “Printers and faxes” deberia aparecer la impresora FILE con un icono que es una impresora con un floppy encima

– En SAP, entramos a la transaccion SP01 para ver los spool requests y ponemos el criterio de seleccion apropiado

– Ponemos un checkmark al spool request que deseamos salvar en PostScript y seleccionamos en el menu “Spool Request” -> “Print” -> “Print with changed parameters…”

– Debera existir en SAP una impresora llamada z_file (en minusculas). La impresora tendra las siguientes propiedades:

En el tab “Device Attributes”

Output Device: z_file

Short name   : ZFIL

Device Type  : SAPWIN SAPWIN   : Rel.4.x/SAPlpd 4.09+ ONLY!

Model        : FILE

Location     : FILE Printer in frontend 

En el tab “Access Method”

Host Spool Access Method: F F: Printing on Front End Computer

Host printer            : FILE

– En el “Output device” ponemos la impresora z_file (en minusculas) y le damos al boton de imprimir. 

– Automaticamente se abrira SAPlpd y unos segundos mas tarde, se abrira un dialog box preguntando “Print to File / Output File Name”. Colocaremos un nombre de archivo local en la PC, como por ejemplo C:\temp\spool_5656.ps

– Como nota adicional, podemos ver el archivo por pantalla sin necesidad de imprimirlo, utilizando un software gratis llamado GSView (http://pages.cs.wisc.edu/~ghost/gsview/). Por eso es recomendable ponerle el apellido .ps al archivo.

– Si queremos imprimir el archivo en una impresora, podemos utlizar este comando desde un command prompt de Windows: 

lpr -S 192.168.2.30 -P 9100 -o l C:\temp\spool_5656.ps

El 192.168.2.30 es el IP de la impresora. El 9100 es el numero de puerto por default que usan las impresoras laser para recibir sus requests. El “–o l” (es una letra L minuscula) sirve para indicar que enviaremos un archivo binario a la impresora. El C:\temp\spool_5656.ps es el nombre del archivo postscript que extrajimos del spool de SAP.

ABAP Report ZHR_SAP_A_KRONOS

*&—————————————————————————-*
*& Report  ZHR_SAP_A_KRONOS                                                   *
*&—————————————————————————-*
*& Enviar un empleado desde SAP a la base de datos de Kronos,                 *
*&    ejecutando un stored procedure en la base de datos OurDatabase          *
*&—————————————————————————-*
*& Manuel Daponte – MDaponte@GMail.Com – 2007-11-21                           *
*&—————————————————————————-*

report zhr_sap_a_kronos.

data:
   v_nombre        type string,
   v_apellido      type string,
   v_subject       type SO_OBJ_DES,  " subject del mail
   v_comando(132)  type c,
   v_pernr         type pa0001-pernr,
   begin of outp occurs 0,
      line(255)    type c,
   end of outp,
   v_texto         type bcsy_text, " texto del mail
   v_inserto       type c value ‘N’.  " Y si inserto Kronos

TABLES: rp50g.
SELECTION-SCREEN: BEGIN OF BLOCK ventana1 WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_pernr FOR RP50G-pernr MATCHCODE Object PREM
NO-EXTENSION NO INTERVALS.
SELECTION-SCREEN: END OF BLOCK ventana1.

v_pernr = s_pernr-low.

if v_pernr = ”.
   write: / ‘No especifico un criterio de seleccion’.
   exit.
endif.

* busco que el empleado exista
select single vorna nachn
  into (v_nombre, v_apellido)
  from pa0002
 where pernr = v_pernr.

if sy-subrc <> 0.
   write: / ‘Empleado’, v_pernr, ‘no existe’.
   exit.
endif.

* quito los espacios en blanco al final del nombre
cl_abap_string_utilities=>del_trailing_blanks( changing str = v_nombre ).

concatenate ‘Ejecutando pase de empleado’ v_pernr v_nombre v_apellido into v_subject separated by space.
write: / v_subject.

* ejecutamos el stored procedure
* execute procedure PROC2 ( IN :Y, OUT :Z )
*exec sql.
*   execute OurDatabase.dbo.proc_SAP_a_Kronos :p_pernr, :v_salida output
*endexec.

concatenate
   ‘osql -S (local) -U usuario -P password -Q "declare @s varchar(100) exec OurDatabase..proc_SAP_a_Kronos ‘
   ‘ ”’
   v_pernr
   ”” ‘, @s output print @s"’
      into v_comando.

*write: / v_comando.

call ‘SYSTEM’ id ‘COMMAND’ field v_comando
              id ‘TAB’     field outp-*sys*.
loop at outp.
   write: /1 outp-line.
   append outp-line to v_texto.  " voy guardando el texto del mail
   if outp-line = ‘Registros insertados. Ejecutar proceso de importacion en Kronos’.
      v_inserto = ‘Y’.  " se enviara el mail…
   endif.
endloop.

* si logro insertar, envio un mail
if v_inserto = ‘Y’.
   write: / ‘Enviando mail…’.
   call function ‘Z_ENVIA_EMAIL_SHARED_DIST_LIST’
      exporting
         p_dist_list_name = ‘KRONOS’
         p_subject        = v_subject
         p_text           = v_texto.
endif.



ABAP FUNCTION Z_ENVIA_EMAIL_SHARED_DIST_LIST

FUNCTION Z_ENVIA_EMAIL_SHARED_DIST_LIST.
*"———————————————————————-
*"*"Local interface:
*"  IMPORTING
*"     REFERENCE(P_DIST_LIST_NAME) TYPE  SO_OBJ_NAM
*"     REFERENCE(P_SUBJECT) TYPE  SO_OBJ_DES
*"     REFERENCE(P_TEXT) TYPE  BCSY_TEXT
*"———————————————————————-

data:
   send_request       type ref to cl_bcs,
   document           type ref to cl_document_bcs,
   recipient          type ref to if_recipient_bcs,
   bcs_exception      type ref to cx_bcs.

try.
   " ——– create persistent send request ————————
   send_request = cl_bcs=>create_persistent( ).

   "——– create and set document ——————————-
   " create document from internal table with text
   document = cl_document_bcs=>create_document(
                 i_type    = ‘RAW’
                 i_text    = P_TEXT
                 i_length  = ’12’
                 i_subject = P_SUBJECT ).

   " add document to send request
   call method send_request->set_document( document ).

   " enviar a un shared distribution list
   " https://www.sdn.sap.com/irj/sdn/thread?messageID=4220548
   recipient = cl_distributionlist_bcs=>getu_persistent(
                  i_dliname = P_DIST_LIST_NAME
                  i_private = ‘ ‘).
   " add recipient with its respective attributes to send request
   call method send_request->add_recipient
       exporting
          i_recipient  = recipient
          i_express    = ‘X’.

   " y esto envia directamente
   call method send_request->send.

   commit work.

   " Instructs mail send program for SAPCONNECT to send email.
   "———————————————————————-*
   " http://www.sapdevelopment.co.uk/reporting/email/email_mbody.htm
   data: gd_error type sy-subrc.
   wait up to 3 seconds.
   if gd_error eq 0.
      submit rsconn01 with mode = ‘INT’ with output = ‘X’ and return.
   endif.

 "———————————————————–
 "                     exception handling
 "———————————————————–
 " replace this very rudimentary exception handling
 "    with your own one !!!
 "———————————————————–
 catch cx_bcs into bcs_exception.
    write: ‘Ocurrio un error.'(001).
    write: ‘Tipo de error:'(002), bcs_exception->error_type.
    exit.

 endtry.

ENDFUNCTION.


Send mail from ABAP to an email address or a shared/private distribution list

*&———————————————————————*
*& Report  ZSENDEMAIL
*&
*&———————————————————————*
*& Example of sending external email via SAPCONNECT
*& Prueba de envio de mail
*&———————————————————————*
REPORT zsendemail.

perform SEND_MAIL.
perform initiate_mail_execute_program.

*———————————————————————–
*———————————————————————–
*———————————————————————–

*&———————————————————————*
*&      Form SEND_MAIL
*&———————————————————————*
*&
*&———————————————————————*
FORM SEND_MAIL.

DATA: send_request       TYPE REF TO cl_bcs.
DATA: text               TYPE bcsy_text.
DATA: document           TYPE REF TO cl_document_bcs.
DATA: sender             TYPE REF TO cl_sapuser_bcs.
DATA: recipient          TYPE REF TO if_recipient_bcs.
DATA: bcs_exception      type ref to cx_bcs.
DATA: sent_to_all        type os_boolean.

try.
   " ——– create persistent send request ————————
   send_request = cl_bcs=>create_persistent( ).

   "——– create and set document ——————————-
   " create document from internal table with text
   APPEND ‘Hello world!’ TO text.
   document = cl_document_bcs=>create_document(
                 i_type    = ‘RAW’
                 i_text    = text
                 i_length  = ’12’
                 i_subject = ‘test created by BCS_EXAMPLE_4’ ).

   " add document to send request
   CALL METHOD send_request->set_document( document ).

   "——— set sender ——————————————-
   " note: this is necessary only if you want to set the sender
   "       different from actual user (SY-UNAME). Otherwise sender is
   "       set automatically with actual user.

   sender = cl_sapuser_bcs=>create( sy-uname ).
   CALL METHOD send_request->set_sender
      EXPORTING i_sender = sender.

   " enviar a una direccion email
   " create recipient – please replace e-mail address !!!
   recipient = cl_cam_address_bcs=>create_internet_address(
                  ‘poncio_piloto@gmail.com’ ).


   " add recipient with its respective attributes to send request
   CALL METHOD send_request->add_recipient
       EXPORTING
          i_recipient  = recipient
          i_express    = ‘X’.

   " enviar a un shared distribution list
   " https://www.sdn.sap.com/irj/sdn/thread?messageID=4220548
   recipient = cl_distributionlist_bcs=>getu_persistent(
                  i_dliname = ‘KRONOS’
                  i_private = ‘ ‘).
   " add recipient with its respective attributes to send request
   CALL METHOD send_request->add_recipient
       EXPORTING
          i_recipient  = recipient
          i_express    = ‘X’.

   " esto permite que se a~adan o cambien las direcciones de mail y se envie en correo
   "———- send document ———————————————————
   "CALL METHOD send_request->edit(
   "   i_hide_note     = ‘X’
   "   i_starting_at_x = 12
   "   i_starting_at_y = 5
   "   i_ending_at_x   = 97
   "   i_ending_at_y   = 22 ).

   " y esto envia directamente
   call method send_request->send.

   COMMIT WORK.

   "———————————————————–
   "                     exception handling
   "———————————————————–
   " replace this very rudimentary exception handling
   "    with your own one !!!
   "———————————————————–
   catch cx_bcs into bcs_exception.
      write: ‘Fehler aufgetreten.'(001).
      write: ‘Fehlertyp:'(002), bcs_exception->error_type.
      exit.

   endtry.

endform.


form initiate_mail_execute_program.
*&———————————————————————*
*&      Form  INITIATE_MAIL_EXECUTE_PROGRAM
*&———————————————————————*
*       Instructs mail send program for SAPCONNECT to send email.
*———————————————————————-*
* http://www.sapdevelopment.co.uk/reporting/email/email_mbody.htm
   data: gd_error type sy-subrc.
   wait up to 3 seconds.
   if gd_error eq 0.
      submit rsconn01 with mode = ‘INT’ with output = ‘X’ and return.
   endif.
endform.
* INITIATE_MAIL_EXECUTE_PROGRAM

How to execute an OS command from ABAP?

To execute an operating system command from ABAP, Mr. Arturo Salcido sent this code to me:

Para ejecutar un comando de sistema operativo desde ABAP, el Sr. Arturo Salcido me envio este codigo:


*&———————————————————————*
*& Report  ZWINCMD                                                     *
*&                                                                     *
*&———————————————————————*
*&                                                                     *
*&                                                                     *
*&———————————————————————*

REPORT ZWINCMD NO STANDARD PAGE HEADING.
include <icon>.

* Ejecuta un comando en el servidor
* data declaration
DATA: BEGIN OF OUTP OCCURS 0,
  LINE(255)     TYPE C,
END OF OUTP.
*Selection screen
PARAMETERS: comando(132) TYPE C LOWER CASE.

START-OF-SELECTION.
  PERFORM EXEC_OS.

*&———————————————————————*
*&      Form  EXEC_OS
*&———————————————————————*
*       text
*———————————————————————-*
*  –>  p1        text
*  <–  p2        text
*———————————————————————-*
FORM EXEC_OS.
  REFRESH OUTP.

* System call which executes a Unix command *
  CALL ‘SYSTEM’ ID ‘COMMAND’ FIELD COMANDO
              ID ‘TAB’     FIELD OUTP-*SYS*.

* Display *
  FORMAT COLOR COL_POSITIVE HOTSPOT.
  WRITE:  ICON_EXECUTE_OBJECT AS ICON,
          ‘Execute’ .
  FORMAT RESET.
  WRITE:
          COMANDO INPUT.
  WRITE: / SY-SUBRC.
  LOOP AT OUTP.
    WRITE: /1 OUTP-LINE.
  ENDLOOP.
  REFRESH OUTP.
ENDFORM.                               " EXEC_UNIX

AT LINE-SELECTION.
  DATA: FLDNAME(20), LINENO TYPE I.
  GET CURSOR FIELD FLDNAME LINE LINENO.
  IF LINENO = 1.                       " if on first line
    READ LINE 2 FIELD VALUE COMANDO INTO COMANDO.
    SY-LSIND = 1.
    PERFORM EXEC_OS.
  ENDIF.

AT PF8.
  READ LINE 2 FIELD VALUE COMANDO INTO COMANDO.
  SY-LSIND = 0.
  PERFORM EXEC_OS.


Tareas de copia de mandante de SAP

Tareas para copiar el mandante productivo a desarrollo o calidad:

– Si amerita, exportar los usuarios del mandante que va a ser sobreescrito SCC8

– Exportar el mandante productivo SCC8

– Importar el mandante STMS

– Post client import methods SCC7

– Revisar log del import SCC3

– Si amerita, subir la orden de transporte con los usuarios que tenia el mandante originalmente, y arreglar la organizacion de los mismos:

Despues de importar los usuarios nuevamente, en la SU01 da el error "Address not maintained" al tratar de ir al primer tab.

Cuando tratamos de modificar da "Inconsistency with address"

Inconsistency with address

    Message no. 01022

Diagnosis

    The address information in the user administration is not consistent
    with the data in the business address services, so the system is
    currently unable to display an address for the user.

System Response

    The address tab in user maintenance cannot be selected. The logon data
    is displayed.

Procedure for System Administration

    You can clean up the inconsistent address data with report RSADRCK2.

– Cambiar las listas de distribucion de mails en la SO23 (o llegandole por SAP Business Workplace SBWP)

– Ejecutar la transaccion BUSP en el mandante para los application objects

BUPA
BUPR
FICA
PSOB

  Y regenerando “All screens”. De esta manera no tendremos problema con CAA1, CAA2 y CAA3.

– Si es un mandante nuevo, regenerar el modulo que tiene la lista de los mandantes. No recuerdo ahora el nombre del programa, asi que ver los dumps en la ST22 y ver el codigo que causo el dump: en las primeras lineas dice como regenerarlo.