*----------------------------------------------------------------------
*  Programme     : ZSF_CSV2BDD3
*  Objectif      : insert into (p_table) file (p_name)
* ---------------------------------------------------------------------
*  Nom l'auteur  : Sébastien FERRY
*  Création      : 15/05/2006
* ---------------------------------------------------------------------
*  Modifications : INTERDITES
*----------------------------------------------------------------------
 
report  zsf_csv2bdd3.
 

************************************************************************
*           TABLES                                                     *
************************************************************************
 
* Il n'y en a pas, et c'est là toute la puissance de ce programme
 

************************************************************************
*  TYPES                                                               *
************************************************************************
 
types: type_nom_champ(100)      type c
     , type_valeur_champ(1024)  type c
     , type_fichier_ligne(1024) type c
     .
 
************************************************************************
*  TABLES INTERNES                                                     *
************************************************************************
 
data : t_table_split      type standard table of type_valeur_champ
     , t_table_split_line like line of t_table_split
 
     , t_table_struc      type standard table of type_nom_champ
     , t_table_struc_line like line of t_table_struc
 
     , t_fichier      type standard table of type_fichier_ligne
     , t_fichier_line like line of t_fichier
     .
 
************************************************************************
*  DECLARATIONS                                                        *
************************************************************************
 
 
 
************************************************************************
*  SELECT-OPTIONS                                                      *
************************************************************************
 
* Nom du fichier à uploader
parameter p_name like rlgrap-filename
           obligatory default 'E:\xml\zvrp10_mapxml_so.csv'.
 
* Nom de la table à mettre à jour
parameter p_table like dd02l-tabname
           obligatory default 'ZVRP10_MAPXML_SO'.
 
* Suppression préalable ?
parameter p_delete as checkbox
           default ''.
 
* Séparateur
parameter p_split type c
           obligatory default ';'.
 

* Boite de dialogue de sélection de fichier
* Associée au paramètre "nom du fichier"
at selection-screen on value-request for p_name.
  call function 'F4_FILENAME'
       exporting
            program_name  = sy-cprog
            dynpro_number = sy-dynnr
            field_name    = 'P_NAME'
       importing
            file_name     = p_name.
 
************************************************************************
* START OF SELECTION                                                   *
************************************************************************
 
start-of-selection.
 
* 1) Vérification des paramètres
* 1.1) tables SPECIFIQUES seulement
  if p_table(1) <> 'Z'.
    write / 'SECURITE: gestion UNIQUEMENT des tables spécifiques Z*'.
    write: / 'table en paramètre: ', p_table.
    exit.
  endif.
 
* 1.2) Suppression des données de la table
*      seulement si un mandant est présent
  if p_delete = 'X'.
 
    data l_dd03l_mandt_count type i.
 
* DD03L = Zones de table
* < TABNAME*   : Nom de table
* < FIELDNAME* : Nom de zone
* < AS4LOCAL*  : Etat d'activation d'un objet du repository
* ! AS4VERS*   : Version de l'entrée (non utilisée)
* ! POSITION*  : Position de la zone dans la table
 
    select count(*)
    into   l_dd03l_mandt_count
    from   dd03l
    where  tabname   = p_table
    and    fieldname = 'MANDT'
    and    as4local  = 'A' " Actif
    .
 
    if l_dd03l_mandt_count <> 1.
      write / 'SECURITE: Suppression UNIQUEMENT des tables avec MANDT'.
      write: / 'table en paramètre: ', p_table.
      exit.
    endif.
 
  endif.
 
* 2) Ouverture et lecture du fichier
 
  call function 'WS_UPLOAD'
       exporting
            filename            = p_name
            filetype            = 'ASC'
       tables
            data_tab            = t_fichier
       exceptions
            conversion_error    = 1
            file_open_error     = 2
            file_read_error     = 3
            invalid_table_width = 4
            invalid_type        = 5
            no_batch            = 6
            unknown_error       = 7
            others              = 8.
 
* 2.1) Gestion des erreurs liées au fichier
  if sy-subrc <> 0.
 
    data l_err_msg(64) type c.
    case sy-subrc.
      when 1. l_err_msg = 'conversion_error '.
      when 2. l_err_msg = 'file_open_error '.
      when 3. l_err_msg = 'file_read_error '.
      when 4. l_err_msg = 'invalid_table_width '.
      when 5. l_err_msg = 'invalid_type '.
      when 6. l_err_msg = 'no_batch '.
      when 7. l_err_msg = 'unknown_error '.
      when 8. l_err_msg = 'OTHERS '.
    endcase.
 
    write : / 'ERREUR AVEC WS_UPLOAD'
          , sy-subrc
          , l_err_msg.
 
    exit.
  endif.
 
  write:/ 'Fichier chargé:', p_name.
 
* 3) Création d'une ligne du type de la table en paramètre DYNAMIQUE
 
  field-symbols : <fs_data_line>  type any.
  data : t_data_line type ref to data .
 
  create data t_data_line type (p_table).
  assign t_data_line->* to <fs_data_line>.
 

* 4) Parcours des lignes du fichier
*    (via la table interne renvoyée par WS_UPLOAD)
 
* 4.1) Lecture des champs de l'entête
*      Correspond à la première ligne du fichier
 
  read table t_fichier index 1
  into t_fichier_line.
 
  if sy-subrc <> 0 .
    write / 'ERREUR: lecture des champs d''entête'.
    exit.
  endif.
 
  split t_fichier_line at p_split
  into table t_table_struc.
 
  if sy-subrc <> 0 .
    write / 'ERREUR: split des champs d''entête'.
    exit.
  endif.
 
* 4.2) Suppression des données de la table
*      (seulement si un mandant est présent)
  if p_delete = 'X'.
    delete from (p_table)
    where mandt = sy-mandt.
  endif.
 

* 4.3) Parcours des lignes de données du fichier
*      (à partir de la deuxième ligne <=> après la ligne d'entête)
  data l_struc_index type i.
  field-symbols <fs>.
 
  data l_sy_scols type i.
  l_sy_scols = sy-scols - 24.
 
  loop at t_fichier
  into t_fichier_line
  from 2 .
 
  clear <fs_data_line>.
 

* 4.2.1) Eclatement des champs CSV de données
 
  split t_fichier_line at p_split
  into table t_table_split.
 
  l_struc_index = 0.
 
*   Boucle sur les données
  loop at t_table_split
  into t_table_split_line.
 
*     Recherche du nom du champ de la table/structure correspondant
    l_struc_index = l_struc_index + 1.
 
    read table t_table_struc
    index l_struc_index
    into  t_table_struc_line.
 
    if sy-subrc <> 0.
*       fin de la table
 
      write : / 'AVERTISSEMENT: champ inconnu'
            , l_struc_index
            , ' (donnée ignorée)'
            .
      exit. " loop...
 
    else.
      assign component t_table_struc_line
             of structure <fs_data_line>
             to <fs>.
 
      if sy-subrc <> 0.
*         Erreur ?
        write : / 'AVERTISSEMENT: destination inconnue'
              , t_table_struc_line
              , ' (donnée ignorée)'
              .
      else.
        if t_table_struc_line = 'MANDT'.
*           Cas particulier du mandant (utilisation du mandant courant)
          t_table_split_line = sy-mandt.
        endif.
 
        <fs> = t_table_split_line.
 
        write : / t_table_struc_line(16)
              , ' = ', t_table_split_line(l_sy_scols).
 
      endif. " ASSIGN COMPONENT ... OF <> TO <fs> / sy-subrc <> 0
 

    endif. " READ TABLE t_table_struc / sy-subrc <> 0
 
  endloop. " at t_table_split
 
* 4.3) Ajout dans la table
 
  insert into (p_table) values <fs_data_line>.
 
*  write : / <fs_data_line>.
  write : /.
 
endloop. " at t_fichier