Les annonces de la TR1 de la 7.5 ou TR7 de la 7.4 sont sorties et disponibles ici https://www.ibm.com/support/pages/node/1119129/


• Voici selon nous 5 nouveautés à suivre dans cette Technology Refresh

• 1) La possibilité de faire des mises à jour sur des flux json avec la fonction JSON_UPDATE , ça fait longtemps que nos équipes râlaient, parce qu’elles devaient faire du bricolage quand on travaillait sur du flux json.


• 2) La possibilité d’exécuter des fonctions table remote, par exemple avec le service REMOTE TABLE, un object_statistics sur une partition distante. Ça peut avoir du sens pour automatiser des contrôles de cohérence.


• 3) Les nouvelles fonctions table, SYSTOOLS.AUDIT_JOURNAL_xx qui permettent de traiter les postes d’audit et plus globalement les nouveautés sur les audits comme la disponibilité d’IDS dans Navigator for i qui n’était pas présent dans la nouvelle interface.


• 4) SELF (SQL Error Logging Facility) qui va permettre de mettre au point les traitements SQL en attrapant de manière plus fine les erreurs et en pouvant les suivre dans le temps sans passer par un mode de debug parfois trop bavard en log.


• 5) Les nouveaux services pour administrer Object Connect (vous savez les commandes SAVRSTxxx, CHANGE_OBJECTCONNECT et OBJECTCONNECT_INFO), un petit rappel, Object Connect peut désormais fonctionner en IP. Disponible par PTF et c’est la dernière fonction SNA qui n’avait pas d’équivalent ip. Ces nouveaux services permettront d’administrer et d’avoir des informations sur ce qui s’exécute dans les échanges inter-machines.


• Rendez-vous en décembre pour les premiers tests.

, , , Date source de vos programmes

On est amené quand on fait des analyses à regarder les dates de source, on constate que ces dates sont à null pour tous les objets de type ILE.

Vous avez une vue QSYS2.PROGRAM_INFO qui permet d’avoir ces informations sur les programmes, un peu comme la commande DSPPGM.

Voici pourquoi : quand vous travaillez en OPM vous compilez des sources qui deviennent des programmes; quand vous travaillez en ILE, vous compilez des sources qui deviennent des modules, puis vous les assemblez pour créer des programmes et du coup une date de source sur un programme ILE ne veut rien dire.

En réalité un programme a un module qui s’appelle point d’entrée programme qui, quand on travaille en BND (CRTBND*), est le seul module placé dans qtemp qui est assemblé pour créer votre programme.

On voit donc que si on veut, on peut assimiler la date du source du programme à la date du module PEP, qui dans plus de 99 % des cas a le même nom que le programme.
On a une deuxième vue permet d’avoir les modules par programme, QSYS2.BOUND_MODULE_INFO.

Il faudra donc combiner les 2 vues.

par exemple :

  • Pour les programmes ILE

SELECT a.PROGRAM_NAME, a.PROGRAM_TYPE, b.SOURCE_FILE_LIBRARY, b.SOURCE_FILE,
b.SOURCE_FILE_MEMBER, b.SOURCE_CHANGE_TIMESTAMP
FROM QSYS2.PROGRAM_INFO A join QSYS2.BOUND_MODULE_INFO B
on a.PROGRAM_NAME = b.PROGRAM_NAME
and A.PROGRAM_NAME = b.BOUND_MODULE and A.PROGRAM_LIBRARY = b.PROGRAM_LIBRARY
WHERE a.PROGRAM_LIBRARY = ‘FADY’ and a.PROGRAM_TYPE = ‘ILE’

  • Pour les programmes OPM

SELECT a.PROGRAM_NAME, a.PROGRAM_TYPE, A.SOURCE_FILE_LIBRARY, A.SOURCE_FILE, A.SOURCE_FILE_MEMBER,
A.SOURCE_FILE_CHANGE_TIMESTAMP
FROM QSYS2.PROGRAM_INFO A
WHERE a.PROGRAM_LIBRARY = ‘FADY’ and a.PROGRAM_TYPE = ‘OPM’

en faisant l’union des deux requêtes vous aurez les dates de tous vos programmes ILE et OPM.

Il y a sans doute d’autres solutions mais celle-ci est très simple à utiliser.

, , Droits SQL sur les Zones

On m’a récemment demandé comment savoir si un fichier était couvert par des droits SQL sur les zones

J’ai d’abord pensé que la fonction table QSYS2.OBJECT_PRIVILEGES allait me rendre ce service !

donc j’ai lancé cette requête pour analyser mon fichier

Exemple :

SELECT *
FROM TABLE(QSYS2.OBJECT_PRIVILEGES(‘MABASESQL’, ‘CLIENTS’, ‘*FILE’));

et je n’ai pas trouvé l’information dans les zones renvoyées

puis j’ai essayé avec les commandes historiques en sortie de fichier ici DSPOBJAUT

Exemple :

DSPOBJAUT OBJ(MABASESQL/CLIENTS)
OBJTYPE(FILE) OUTPUT(OUTFILE)
OUTFILE(MABASESQL/LSTAUT)

Select * from MABASESQL.lstaut

et la on a le résultat qui l’indique
ZONE OAOBJA à ‘USER DEF’ et une ZONE des DATA ici OAUPD à ‘/’

En résumé

On ne sait pas par SQL, mais on sait faire par une sortie fichier historique


Oui je sais , on peut trouver l’information par des vues spécifiques dans QSYS2 et SYSIBM

Vous avez d’abord la vue SYSIBM.SQLCOLPRIVILEGES mais attention, vous avez toutes les autorisations sur la zone y compris celles qui correspondent à un *CHANGE sur le fichier par exemple.


exemple :

Select * from SYSIBM.SQLCOLPRIVILEGES
where TABLE_SCHEM = ‘MABASESQL’ and TABLE_NAME = ‘CLIENTS’

order by column_name, grantee


Ou mieux la vue QSYS2.COLUMN_PRIVILEGES qui ne contient que les zones avec des autorisations spécifiques

exemple

Select * from QSYS2.COLUMN_PRIVILEGES
where TABLE_SCHEMA = ‘MABASESQL’ and TABLE_NAME = ‘CLIENTS’

j’ai donc fait une RFE pour avoir l’information dans la fonction table QSYS2.OBJECT_PRIVILEGES

Si vous êtes intéressés votez pour moi c’est ici https://2e4ccba981d63ef83a875dad7396c9a0.ideas.aha.io/ideas/RIRP-I-1260

Je vous indiquerais la réponse d’IBM sur le sujet

, RDi : configurer et déployer les Actions de l’utilisateur

Les actions utilisateur vous permettent d’exécuter des commandes préformatées sur les objets ou sur les membres de vos filtres, en utilisant le clic droit pour exécuter l’action.

Elles sont équivalentes aux options définies par l’utilisateur que l’on peut gérer par F16 sous PDM.

Gérer les actions de l’utilisateur

La gestion des actions utilisateur est accessible par clic droit sur les objets ou membres des filtres.

Créer une action objet

Nous allons créer une action pour exporter une table vers l’IFS au format CSV.

L’action utilisera la commande CPYTOIMPF que nous allons préformater.

Le bouton « Insérer une variable » affiche la liste des variables que nous allons pouvoir utiliser dans les paramètres de la commande pour substituer les attributs de l’objet sur lequel l’action s’exécute :

Le bouton « Invite » permet d’afficher l’invite de commande pour compléter les paramètres :

La case « Interroger d’abord » permettra d’afficher l’invite de commande lors de l’utilisation de l’action.

Enfin, il est conseillé d’indiquer les types de ressources pour lesquelles cette action sera proposée dans le clic droit :

Une fois créée, l’action apparait dans le catalogue des actions Objet :

Elle peut être utilisée par clic droit sur un objet de type fichier :

L’invite de commande est affichée avec les valeurs de substitution des variables utilisées :

Le message d’exécution de l’action s’affiche dans l’historique des commandes de RDI :

Le fichier CSV est créé dans l’IFS :

Créer une action membre

Nous allons créer une action permettant de convertir un membre source RPG 4 en RPG FREE.

Pour cela, nous avons créé une commande CVTRPGFREE basée sur un convertisseur Open Source auquel GAIA contribue.

Pour limiter l’action au membres sources de type RPGLE et SQLRPGLE, nous allons Editer la liste des Types définis et créer un Type défini que nous nommerons RPGLE et qui rassemblera les types de membre RPGLE et SQLRPGLE :

Le fenêtre « Gérer les types nommés » s’ouvre :

Le bouton « Parcourir » permet de choisir les types de membre existants pour les ajouter à la liste :

Le nouveau Type défini « RPGLE » s’affiche dans la liste des types de membres définis :
On peut maintenant l’utiliser pour notre action :

Une fois créée, l’action apparait dans le catalogue des actions Membre :

Elle peut être utilisée par clic droit sur un membre de type RPGLE ou SQLRPGLE pour le convertir en RPG FREE :

Le message d’exécution de l’action s’affiche dans l’historique des commandes de RDI :
Le membre PGMRPGFREE a été créé avec la conversion en RPG FREE du membre initial PGMRPG4 :

Notons qu’en effectuant une sélection de plusieurs ressources dans un filtre, on peut exécuter une action utilisateur sur toutes ces ressources par un seul clic droit.

Exemple ci-dessous : on peut exporter 4 fichiers vers l’IFS au format CSV en un seul clic

Exporter/Importer les actions utilisateur

Les actions utilisateur peuvent être exportées vers un fichier de configuration à partir du menu

Fichier > Exporter > Rational Developer for i :

2 modes d’exportation sont possibles :

  • l’export « Fichier de configuration » permet d’exporter la configuration vers un fichier local, qui pourra si on le souhaite être partagé et importé par d’autres utilisateurs vers leur Workspace.
  • l’export « Fichier de configuration pour distribution automatique » permet d’exporter la configuration pour la distribuer automatiquement aux autres utilisateurs

Exporter Fichier de configuration pour distribution automatique

Pour exporter les actions utilisateur, décocher toutes les cases et ne conservez que la configuration « Artefacts de systèmes distants ».

Les filtres sont exportés, lors de l’import vous perdrez donc les filtres de votre Workspace.

Ca peut être gênant, mais ça peut aussi être l’occasion de faire du ménage dans vos filtres….

Le fichier de configuration sera généré dans le répertoire suivant de l’IFS :

/QIBM/ProdData/Devtools/clientconfig

Choisissez un numéro de version pour identifier le fichier de configuration :

Avant de Terminer, assurez-vous d’avoir les droits d’écriture dans le répertoire de destination.

Le fichier de configuration est généré dans l’IFS pour une distribution automatique de cette configuration :

Lorsque les utilisateurs se connecteront à l’IBM i, une fenêtre d’importation leur sera automatiquement proposée :

L’import peut être accepté (OK) ou pas (Annuler) mais tant qu’il n’aura pas été accepté, il sera reproposé à chaque connexion à l’IBM i par RDI.

C’est terminé !

PS :

Si le fichier de configuration a été exporté vers un fichier local par l’export Fichier de configuration au lieu de Fichier de configuration pour distribution automatique, il peut être importé de la même manière par le menu Fichier > Importation > Rational Developer for i > Fichiers de configuration. Il suffit d’indiquer l’emplacement du fichier de configuration, ensuite la procédure est identique à celle de la distribution automatique :

Toutes les instructions SQL contenues dans un programme – mais pas les CL – sont écrites dans qsys2.sysprogramstmtstat; qu’on ait le source du programme ou pas.
En plus de stocker l’instruction, on accède à d’autres informations comme le nombre d’exécutions, le nombre de variables hôtes …
DSPPGMREF référence l’utilisation de fichier par SQL de façon très succincte, on accède à bien plus de détails
en explorant QSYS2.SYSPROGRAMSTMTSTAT.

On peut visualiser directement les différentes instructions :

Si on n’est intéressé que par les tables écrites dans les instructions contenues dans un programme, il faut filtrer. On utilise la fonction table qsys2.parse_statement qui sait parser le SQL. Cette dernière, pour faire le travail, a besoin d’informations supplémentaires contenues dans
qsys2.sysprogrammstat :

  • convention de nommage
  • séparateur décimal
  • délimitateur de chaine

Cela donne la requête :

WITH program_statements(naming_mode, dec_point, string_delim, stmt_text, stmt_nbr, system_program_name, program_type) AS
(SELECT a.naming,
a.decimal_point,
a.sql_string_delimiter,
b.statement_text,
b.statement_number,
a.system_program_name,
a.program_type
FROM qsys2.sysprogramstat a
INNER JOIN qsys2.sysprogramstmtstat b
ON a.program_schema = b.program_schema
AND a.program_name = b.program_name
AND a.module_name = b.module_name
WHERE a.number_statements > 0
AND a.program_schema = ‘GCOMPARE’
AND a.program_name =’COMPARE1′ )
SELECT system_program_name,
program_type,
c.schema,
c.name,
stmt_nbr,
stmt_text
FROM program_statements,
TABLE(qsys2.parse_statement(stmt_text, naming_mode, dec_point, string_delim)) c
WHERE c.name_type = ‘TABLE’
ORDER BY stmt_nbr,
c.schema,
c.name;

On peut modifier cette dernière requête en indiquant une liste de bibliothèques pour a.program_schema.
En la planifiant régulièrement et en récupérant son resultset dans un fichier, on pourra voir rapidement les utilisations connues d’une table.

Malheureusement (ou pas) les « Execute Immediate :var » n’indiquent pas ce qu’elles contiennent …

, CONTROLER IBAN & RIB

L’International Bank Account Number, généralement nommé sous l’acronyme IBAN, est un système international de numérotationLe numéro IBAN, ou code IBAN, est affiché sur votre Relevé d’Identité Bancaire (RIB). Formalisé par une suite de chiffres et de lettres pas toujours compréhensibles pour les usagers bancaires, l’IBAN est une norme internationale ISO qui a été mise en place pour sécuriser et faciliter les échanges et transferts bancaires internationaux sur tous les continents.

Dans cet article nous allons voir comment vérifier si la clé d’un IBAN est correcte. Ensuite nous effectuerons la vérification de la clé d’un RIB. Les exemples sont basés sur un compte bancaire français.

Contrôler la clé IBAN

Structure de l’IBAN

FRKK BBBB BGGG GGCC CCCC CCCC CKK

B = code banque
G = code guichet
C = numéro de compte
K = clef

Le RIB (ou BBAN) comprend les informations suivantes :

– Le nom de la banque et de l’agence;
– Le code banque à 5 chiffres;
– Le code guichet à 5 chiffres ;
– Le numéro du compte à 11 chiffres ou lettres au maximum;
– La clé RIB, à 2 chiffres.

Le calcul de la clé IBAN est fonction de l’enchaînement entre le BBAN, le code pays (transformé en données chiffrées) et 00.
Concernant la conversion du code pays, il faut savoir que la lettre A équivaut au nombre 10, B = 11, C = 12, D = 13… jusqu’à la dernière lettre de l’alphabet Z qui vaut 35.


La formule arithmétique pour résoudre l’équation et déterminer une clé IBAN est :

Clé IBAN = 98 – ((Valeur numérique) modulo 97).

Il faut donc procéder en deux étapes :

  • Reconstituer l’IBAN sous la forme BBAN + [Code Pays ISO2] + « 00 »
  • Remplacer toutes les lettres de l’IBAN par le nombre qui leur correspond (entre 10 et 35)

Voici une procédure, écrite dans un programme de service, qui permet la vérification de la clé d’un IBAN.

dcl-proc checkIban export;
  dcl-pi *n ind;
    numIban char(27) const;
  end-pi;

  dcl-s count int(3) ;
  dcl-s index int(3) ;
  dcl-s posit int(3) ;
  dcl-s stringToCalculate varchar(50) ;
  dcl-c letters    'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ;

  stringToCalculate = %subst(numIban:5) + %subst(numIban:1:2) + '00';

  for count = 1 to %len(%trim(stringToCalculate)) ;
    index = %scan(%subst(stringToCalculate:count:1):letters) ;
    if index > 0 ;
      posit = count - 1 ;
      index += 9 ;
    
      stringToCalculate = %subst(stringToCalculate : 1 : posit)
                        + %trim(%char(index))
                        + %subst(stringToCalculate : posit + 2) ;
    endif ;
  endfor;

  return (98 - %rem(%DEC(%trim(stringToCalculate) : 50 : 0):97)
         = %DEC(%SUBST(numIban : 3 : 2) : 2 : 0)) ;

end-proc;                       

Ajouter le code suivant dans le source de liage

EXPORT     SYMBOL("CHECKIBAN") 

Utilisation du contrôle

// Déclaration
dcl-PR checkIban ind ;
 P_Iban char(27) const;
end-pr ;         

// Appel
 retour = checkIban('FR3330002005500000157841Z25');
  if retour;
    dsply 'IBAN Correct' ;
  else ;
    dsply 'IBAN Faux' ;
  endif;  

Contrôler la clé RIB

Structure du RIB (voir paragraphe précédent, c’est un composant de l’IBAN)

Le numéro de RIB permet l’identification du compte pour une utilisation Nationale. C’est le numéro à transmettre pour effectuer un virement en France.

La clé RIB est une formule mathématique, qui ne peut s’appliquer que sur des valeurs numériques. Il convient donc de remplacer les éventuelles lettres présentes dans les données du RIB avant de pouvoir en calculer la clé.

Chaque lettre est remplacée par son équivalent numérique :

A,J = 1

B,K,S = 2

C,L,T = 3

D,M,U = 4

E,N,V = 5

F,O,W = 6

G,P,X = 7

H,Q,Y = 8

I,R,Z = 9

La clé peut alors être calculée avec la formule suivante :

Clé RIB = 97 – ( ( 89 x Code banque + 15 x Code guichet + 3 x Numéro de compte ) modulo 97 )

Voici une procédure, écrite dans un programme de service, qui permet la vérification de la clé d’un RIB.

dcl-proc checkRib export;
  dcl-pi *n ind;
    numRib char(23) const ;
  end-pi;

  dcl-s count int(3) ;
  dcl-s index int(3) ;
  dcl-s posit int(3) ;
  dcl-s stringToCalculate varchar(23) ;
  dcl-c letters    'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ;

  stringToCalculate = numRib ;

  for count = 1 to %len(%trim(stringToCalculate)) ;
    index = %scan(%subst(stringToCalculate:count:1) : letters) ;
    if index > 0;
      posit = count - 1 ;
      select ;
        when index >= 10 and index <= 18 ;
          index -= 9 ;
        when index >= 19 ;
          index -= 17 ;
      endsl ;

      stringToCalculate = %subst(stringToCalculate : 1 : posit)
                        + %trim(%char(index))
                        + %subst(stringToCalculate : posit + 2) ;
    endif ;
  endfor ;

  return (97 - %rem(
                  (%DEC(%subst(stringToCalculate:1:5) : 5 : 0)*89
                  + %DEC(%subst(stringToCalculate:6:5) : 5 : 0)*15
                  + %DEC(%subst(stringToCalculate:11:11) : 11 : 0)*3)
                    :97)
          = %DEC(%SUBST(stringToCalculate : 22 : 2) : 2 : 0)) ;

end-proc;  

Ajouter le code suivant dans le source de liage

EXPORT     SYMBOL("CHECKRIB") 

Utilisation du contrôle

// Déclaration
dcl-PR checkRib ind ;
 P_Rib char(23) const ;
end-pr ;               

// Appel
retour = checkRib('3000200550044AB57O41Z68') ;
  if retour;
    dsply 'RIB Correct'  ;
  else ;
    dsply 'RIB Faux' ;
  endif; 
, Exemples SQL personnalisés sur ACS

Lorsque l’on travaille sur une belle requête SQL, nous avons tendance à la garder et la sauvegarder en local sur notre poste (parfois dans l’IFS). Pour la partager à un collègue quoi de mieux qu’un bon vieux mail ?

Ou alors, on peut exploiter les Exemples personnalisés d’ACS pour mutualiser nos découvertes !

Exemples SQL sur ACS

Via l’Exécuteur de scripts SQL d’ACS, une multitude d’exemples est fournie.
Pour y accéder trois possibilités :

  • Edition > Exemples > Insertion à partir d’exemples…
  • Ctrl + I
  • Via la petite icône SQL avec les deux flèches ci-dessous

On y retrouve tout un catalogue d’exemples relativement bien fourni :

Il suffit de rechercher les mots clés qui nous intéressent puis de cliquer sur Insertion, et enfin de remplacer les données variables de la requête.

Ajouter ses exemples personnalisés

Création d’un répertoire dans l’IFS

La première étape consiste à créer un répertoire commun dans l’IFS, le plus simple est de le créer dans /home/ qui est généralement déjà configuré comme partagé (donc visible pour Windows).
Par la suite nous utiliserons le chemin suivant : /home/exemples_sql/.
C’est ici que nous travaillerons pour créer nos exemples personnalisés.

Création d’un exemple

Il suffit de créer un nouveau source SQL, par exemple via ACS :

-- category: Exemples perso
-- description: Recherche d'un fichier dans l'ifs
SELECT *
  FROM TABLE (
      qsys2.ifs_object_statistics(start_path_name => '/')
  )
 WHERE path_name LIKE '%fichier.txt';

Le commentaire category permet de trier et regrouper vos exemples par usages.
Le commentaire description correspond au texte indiqué dans la liste des exemples.

Une fois l’exemple terminé il suffit de sauvegarder le script dans le répertoire de l’IFS choisi : Fichier > Sauvegarde sous… > Fichier STREAM IFS.

Il est bien entendu toujours possible de modifier ou supprimer des exemples à partir de ce répertoire.

Intégration du répertoire d’exemples à ACS

Dans un onglet d’ACS, ouvrir le menu des exemples : Edition > Exemples > Insertion à partir d’exemples…
Puis cliquer sur Préférences…

Cliquer ensuite sur Ajout

Indiquer ici le chemin vers le répertoire de l’IBM i qui contient les exemples SQL : \\<Nom de l’IBM i>\home\exemples_sql

Les exemples sont maintenant dans la liste avec les autres.
Ils sont triés par catégorie (que l’on retrouve juste en dessous de la mire de recherche).
Ils sont listés en dessus par description et un aperçu est disponible à droite.

Pour retrouver des exemples deux possibilités :

  • Choisir la catégorie à afficher en cliquant sur la catégorie actuelle (ici Exemples perso)
  • Utiliser la mire de recherche, qui affichera les exemples correspondant aux mots clés, toutes catégories confondues

Pour plus de détails

Exemples SQL de Birgitta Hauser : https://gist.github.com/BirgittaHauser
Exemples SQL de Scott Forstie : https://gist.github.com/forstie
, , /Include contre /Copy

On entend beaucoup de choses, je vais essayer de vous clarifier un peu les choses

Les directives /COPY et /INCLUDE sont identiques sauf qu’elles sont gérées différemment par le précompilateur SQL, en gros si vous codez avec un Source en SQLRPGLE.

Sur la commande CRTSQLRPGI vous avez le paramètre RPGPPOPT
Permet d’indiquer si le compilateur ILE RPG va être appelé pour prétraiter le membre source avant lancement de la
précompilation SQL. Cette étape sur le membre source SQL permet de traiter certaines instructions de compilation
avant la précompilation SQL. Le source prétraité est placé dans le fichier QSQLPRE de la bibliothèque QTEMP.
Il servira à la précompilation SQL. puis à la complilation RPGLE

3 valeurs possibles sont :
*NONE
Le compilateur n’est pas appelé pour le prétraitement.
*LVL1
Le compilateur est appelé pour le prétraitement afin de développer /COPY et traiter les instructions de compilation conditionnelles à l’exception de /INCLUDE.
*LVL2
Le compilateur est appelé pour le prétraitement afin
de développer /COPY et /INCLUDE et traiter les instructions de compilation conditionnelles

voici un exemple
Un module utilise la description d’un fichier qui est dans un include

le source à inclure

sa déclaration dans le programme ou le module

.

Compile avec *NONE

Compile avec *LVL2

Remarque
Si vous faites du SQLRPGLE, ce qui est fortement recommandé à ce jour forcer cette valeur *LVL2 comme ca pas de doute !

Une petite explication sur les fichiers ACS et leur extension, et les migrations possibles à partir des fichiers de Client Access

Pour les fichiers de définition de session

Les fichiers, KMP, PMP, BAR, MAC ont la même extension, mais ne sont pas compatibles, vous devrez les migrer par l’outil de migration .

Gestionnaire de sessions / fichier / importer

Pour les transferts de fichiers

Vous pouvez ouvrir un fichier DTF par ACS et l’enregistrer en DTFX, la migration est automatique

On n’a pas d’outil pour migrer les descriptions de fichier FDX, vous devrez les recréer ou modifier le source, il y a peu de différences

Résumé

On sait migrer les sessions, les claviers, les transferts les macros **

Pour les fichiers macros, vous ne pourrez migrer que ce qui a été enregistré et non codé

Mais ca peut être l’occasion de faire le ménage de reprendre propre.

**