Quelquepart

Blog d'un développeur ABAP

Vous êtes ici : Accueil>Fonction

Fonction

Caractères interdits sur BW

Rédigé par Sébastien Hermann dans Fonction, Liste mémo -

Lors de chargements il peut arriver d'avoir une erreur à cause de caractères interdits : "Value 'xxxxx' for characteristic YYYY contains invalid characters"

La transaction RSKC permet de définir la liste des caractères autorisés. Classiquement le générique "ALL_CAPITAL" est utilisé. Mais à quoi correspond-il exactement ?

ALL_CAPITAL autorise tous les caractères à l'exception de 31 caractères de contrôle, c'est-à-dire des caractères invisibles généralement utilisés par les programmes de traitement de texte pour gérer la mise en forme. Aucun de ces caractères ne peut être saisi directement dans SAP, seules des interfaces tiers peuvent éventuellement les injecter. En revanche, il est fréquent de les introduire par erreur lors de copier/coller depuis des logiciels tiers (Word, Excel ou Outlook par exemple).

SAP ne sachant pas les interpréter, ils sont affichés comme des # (mais sont conservés dans leur forme d’origine grâce à Unicode).

Voici la liste des 31 caractères interdits par ALL_CAPITAL :

CodeDésignation
01START OF HEADING
02START OF TEXT
03END OF TEXT
04END OF TRANSMISSION
05ENQUIRY
06ACKNOWLEDGE
07BELL
08BACKSPACE
09CHARACTER TABULATION
0ALINE FEED (LF)
0BLINE TABULATION
0CFORM FEED (FF)
0DCARRIAGE RETURN (CR)
0ESHIFT OUT
0FSHIFT IN
10DATA LINK ESCAPE
11DEVICE CONTROL ONE
12DEVICE CONTROL TWO
13DEVICE CONTROL THREE
14DEVICE CONTROL FOUR
15NEGATIVE ACKNOWLEDGE
16SYNCHRONOUS IDLE
17END OF TRANSMISSION BLOCK
18CANCEL
19END OF MEDIUM
1ASUBSTITUTE
1BESCAPE
1CINFORMATION SEPARATOR FOUR
1DINFORMATION SEPARATOR THREE
1EINFORMATION SEPARATOR TWO
1FINFORMATION SEPARATOR ONE

Pour autoriser ces caractères, il est possible d'utiliser "ALL_CAPITAL_PLUS_HEX" dans RSKC.

Quelques fonctions utiles :
RSKC_ALLOWED_CHAR_GET permet d'obtenir la liste des caractères autorisés saisis dans RSKC.
RSKC_CHAVL_CHECK permet de tester si une valeur va être autorisée par BW.

Un petit fragment de code qui permet de supprimer d'une variable les 31 caractères :

* w_data contient le texte à nettoyer
  DATA: l_length TYPE i,
        l_pos TYPE i,
        lo_not_allowed TYPE REF TO cl_abap_conv_in_ce,
        l_not_allowed_x(32) TYPE x VALUE
'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F',
        l_not_allowed TYPE string.

* Get list of unauthorized values
  lo_not_allowed = cl_abap_conv_in_ce=>create( input = l_not_allowed_x ).
  lo_not_allowed->read( IMPORTING data = l_not_allowed ).

* search if unauthorized value is found
  IF w_data CA l_not_allowed.
* If found, replace it by space
    l_length = STRLEN( w_data ).
    l_pos = 0.
    DO l_length TIMES.
      IF w_data+l_pos(1) CA l_not_allowed.
        w_data+l_pos(1) = space.
      ENDIF.
      l_pos = l_pos + 1.
    ENDDO.
  ENDIF.

Rendre invisible une fenêtre SAPGUI (un mode)

Rédigé par Sébastien Hermann dans Fonction -

Devenez le Majax de l'ABAP grâce à la fonction SAPGUI_SET_PROPERTY
En effet cette fonction du SAPGUI permet de modifier les propriétés de ce dernier, comme par exemple l'affichage des fenêtres SAP !

CALL FUNCTION 'SAPGUI_SET_PROPERTY'
     DESTINATION 'SAPGUI'
     EXPORTING PROPERTY   = 'VISIBLE'
               VALUE = ' '.

Par ce simple appel votre fenêtre disparait complètement. Heureusement l'opération n'est pas irréversible :

CALL FUNCTION 'SAPGUI_SET_PROPERTY'
     DESTINATION 'SAPGUI'
     EXPORTING PROPERTY   = 'VISIBLE'
               VALUE = 'X'.

vous permettra de faire réapparaitre la fenêtre disparue.

En revanche, les usages productifs de cette fonction semblent assez restreint...
On peut imaginer s'en servir lors de lien OLE avec Excel ou Word (création dynamique de document sur le poste utilisateur)
Si vous trouvez un autre usage ou que vous arrivez à avoir des informations sur les autres propriétés modifiables du SAPGUI par cette fonction, n'hésitez pas a laisser un commentaire.

Modifications en production

Rédigé par Sébastien Hermann dans Fonction -

Faire des modifications en production, c'est mal, c'est même carrément interdit.
Oui, tout le monde le sait. Mais alors, pourquoi SAP met a disposition ces 2 fonctions ?

DB_EXECUTE_SQL
Cette fonction permet d'exécuter la requête SQL passée en paramètre. Cette requête, au format "EXEC SQL", peut être INSERT, DELETE, UPDATE... ou tout autre instruction ne nécessitant pas de résultat (SELECT ne renverra rien).

Un exemple inoffensif :

( DROP INDEX TESTINDEX pour supprimer l'index créé)

RFC_ABAP_INSTALL_AND_RUN
Encore plus dangereux, cette fonction compile et exécute tout code abap passé en paramètre. Il suffit de passer le code dans la table PROGRAM. Le résultat sera contenu dans la table WRITES.

Un exemple qui liste les 10 premier clients :

Avec un simple accès à SE37, le mode test permet de faire virtuellement n'importe quelle opération sur un système productif grâce à ces 2 fonctions livrées en standard par SAP.

Terminated change run : fonction RSDDS_AGGR_MOD_CLOSE

Rédigé par Sébastien Hermann dans Fonction -

Lors d'une interruption de chargement d'une donnée de base, elle peut se retrouver complètement bloquée avec une erreur "Attributes for characteristic are locked by a terminated change run" (RSENQ 063 ou RSENQ 062) ou bien une erreur plus générale "Lock NOT set for: ...." (RSENQ 002)

Le cas peut être diagnostiqué en lançant le module fonction : RSDDS_AGGR_MOD_STATE_GET (ne rien renseigner en entrée), la table E_T_CHABASNM contiendra la liste des données de base bloquées. S'il n'y a aucun problème, la fonction renverra une exception.

Pour débloquer la situation il suffit de lancer le module fonction : RSDDS_AGGR_MOD_CLOSE

Classe CL_GUI_FRONTEND_SERVICES

Rédigé par Sébastien Hermann dans Fonction -

Derrière ce nom se cache une véritable trousse à outils de méthodes toutes plus utiles les unes que les autres. En effet SAP a décidé de regrouper au sein d'une même classe toutes les "fonctions" de dialogue avec le pc de l'utilisateur (aussi appelé "poste client").
Terminé les WS_UPLOAD ou autre GUI_UPLOAD (que SAP indique depuis longtemps comme obsolète), place à la méthode upload.

L'usage est simplifié au maximum, afin que même les développeurs fermés à l'abap objet puissent les utiliser. Inutile de créer un objet ou déclarer quoi que ce soit, vous pouvez appeler directement la méthode qui vous intéresse dans la classe CL_GUI_FRONTEND_SERVICES, de la même manière que vous appelleriez une fonction classique.

Ci dessous un tableau récapitulant les principales méthodes, avec un exemple d'utilisation.

Méthode Description Code exemple
CLIPBOARD_EXPORT Exporter des données dans le presse-papier Windows
DATA : s_line(100),
       t_line LIKE TABLE OF s_line,
       i_rc TYPE i.

APPEND 'Test envoi presse-papier' TO t_line.

CALL METHOD cl_gui_frontend_services=>clipboard_export
  IMPORTING
    data         = t_line
  CHANGING
    rc           = i_rc
  EXCEPTIONS
    OTHERS       = 0.
WRITE i_rc.
CLIPBOARD_IMPORT Importer des données du presse-papier Windows
DATA : s_line(100),
       t_line LIKE TABLE OF s_line,
       i_length TYPE i.

CALL METHOD cl_gui_frontend_services=>clipboard_import
  IMPORTING
    data         = t_line
    length       = i_length
  EXCEPTIONS
    OTHERS       = 0.

LOOP AT t_line INTO s_line.
  WRITE / s_line.
ENDLOOP.
DIRECTORY_BROWSE Affiche un popup windows de sélection de répertoire sur le poste local Ne fonctionne pas avec le noyau 4.6c
DATA : w_folder TYPE string,
       w_title TYPE string,
       w_init TYPE string.

w_title = 'Rechercher le dossier'.
w_init = 'C:'.

CALL METHOD cl_gui_frontend_services=>directory_browse
  EXPORTING
    window_title    = w_title
    initial_folder  = w_init
  CHANGING
    selected_folder = w_folder
  EXCEPTIONS
    OTHERS          = 0.

WRITE w_folder.
DIRECTORY_CREATE Créer un répertoire sur le poste client
DATA : w_dir TYPE string,
       i_rc TYPE i.

w_dir = 'C:Nouveau Rep inexistant'.

CALL METHOD cl_gui_frontend_services=>directory_create
  EXPORTING
    directory = w_dir
  CHANGING
    rc        = i_rc
  EXCEPTIONS
    OTHERS    = 0.

WRITE i_rc.
DIRECTORY_DELETE Supprimer un répertoire sur le poste client
DATA : w_dir TYPE string,
       i_rc TYPE i.

w_dir = 'C:Nouveau Rep inexistant'.

CALL METHOD cl_gui_frontend_services=>directory_delete
  EXPORTING
    directory = w_dir
  CHANGING
    rc        = i_rc
  EXCEPTIONS
    OTHERS    = 0.

WRITE i_rc.
DIRECTORY_EXIST Tester si un répertoire existe sur le poste client
DATA : w_dir TYPE string,
       w_rc.

w_dir = 'C:guixt'.

CALL METHOD cl_gui_frontend_services=>directory_exist
  EXPORTING
    directory = w_dir
  RECEIVING
    result    = w_rc
  EXCEPTIONS
    OTHERS    = 0.

WRITE w_rc. "X si existe, space si n'existe pas
DIRECTORY_LIST_FILES Liste les fichiers d'un répertoire
DATA : s_line(100),
       t_line LIKE TABLE OF s_line,
       w_dir TYPE string,
       i_count TYPE i.

w_dir = 'C:'.

CALL METHOD cl_gui_frontend_services=>directory_list_files
  EXPORTING
    directory                   = w_dir
    filter                      = '*.TXT'
*    FILES_ONLY                  =
*    DIRECTORIES_ONLY            =
  CHANGING
    file_table                  = t_line
    count                       = i_count
  EXCEPTIONS
    OTHERS                      = 0.

WRITE i_count.
LOOP AT t_line INTO s_line.
  WRITE / s_line.
ENDLOOP.
ENVIRONMENT_GET_VARIABLE Lecture d'une variable d'environnement Windows Ne semble pas fonctionner sur noyau SAP_BASIS 6.20
DATA : w_var TYPE string,
       w_val TYPE string.

w_var = 'OS'.

CALL METHOD cl_gui_frontend_services=>environment_get_variable
  EXPORTING
    variable = w_var
  CHANGING
    value    = w_val
  EXCEPTIONS
    OTHERS   = 0.

WRITE w_val.
ENVIRONMENT_SET_VARIABLE Modification d'une variable d'environnement Windows Ne semble pas fonctionner sur noyau SAP_BASIS 6.20
DATA : w_var TYPE string,
       w_val TYPE string,
       i_rc TYPE i.

w_var = 'NEWVAR'.
w_val = 'TEST'.
CALL METHOD cl_gui_frontend_services=>environment_set_variable
  EXPORTING
    variable = w_var
    value    = w_val
  CHANGING
    rc       = i_rc
  EXCEPTIONS
    OTHERS   = 0.

WRITE i_rc.
EXECUTE Exécute une application sur le poste client
DATA : w_appl TYPE string,
       w_param TYPE string.

w_appl = 'C:WINDOWSNOTEPAD.EXE'.
w_param = 'C:boot.ini'.

CALL METHOD cl_gui_frontend_services=>execute
  EXPORTING
    application            = w_appl
    parameter              = w_param
  EXCEPTIONS
    OTHERS                 = 0.
FILE_DELETE Supprimer un fichier sur le poste client
DATA : w_file TYPE string,
       i_rc TYPE i.

w_file = 'C:test.txt'.

CALL METHOD cl_gui_frontend_services=>file_delete
  EXPORTING
    filename = w_file
  CHANGING
    rc       = i_rc
  EXCEPTIONS
    OTHERS   = 0.

WRITE i_rc.
FILE_EXIST Tester si un fichier existe sur le poste client
DATA : w_file TYPE string,
       w_rc.

w_file = 'C:test.txt'.

CALL METHOD cl_gui_frontend_services=>file_exist
  EXPORTING
    file   = w_file
  RECEIVING
    result = w_rc
  EXCEPTIONS
    OTHERS = 0.

WRITE w_rc.
FILE_OPEN_DIALOG Affiche un popup windows de sélection de fichier sur le poste local
DATA : w_titre TYPE string,
       w_file TYPE string,
       w_dir TYPE string,
       t_file TYPE filetable,
       s_file LIKE LINE OF t_file,
       i_rc TYPE i.

w_titre = 'Selection de fichier'.
w_file = 'test.txt'.
w_dir = 'C:guixt'.

CALL METHOD cl_gui_frontend_services=>file_open_dialog
  EXPORTING
    window_title      = w_titre
    default_filename  = w_file
    initial_directory = w_dir
  CHANGING
    file_table        = t_file
    rc                = i_rc
  EXCEPTIONS
    OTHERS            = 0.

WRITE i_rc.
LOOP AT t_file INTO s_file.
  WRITE / s_file.
ENDLOOP.
FILE_SAVE_DIALOG Affiche un popup windows de sélection de fichier sur le poste local (avec confirmation si le fichier existe déjà)
DATA : w_titre TYPE string,
       w_file TYPE string,
       w_dir TYPE string,
       w_name TYPE string,
       w_path TYPE string,
       w_fp TYPE string.

w_titre = 'Selection de fichier pour sauvegarde'.
w_file = 'test.txt'.
w_dir = 'C:guixt'.

CALL METHOD cl_gui_frontend_services=>file_save_dialog
  EXPORTING
    window_title      = w_titre
    default_file_name = w_file
    initial_directory = w_dir
  CHANGING
    filename          = w_name
    path              = w_path
    fullpath          = w_fp
  EXCEPTIONS
    OTHERS            = 0.

WRITE : / w_name, / w_path, / w_fp.
GUI_DOWNLOAD Télécharger un fichier sur le poste client
DATA : w_file type string,
       s_file type string,
       t_file like table of s_file.

w_file = 'C:test.txt'.
s_file = 'Test de contenu de fichier'.
append s_file to t_file.

CALL METHOD cl_gui_frontend_services=>gui_download
  EXPORTING
    filename                = w_file
    FILETYPE                = 'ASC'
  changing
    data_tab                = t_file
  EXCEPTIONS
    others                  = 0.
GUI_UPLOAD Charger un fichier depuis le poste client
DATA : w_file TYPE string,
       s_file TYPE string,
       t_file LIKE TABLE OF s_file.

w_file = 'C:test.txt'.

CALL METHOD cl_gui_frontend_services=>gui_upload
  EXPORTING
    filename = w_file
  CHANGING
    data_tab = t_file
  EXCEPTIONS
    OTHERS   = 0.

LOOP AT t_file INTO s_file.
  WRITE / s_file.
ENDLOOP.
REGISTRY_DELETE_KEY Supprimer une clé de registre sur le poste client Ne semble pas fonctionner sur noyau SAP_BASIS 6.20
REGISTRY_DELETE_VALUE Supprimer une valeur de registre sur le poste client Ne semble pas fonctionner sur noyau SAP_BASIS 6.20
REGISTRY_GET_VALUE Lire une valeur de registre sur le poste client Ne semble pas fonctionner sur noyau SAP_BASIS 6.20
REGISTRY_SET_VALUE Modifier une valeur de registre sur le poste client Ne semble pas fonctionner sur noyau SAP_BASIS 6.20