Posts Tagged abap

Modifications en production

Je vous conseille d’aller lire cet article à sa nouvelle adresse : Modifications en production

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 :

DB_EXECUTE_SQL

DB_EXECUTE_SQL


( 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 :

RFC_ABAP_INSTALL_AND_RUN

RFC_ABAP_INSTALL_AND_RUN

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.

Tags: , , ,

Ajouter des boutons sur un écran de sélection

Je vous conseille d’aller lire cet article à sa nouvelle adresse : Ajouter des boutons sur un écran de sélection

SSCRFIELDS : Boutons dans un écran de sélection

SSCRFIELDS : Boutons dans un écran de sélection


Dans un écran SAP, pour gérer des boutons au niveau de la barre de fonction (toolbar), vous devez créer un statut de surface (set pf-status et SE41) et y définir vos boutons. Sans être vraiment long, l’opération est assez fastidieuse, surtout si l’on doit documenter chaque objet créé ;-)

Dans un écran de sélection, il existe une astuce afin de gérer jusqu’à 5 boutons dans la toolbar sans avoir à déclarer de statut de surface, simplement avec un peu d’ABAP. C’est la structure SSCRFIELDS qui va nous permettre ce petit tour de magie.

  1. Tout d’abord déclarer la structure sscrfields.
    TABLES sscrfields.
  2. Activer les boutons (de 1 à 5)
    SELECTION-SCREEN FUNCTION KEY 1.
    SELECTION-SCREEN FUNCTION KEY 2.
  3. Renseigner le texte du bouton (il est possible d’y mettre un icone)
    INITIALIZATION.
      sscrfields-functxt_01 = 'Fonction 1'.
      sscrfields-functxt_02 = '@01@Fonction 2'.
  4. Capturer l’action dans le PAI de l’écran de sélection
    AT SELECTION-SCREEN.
      CASE sy-ucomm.
        WHEN 'FC01'.
          MESSAGE i000(38) WITH 'Fonction 1 !'.
        WHEN 'FC02'.
          CLEAR sy-ucomm.
          MESSAGE e000(38) WITH 'Fonction 2 !'.
      ENDCASE.

C’est tout !
Autre avantage, les boutons étant intégralement déclarés dans le code, un simple copier-coller vous permet de réutiliser votre code ailleurs ;-)

La preuve par cet exemple complet :

REPORT zkunnr.

* declaration
TABLES sscrfields.

* Ecran de sélection
SELECTION-SCREEN FUNCTION KEY 1.
SELECTION-SCREEN FUNCTION KEY 2.
SELECTION-SCREEN BEGIN OF BLOCK one WITH FRAME TITLE text-t01.
PARAMETERS p_kunnr LIKE kna1-kunnr.
SELECTION-SCREEN END OF BLOCK one.

INITIALIZATION.
  sscrfields-functxt_01 = 'Fonction 1'.
  sscrfields-functxt_02 = '@01@Fonction 2'.

AT SELECTION-SCREEN.
  CASE sy-ucomm.
    WHEN 'FC01'.
      MESSAGE i000(38) WITH 'Fonction 1 !'.
    WHEN 'FC02'.
      CLEAR sy-ucomm.
      MESSAGE e000(38) WITH 'Fonction 2 !'.
  ENDCASE.

START-OF-SELECTION.
  WRITE p_kunnr.

Tags: , , ,

BW3 : Suppression des données d’un cube avec ses dimensions

Je vous conseille d’aller lire cet article à sa nouvelle adresse : BW3 : Suppression des données d’un cube avec ses dimensions

L’accroissement de la taille des dimensions sur BW3 est un problème classique de l’équipe de maintenance. En effet, lors d’un cube chargé en “full” quotidiennement, le contenu du cube est généralement purgé au début du chargement.

Malheureusement cette étape de la process chain ne propose pas d’option pour supprimer également le contenu des dimensions. Ainsi leur taille croit jour après jour, finissant si l’on y prend pas garde par dépasser la volumétrie du cube lui même, entrainant ainsi une dégradation des performances de plus en plus prononcée, ainsi qu’un accroissement de la taille occupée par le cube sur le disque.

SAP a finit par se rendre compte de ce problème, et la version BI7 propose en option de supprimer le contenu des dimensions lors de la suppression du contenu d’un cube.
Pour les malheureux qui n’ont pas encore migré, il n’y a pas de solution standard, à part effectuer régulièrement une suppression manuelle du contenu des dimensions (prévoir un réveil a 3h du matin pour intervenir juste avant le chargement de la process chain…)

J’ai donc réalisé un petit ABAP spécifique afin de réaliser cette opération. Il vient remplacer le processus de suppression de contenu de cube dans les process chain. Il suffit de préciser en paramètre d’entrée le nom du cube pour que son contenu ainsi que ses dimensions soient supprimées.

Télécharger le code source de ZCUBE_DELETE

Tags: , , , , , ,

Classe CL_GUI_FRONTEND_SERVICES

Je vous conseille d’aller lire cet article à sa nouvelle adresse : Classe CL_GUI_FRONTEND_SERVICES

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:\WINDOWS\NOTEPAD.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

Tags: , ,

ZTOAD – Requêteur Open SQL

Je vous conseille d’aller lire cet article à sa nouvelle adresse : ZTOAD – Requêteur Open SQL

Vous avez surement déjà été confronté à un bug dans un programme en production qui ne semble pas être reproductible en environnement de test.

Dans ces cas là, il n’est pas toujours évident de débugger directement le programme en production (problème de droits, sensibilité des données, risque de mauvaise exécution, documents créés avec votre user…). Quand le bug semble venir d’une requête SQL un peu compliquée (jointure sur 5 tables, subquery…), vous voila embarqué dans de fastidieuses recherches via SE16 avec 3 ou 4 modes ouverts pour essayer de comprendre le problème avec la requête (et encore… le problème ne vient peut-être même pas de cette requête la !)

Dans d’autres mondes, les développeurs n’ont pas ce genre de problèmes et peuvent composer en temps réel leur requêtes personnalisées directement sur la base de données. Sur SAP ce n’est pas possible. Vraiment ? Pas en standard en tout cas. Il suffit donc de créer un programme spécifique.

Dérivé de Z_TETARD lui même dérivé de YES4SQL, voici ZTOAD, mon requêteur SQL. Il permet de faire vos propres requêtes multi-tables, ou de copier coller celle du programme à débugger.

Les commentaires ABAP sont supprimés avant exécution, les alias de table sont compris, les requêtes sont mémorisées pour réutilisation  (jusqu’à 99 requêtes).

 

ZTOAD historique des requêtes

ZTOAD historique des requêtes

 

Choisissez au lancement si vous voulez partir sur une page blanche ou reprendre une ancienne requête.
Sur cet écran vous pouvez choisir de supprimer une ancienne requête afin de garder un historique clair.

 

ZTOAD Saisie de requête

ZTOAD Saisie de requête

 

Saisissez / complétez votre requête, puis sauvegardez la (cela lance le traitement). Vous pouvez l’aérer et la commenter. * et ” sont acceptés pour les commentaires.

 

ZTOAD Visualisation résultat

ZTOAD Visualisation résultat

Le résultat apparait dans un ALV grid, avec rappel en en-tête de votre requête.

 

A noter : le programme n’accepte que les requêtes de type SELECT afin d’être “acceptable” en production (sous réserve)

Télécharger ZTOAD (compatible 4.6c)
Télécharger ZTOAD (compatible 4.7+)

Tags: , , , , ,