Trucs et Astuces - AS400 - Tips and Tricks

page d'accueil   Boite à outils

 

CCSID Table des matières

2013-12-11, + links updated

Le CCSID (ou code page) est un numéro de table de correspondance qui donne pour un caractère donné, la valeur hexadécimale et le "dessin" de ce caractère à l'écran (ou sur papier). Il est défini un peu partout et utilisé en permanence.

Notions associées

Le CCSID est un jeu de valeurs hexadécimales associant un code hexa (ou code point) à une représentation humaine. exemples : en CCSID 297, le "A" est codé x'C1'. En CCSID 850, le "A" est codé x'41'.

Un CCSID donné associe une liste de valeurs hexadécimales à une liste "d'images". Cette liste s'appelle un Character Set

Le Character Set le plus court est celui qui définit la liste des caractères invariants, c'est à dire qu'ils sont présents dans tous les character sets - enfin, presque tous, il y a des exceptions-.

L'alphabet invariant est le suivant : 0 1 2 3 4 5 6 7 8 9 - % & ( ) * , . / : ; ? _ ’ “ + < = > a A b B c C d D e E f F g G h H i I j J k K l L m M n N o O p P q Qr R s S t T u U v V w W x X y Y z Z. il s'agit du CCSID 640 (CCSID = Character Set = Jeu de caractères)

ccsid 640: https://www.ibm.com/docs/en/i/7.3?topic=sets-syntacticinvariant-character-set-00640

all code page at IBMi: https://www.ibm.com/docs/en/SSEQ5Y_5.9.0/com.ibm.pcomm.doc/reference/pdf/hcp_referenceV58.pdf

Le schéma d'encodage (ou Encoding Scheme) décrit les règles générales utilisées pour coder les CCSID.
Les schéma d'encodage sont :

More on CCSID :

 

 

Le CCSID est un paramètre 

Par défaut

Remarque : un programme n'a pas de CCSID. Il adopte celui de son travail

Aujourd'hui, la plupart des écrans-claviers sont émulés par Client Access (de IBM), Rumba (de WallData), Mosha (de ?), ... Ces logiciels offrent souvent plusieurs CCSID dans leurs paramètres. Mais, sur un AS400, il reste souvent un écran Twinax par ci par là, le dernier étant la console système.

Chaque fois qu'un programme veut traiter une information, le travail recherche cette information et applique les transformations nécessaires pour que les données prises avec le CCSID de l'objet de départ soient présentées au programme dans le CCSID du travail.

Juste que là, tout va bien.

Le CCSID 65535 (*HEXA de son petit nom) signifie "Touche à rien, je m'occupe de tout". Ou plus sérieusement il est sensé interdire au système de transformer quoi que ce soit. Cette valeur est là pour permettre la compatibilité ascendante, c'est donc la valeur par défaut depuis que la notion de CCSID est apparue (OS400 V3.05). Dans cette configuration, le { américain est présenté é sur un écran français.

Quelques CCSID

273 EBCDIC, GERMANY FR AUSTRIA
277 EBCDIC, DENMARK NORWAY
278 EBCDIC, FINLAND SWEDEN
280 EBCDIC, ITALY
284 EBCDIC, SPAIN LATIN AMERICA
285 EBCDIC, UNITED KINGDOM
871 EBCDIC, ICELAND
037 EBCDIC, USA CANADA CCSID037.JPG
297 EBCDIC, FRANCE CCSID297.JPG
1147 EBCDIC, FRANCE Euro (à la place de l'oreiller (¤))
500 EBCDIC, MULTILINGUAL # 5 europe de l'ouest CCSID500.JPG
850 ASCII, PC DOS CCSID850.JPG
1252 ANSI, Windows ECMA latin 1 + signe euro
1208 UTF-8 http://en.wikipedia.org/wiki/UTF-8
1200 UTF-16 http://en.wikipedia.org/wiki/UTF-16                
13488 UCS-2

La liste intégrale des CCSID gérés par l'AS400 est sur le site IBM de documentation AS400 : http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/db2/rbafzmst180.htm ou http://www-03.ibm.com/servers/eserver/iseries/software/globalization/

Là où ça commence à devenir amusant, c'est que cette valeur par défaut (65535=*HEXA) est incompatible avec pas mal de fonctions vitales, à commencer par la copie de fichier. Donc CPYF se fout un peu du CCSID du travail et juge lui-même s'il doit traduire les informations ou pas. Il le fait avec plus ou moins de bonheur, ce bonheur dépendant du CCSID de départ, du CCSID d'arrivée, du CCSID du travail et de la disponibilité de tables de conversion directe ou indirecte (pour passer du CCSID 037 au CCSID 297, il peut être nécessaire de passer par le CCSID 500). Si CPYF doit mettre en oeuvre plus de 2 tables de conversion il s'en sort rarement sans dégâts. Personnellement je trouve que c'est déjà une belle performance.

Là où ça devient un feu d'artifice, c'est quand on commence à utiliser les fichiers sur IFS (objet *STMF). On peut obtenir des résultats hallucinants si la machine est restée  en ccsid 65535. J'ai réussi (bien malgré moi ...) à produire un fichier "bloc-notes" avec de l'EBCDIC à l'intérieur ! C'est surprenant. C'est encore plus surprenant quand l'affichage est correct si on le consulte directement dans l'AS400 par WRKLNK. Evitez d'écrire dans un fichier IFS depuis un programme RPG avant d'avoir touché du doigt les méandres des CCSID.
Depuis, j'ai trouvé pas mal de moyens différents d'écrire correctement des données valides dans les fichiers IFS (How to make a PDF file with RPG; How to make an EXCEL file with RPG)

Quelques expériences enrichissantes

sur la base d'un fichier quelconque contenant du texte avec des caractères accentués, dupliquer le fichier, jouer avec CHGPF et CPYF, consulter ensuite le fichier cible, avec DSPPFM (en clair et en hexa) puis avec RUNQRY.

DSPPFM respecte en priorité le fichier source, RUNQRY respecte en priorité le CCSID du travail. Dans certaines configurations l'affichage en clair sera différent. Tout le problème est dans la maitrise des effets des différents outils en fonction de l'ordre dans lequel on les utilise.

Initialiser le fichier de base


*************** Beginning of data *************************************
                R EBCDICF                                             
                  EBCDIC        16A         COLHDG('EBCDIC')          
****************** End of data ****************************************
CRTPF FILE(JPLTOOLS/EBCDICP) SRCFILE(JPLTOOLS/JPLTOOLS) SIZE(*NOMAX) 
RUNSQLSTM SRCFILE(JPLTOOLS) SRCMBR(EBCDICDATA)         

===> dspfd ebcdicp 
Fichier. . . . . . . . . . . . . . . . . . : FILE EBCDICP 
  Bibliothèque . . . . . . . . . . . . . . : *LIBL 
ID codé de jeu de caractères . . . . . . . : CCSID 65535   
 ===> dspffd ebcdicp
Info fichier
Fichier . . . . . . . . . . . . . . . . . . : EBCDICP
Bibliothèque . . . . . . . . . . . . . . : JPL
Information format
Format d'enregistrement . . . . . . . . . . : EBCDICP
Informations de niveau zone
Type Long Long Position Usage En-tête
Zone données zone tampon tampon zone colonne
EBCDICP ALPHA 16 16 1 E/S
ID codé de jeu de caractères . . . . . : 65535

Faire autant de fichier de travail que necessaire

Charger ces fichiers

Du fait que le fichier de depart est en 65535, il n'y a en théorie pas de conversion et chaque fichier contient un code hexa complet correct.

Mesure d'impact : vérifier le contenu de EBCDICP037 par DSPPFM, en clair et en hexa, puis par RUNQRY


===> dsppfm ebcdicp                                                            
                                                                                
                           Membre de fichier physique                                                                               
 Fichier  . . . . :   EBCDICP             Bibliothèque . . :   JPL                                                                  
 Membre . . . . . :   EBCDICP             Enregistrement . :   1                                                                    
 Contrôle . . . . .                       Colonne  . . . . :   1                                                                    
 Recherche  . . . .                                                                                                                 
 * . . .  + . . .  . 1 . .  . . + .                                                  *...+....1....+.                               
 40414243 44454647 48494A4B 4C4D4E4F                                                *  âä@áãå\ñ°.<(+!                    *          
 50515253 54555657 58595A5B 5C5D5E5F                                                *&{êë}íîïìߧ$*);^                    *          
 60616263 64656667 68696A6B 6C6D6E6F                                                *-/ÂÄÀÁÃÅÇÑù,%_>?                    *          
 70717273 74757677 78797A7B 7C7D7E7F                                                *øÉÊËÈÍÎÏ̵:£à'="                    *          
 80818283 84858687 88898A8B 8C8D8E8F                                                *Øabcdefghi«»ðýþ±                    *          
 90919293 94959697 98999A9B 9C9D9E9F                                                *[jklmnopqrªºæ¸Æ€                    *          
 A0A1A2A3 A4A5A6A7 A8A9AAAB ACADAEAF                                                *`¨stuvwxyz¡¿ÐÝÞ®                    *          
 B0B1B2B3 B4B5B6B7 B8B9BABB BCBDBEBF                                                *¢#¥·©]¶¼½¾¬|¯~´×                    *          
 C0C1C2C3 C4C5C6C7 C8C9CACB CCCDCECF                                                *éABCDEFGHI­ôöòóõ                    *          
 D0D1D2D3 D4D5D6D7 D8D9DADB DCDDDEDF                                                *èJKLMNOPQR¹ûü¦úÿ                    *          
 E0E1E2E3 E4E5E6E7 E8E9EAEB ECEDEEEF                                                *ç÷STUVWXYZ²ÔÖÒÓÕ                    *          
 F0F1F2F3 F4F5F6F7 F8F9FAFB FCFDFEFF                                                *0123456789³ÛÜÙÚ                    *          
   

 


Fichier  . . . . :   EBCDICP037          Bibliothèque . . :   QTEMP             
 Membre . . . . . :   EBCDICP             Enregistrement . :   1                 
 Contrôle . . . . .                       Colonne  . . . . :   1                 
 Recherche  . . . .                                                              
 * . . .  + . . .  . 1 . .  . . + .                                                 *...+....1....+.                               
 40414243 44454647 48494A4B 4C4D4E4F                                                *  âä@áãå\ñ°.<(+!                    *          
 50515253 54555657 58595A5B 5C5D5E5F                                                *&{êë}íîïìߧ$*);^                    *          
 60616263 64656667 68696A6B 6C6D6E6F                                                *-/ÂÄÀÁÃÅÇÑù,%_>?                    *          
 70717273 74757677 78797A7B 7C7D7E7F                                                *øÉÊËÈÍÎÏ̵:£à'="                    *          
 80818283 84858687 88898A8B 8C8D8E8F                                                *Øabcdefghi«»ðýþ±                    *          
 90919293 94959697 98999A9B 9C9D9E9F                                                *[jklmnopqrªºæ¸Æ€                    *          
 A0A1A2A3 A4A5A6A7 A8A9AAAB ACADAEAF                                                *`¨stuvwxyz¡¿ÐÝÞ®                    *          
 B0B1B2B3 B4B5B6B7 B8B9BABB BCBDBEBF                                                *¢#¥·©]¶¼½¾¬|¯~´×                    *          
 C0C1C2C3 C4C5C6C7 C8C9CACB CCCDCECF                                                *éABCDEFGHI­ôöòóõ                    *          
 D0D1D2D3 D4D5D6D7 D8D9DADB DCDDDEDF                                                *èJKLMNOPQR¹ûü¦úÿ                    *          
 E0E1E2E3 E4E5E6E7 E8E9EAEB ECEDEEEF                                                *ç÷STUVWXYZ²ÔÖÒÓÕ                    *          
 F0F1F2F3 F4F5F6F7 F8F9FAFB FCFDFE3F                                                *0123456789³ÛÜÙÚ                    *          
   

 Maintenant, faire la manipulation inversée :

et refaire la mesure d'impact. Surprise ! les données du fichier ont été transformées de telle sorte que le code interne de chaque caractère fichier soit égal au code externe présenté sur l'écran DSPPFM (RUNQRY affiche autre chose ... je vous laisse le plaisir de la découverte). Ainsi, x'C0' = é en ebcdic 297 et { en ebcdic 037. Une fois traduit, on trouve x'51' en C0, et en x'C0' en 51.    


 Fichier  . . . . :   EBCDICP037          Bibliothèque . . :   QTEMP             
 Membre . . . . . :   EBCDICP             Enregistrement . :   1                 
 Contrôle . . . . .                       Colonne  . . . . :   1                 
 Recherche  . . . .                                                              
 * . . .  + . . .  . 1 . .  . . + .                                                 *...+....1....+.                               
 40414243 7C454647 E049904B 4C4D4E5A                                                *  âäàáãåçñ[.<(+§                    *          
 50C05253 D0555657 5859B55B 5C5D5EB0                                                *&éêëèíîïìß]$*);¢                    *          
 60616263 64656667 6869DD6B 6C6D6E6F                                                *-/ÂÄÀÁÃÅÇѦ,%_>?                    *          
 70717273 74757677 78A07AB1 447D7E7F                                                *øÉÊËÈÍÎÏÌ`:#@'="                    *          
 80818283 84858687 88898A8B 8C8D8E8F                                                *Øabcdefghi«»ðýþ±                    *          
 BA919293 94959697 98999A9B 9C9D9E9F                                                *¬jklmnopqrªºæ¸Æ€                    *          
 79BDA2A3 A4A5A6A7 A8A9AAAB ACADAEAF                                                *µ~stuvwxyz¡¿ÐÝÞ®                    *          
 4A7BB2B3 B4BBB6B7 B8B95F4F BCA1BEBF                                                *°£¥·©|¶¼½¾^!¯¨´×                    *          
 51C1C2C3 C4C5C6C7 C8C9CACB CCCDCECF                                                *{ABCDEFGHI­ôöòóõ                    *          
 54D1D2D3 D4D5D6D7 D8D9DADB DC6ADEDF                                                *}JKLMNOPQR¹ûüùúÿ                    *          
 48E1E2E3 E4E5E6E7 E8E9EAEB ECEDEEEF                                                *\÷STUVWXYZ²ÔÖÒÓÕ                    *          
 F0F1F2F3 F4F5F6F7 F8F9FAFB FCFDFE3F                                                *0123456789³ÛÜÙÚ                    *          
   

Vous êtes joueur ? Alors ajouter des combinaisons supplémentaires :

Finalement; je ne résiste pas au plaisir de vous montrer l'effet dans RUNQRY :

===> dspjob


                      Attributs de définition d'un travail                      
 Identificateur de langue  . . . . . . . . . . . . :   FRA                      
 ID de pays ou de région . . . . . . . . . . . . . :   FR                       
 ID de jeu de caractères codés . . . . . . . . . . :   65535                    
 ID codé de jeu de caractères par défaut . . . . . :   297                      
 Contrôle ID caractère . . . . . . . . . . . . . . :   *DEVD                    


 ===> dsppfm ebcdicp                                                            

                                                                                
 Fichier  . . . . :   EBCDICP             Bibliothèque . . :   JPL                                                                  
 * . . .  + . . .  . 1 . .  . . + .                                                  *...+....1....+.                               
 40414243 44454647 48494A4B 4C4D4E4F                                                *  âä@áãå\ñ°.<(+!                    *          
 50515253 54555657 58595A5B 5C5D5E5F                                                *&{êë}íîïìߧ$*);^                    *          
 60616263 64656667 68696A6B 6C6D6E6F                                                *-/ÂÄÀÁÃÅÇÑù,%_>?                    *          
 70717273 74757677 78797A7B 7C7D7E7F                                                *øÉÊËÈÍÎÏ̵:£à'="                    *          
 80818283 84858687 88898A8B 8C8D8E8F                                                *Øabcdefghi«»ðýþ±                    *          
 90919293 94959697 98999A9B 9C9D9E9F                                                *[jklmnopqrªºæ¸Æ€                    *          
 A0A1A2A3 A4A5A6A7 A8A9AAAB ACADAEAF                                                *`¨stuvwxyz¡¿ÐÝÞ®                    *          
 B0B1B2B3 B4B5B6B7 B8B9BABB BCBDBEBF                                                *¢#¥·©]¶¼½¾¬|¯~´×                    *          
 C0C1C2C3 C4C5C6C7 C8C9CACB CCCDCECF                                                *éABCDEFGHI­ôöòóõ                    *          
 D0D1D2D3 D4D5D6D7 D8D9DADB DCDDDEDF                                                *èJKLMNOPQR¹ûü¦úÿ                    *          
 E0E1E2E3 E4E5E6E7 E8E9EAEB ECEDEEEF                                                *ç÷STUVWXYZ²ÔÖÒÓÕ                    *          
 F0F1F2F3 F4F5F6F7 F8F9FAFB FCFDFE3F                                                *0123456789³ÛÜÙÚ                    *          
                         ****** FIN DES DONNEES ******                                                                              

 ===> dsppfm ebcdicp037

 Fichier  . . . . :   EBCDICP037          Bibliothèque . . :   QTEMP                                                                
 * . . .  + . . .  . 1 . .  . . + .                                                  *...+....1....+.                               
 40414243 7C454647 E049904B 4C4D4E5A                                                *  âäàáãåçñ[.<(+§                    *          
 50C05253 D0555657 5859B55B 5C5D5EB0                                                *&éêëèíîïìß]$*);¢                    *          
 60616263 64656667 6869DD6B 6C6D6E6F                                                *-/ÂÄÀÁÃÅÇѦ,%_>?                    *          
 70717273 74757677 78A07AB1 447D7E7F                                                *øÉÊËÈÍÎÏÌ`:#@'="                    *          
 80818283 84858687 88898A8B 8C8D8E8F                                                *Øabcdefghi«»ðýþ±                    *          
 BA919293 94959697 98999A9B 9C9D9E9F                                                *¬jklmnopqrªºæ¸Æ€                    *          
 79BDA2A3 A4A5A6A7 A8A9AAAB ACADAEAF                                                *µ~stuvwxyz¡¿ÐÝÞ®                    *          
 4A7BB2B3 B4BBB6B7 B8B95F4F BCA1BEBF                                                *°£¥·©|¶¼½¾^!¯¨´×                    *          
 51C1C2C3 C4C5C6C7 C8C9CACB CCCDCECF                                                *{ABCDEFGHI­ôöòóõ                    *          
 54D1D2D3 D4D5D6D7 D8D9DADB DC6ADEDF                                                *}JKLMNOPQR¹ûüùúÿ                    *          
 48E1E2E3 E4E5E6E7 E8E9EAEB ECEDEEEF                                                *\÷STUVWXYZ²ÔÖÒÓÕ                    *          
 F0F1F2F3 F4F5F6F7 F8F9FAFB FCFDFE3F                                                *0123456789³ÛÜÙÚ                    *          
                         ****** FIN DES DONNEES ******                                                                              

 ===> runqry () ebcdicp                                                         
                                                                                
EBCDIC
000001 âä@áãå\ñ°.<(+!
000002 &{êë}íîïìߧ$*);^
000003 -/ÂÄÀÁÃÅÇÑù,%_>?
000004 øÉÊËÈÍÎÏ̵:£à'="
000005 Øabcdefghi«»ðýþ±
000006 [jklmnopqrªºæ¸Æ€
000007 `¨stuvwxyz¡¿ÐÝÞ®
000008 ¢#¥·©]¶¼½¾¬|¯~´×
000009 éABCDEFGHI­ôöòóõ
000010 èJKLMNOPQR¹ûü¦úÿ
000011 ç÷STUVWXYZ²ÔÖÒÓÕ
000012 0123456789³ÛÜÙÚ
****** ******** Fin du rapport ********

 ===> runqry () ebcdicp037                                                      

                                                                                
        EBCDIC                                                                  
 000001   âäàáãåçñ[.<(+§                                                        
 000002 &éêëèíîïìß]$*);¢                                                        
 000003 -/ÂÄÀÁÃÅÇѦ,%_>?                                                        
 000004 øÉÊËÈÍÎÏÌ`:#@'="                                                        
 000005 Øabcdefghi«»ðýþ±                                                        
 000006 ¬jklmnopqrªºæ¸Æ€                                                        
 000007 µ~stuvwxyz¡¿ÐÝÞ®                                                        
 000008 °£¥·©|¶¼½¾^!¯¨´×                                                        
 000009 {ABCDEFGHI­ôöòóõ                                                        
 000010 }JKLMNOPQR¹ûüùúÿ                                                        
 000011 \÷STUVWXYZ²ÔÖÒÓÕ                                                        
 000012 0123456789³ÛÜÙÚ                                                        
 ****** ********  Fin du rapport  ********                                      

c'est ici que ça devient intéressant


 ===> chgjob ccsid(297)                                                         

 ===> runqry () ebcdicp                                                         
                                                                                
EBCDIC
000001 âä@áãå\ñ°.<(+!
000002 &{êë}íîïìߧ$*);^
000003 -/ÂÄÀÁÃÅÇÑù,%_>?
000004 øÉÊËÈÍÎÏ̵:£à'="
000005 Øabcdefghi«»ðýþ±
000006 [jklmnopqrªºæ¸Æ€
000007 `¨stuvwxyz¡¿ÐÝÞ®
000008 ¢#¥·©]¶¼½¾¬|¯~´×
000009 éABCDEFGHI­ôöòóõ
000010 èJKLMNOPQR¹ûü¦úÿ
000011 ç÷STUVWXYZ²ÔÖÒÓÕ
000012 0123456789³ÛÜÙÚ
****** ******** Fin du rapport ********

 ===> runqry () ebcdicp037                                                      
                                                                                
EBCDIC
000001 âä@áãå\ñ°.<(+!
000002 &{êë}íîïìߧ$*);^
000003 -/ÂÄÀÁÃÅÇÑù,%_>?
000004 øÉÊËÈÍÎÏ̵:£à'="
000005 Øabcdefghi«»ðýþ±
000006 [jklmnopqrªºæ¸Æ€
000007 `¨stuvwxyz¡¿ÐÝÞ®
000008 ¢#¥·©]¶¼½¾¬|¯~´×
000009 éABCDEFGHI­ôöòóõ
000010 èJKLMNOPQR¹ûü¦úÿ
000011 ç÷STUVWXYZ²ÔÖÒÓÕ
000012 0123456789³ÛÜÙÚ
****** ******** Fin du rapport ********

le contenu apparent est identique. Et le codage interne est correct, si l'on tient compte du CCSID.

Autre essai : envoyer par mail un fichier avec des caractères accentués

fichier 400
Colonnes . . : 1 100 Examen SEU==> AAA 
FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0 
************** Début des données ************************************************************************************** 
0001.00 DÉJÀ PÊCHÉ 
0002.00 déjà pêché 
*************** Fin des données *************************************************************************************** 

Copie QDLS
CPYTOPCD FROMFILE(.../QPGMSRC)
TOFLR(JPL) 
FROMMBR(AAA) 
TODOC(TOTO.TXT) 

consultation au bloc notes
D?J· PÒCH?
d‚j… pˆch‚
consultation par WRKLNK
Browse : /QDLS/JPL/TOTO.TXT 
Record : 1 of 3 by 18 Column : 1 59 by 131 
Control : 
....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+....0....+....1....+....2....+....3. 
************Beginning of data************** 
DÉJÀ PÊCHÉ 
déjà pêché 
************End of Data******************** 
attributs WRKLNK :
Objet . . . . . . : /QDLS/JPL/TOTO.TXT
Type . . . . . . . . . . . . . . . . . : DOC
Système de l'objet . . . . . . . . . . : Local
Pool de mémoire secondaire . . . . . . : 1
ID de jeu de caractères codés  . . . . : 850
Fichier caché  . . . . . . . . . . . . : Non
Fichier système PC . . . . . . . . . . : Non
Lecture seule  . . . . . . . . . . . . : Non
Archivage requis (PC)  . . . . . . . . : Oui
Archivage requis (AS/400)  . . . . . . : Non

consultation DOS (ASCII) : démarrer / exécuter / cmd
Microsoft Windows XP [version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
H:\>i:
I:\>cd qdls
I:\qdls>cd jpl
I:\qdls\jpl>type toto.txt
DÉJÀ PÊCHÉ
déjà pêché
I:\qdls\jpl>
envoi du mail
SNDDST TYPE(*DOC) 
DSTD('texte accentué PC850') 
MSG('DÉJÀ PÊCHÉ déjà pêché') 
DOC(TOTO.TXT) 
FLR(JPL) 

message reçu correct, texte en PJ : affiché erroné comme au bloc notes

Chemin inverse : depuis windows, au bloc notes, fichier nouveau,
coller le texte
DÉJÀ PÊCHÉ
déjà pêché

enregistrer sous ... un fichier IFS

puis WRKLNK, attributs :

Objet . . . . . . : /jpl/TOTO.TXT 
Type . . . . . . . . . . . . . . . . . : STMF 
Propriétaire . . . . . . . . . . . . . : 
Système de l'objet . . . . . . . . . . : Local 
Pool de mémoire secondaire . . . . . . : 1 
Objet en dépassement . . . . . . . . : Non 
ID de jeu de caractères codés . . . . : 1252 
Fichier caché . . . . . . . . . . . . : Non 
Fichier système PC . . . . . . . . . . : Non 
Lecture seule . . . . . . . . . . . . : Non 
Archivage requis (PC) . . . . . . . . : Oui 
Archivage requis (AS/400) . . . . . . : Oui 
le code page ANSI pour windows europe de l'ouest est 1252

conclusions
- QDLS est un système de fichier typiquement DOS : noms de fichiers 8.3, contenu ASCII (850 ou 437)
- SNDDST est une commande de mail de même génération
- OS400 n'offre pas d'évolution sur ce sujet
- la commande INZPCS fixe les codes page ASCII et EBCDIC pour toutes les conversions QDLS <=> QSYS

sachant que
- 297 est le code page EBCDIC France
- 1147 est le code page EBCDIC France-Euro
- 850 est le code page ASCII France
- 1252 est le code page ANSI europe de l'ouest zone Euro

correction
- remplacer SNDDST par un autre outil, par exemple MMAIL or MAIL
- faire une table de conversion 1147 ou 297 vers 1252


CRTPF FILE(.../EBCDICP) 
RCDLEN(16) 

saisir en hexa le fichier (j'ai utilisé WRKDBF, mais le RUNSQLSTM ci-dessus fait la même chose)

Membre de fichier physique 
Fichier . . . . : EBCDICP Bibliothèque . . : DEV
Membre . . . . . : EBCDICP Enregistrement . : 1 
Contrôle . . . . . Colonne . . . . : 1 
Recherche . . . . 
* . . . + . . . . 1 . . . . + . *...+....1....+. 
40414243 44454647 48494A4B 4C4D4E4F * âä@áãå\ñ°.<(+! * 
50515253 54555657 58595A5B 5C5D5E5F *&{êë}íîïìߧ$*);^ * 
60616263 64656667 68696A6B 6C6D6E6F *-/ÂÄÀÁÃÅÇÑù,%_>? * 
70717273 74757677 78797A7B 7C7D7E7F *øÉÊËÈÍÎÏ̵:£à'=" * 
80818283 84858687 88898A8B 8C8D8E8F *Øabcdefghi«»ðýþ± * 
90919293 94959697 98999A9B 9C9D9E9F *[jklmnopqrªºæ¸Æ€ * 
A0A1A2A3 A4A5A6A7 A8A9AAAB ACADAEAF *`¨stuvwxyz¡¿ÐÝÞ® * 
B0B1B2B3 B4B5B6B7 B8B9BABB BCBDBEBF *¢#¥·©]¶¼½¾¬|¯~´× * 
C0C1C2C3 C4C5C6C7 C8C9CACB CCCDCECF *éABCDEFGHI­ôöòóõ * 
D0D1D2D3 D4D5D6D7 D8D9DADB DCDDDEDF *èJKLMNOPQR¹ûü¦úÿ * 
E0E1E2E3 E4E5E6E7 E8E9EAEB ECEDEEEF *ç÷STUVWXYZ²ÔÖÒÓÕ * 
F0F1F2F3 F4F5F6F7 F8F9FAFB FCFDFEFF *0123456789³ÛÜÙÚ * 
****** FIN DES DONNEES ****** 

avec client access, transferer ce fichier vers le PC
une fois en ASCII
une fois en ANSI
(options par le bouton Détails)

consulter avec le bloc notes

ebcdic2ascii.txt
ÿƒ„@ Ɔ\¤ø.<(+!
&{ˆ‰}¡Œ‹?áõ$*);^
-/¶Ž·µÇ?€¥—,%_>?
›?ÒÓÔÖ×ØÞæ:œ…'="
?abcdefghi®¯Ðìçñ
[jklmnopqr¦§‘÷’Ï
`ùstuvwxyz­¨Ñíè©
½#¾ú¸]ô¬«óª|î~ïž
‚ABCDEFGHIð“”•¢ä
ŠJKLMNOPQRû–?Ý£˜
‡öSTUVWXYZýâ™ãàå
0123456789üêšëéŸ



ebcdic2ansi.txt
âä@áãå\ñ°.<(+!
&{êë}íîïìߧ$*);^
-/ÂÄÀÁÃÅÇÑù,%_>?
øÉÊËÈÍÎÏ̵:£à'="
Øabcdefghi«»ðýþ±
[jklmnopqrªºæ¸Æ¤
`¨stuvwxyz¡¿ÐÝÞ®
¢#¥·©]¶¼½¾¬|¯~´×
éABCDEFGHI­ôöòóõ
èJKLMNOPQR¹ûü¦úÿ
ç÷STUVWXYZ²ÔÖÒÓÕ
0123456789³ÛÜÙÚŸ



puis consulter avec DOS
C:\temp>type ebcdic2ascii.txt
âä@áãå\ñ°.<(+!
&{êë}íîïìߧ$*);^
-/ÂÄÀÁÃÅÇÑù,%_>?
øÉÊËÈÍÎÏ̵:£à'="
Øabcdefghi«»ðýþ±
[jklmnopqrªºæ¸Æ¤
`¨stuvwxyz¡¿ÐÝÞ®
¢#¥·©]¶¼½¾¬|¯~´×
éABCDEFGHI­ôöòóõ
èJKLMNOPQR¹ûü¦úÿ
ç÷STUVWXYZ²ÔÖÒÓÕ
0123456789³ÛÜÙÚƒ

C:\temp>type ebcdic2ansi.txt
áÔõ@ßÒÕ\±?.<(+!
&{ÛÙ}ݯ´ý?º$*);^
-/??????ÃШ,%_>?
°??????¤?Á:úÓ'="
Ïabcdefghi½?­²??
[jklmnopqr¬?µ©ãñ
`¿stuvwxyzí?ð¦Ì«
ó#ÑÀ®]Â?¢¥¼|»~?Î
ÚABCDEFGHI¡¶÷?¾§
ÞJKLMNOPQR?¹³ª· 
þ¸STUVWXYZ?ÈÍÊË?
0123456789?????ƒ

chercher sur le net si la table ce conversion existe déjà

la page http://www16.boulder.ibm.com/pseries/en_US/aixprggd/nlsgdrf/codeset_over.htm fournit quelques indications

chercher avec STRPDM dans QUSRSYS sur les objets *TBL, filtrer (F17) sur 1147 ou 1252

et miracle ! la table QA66BFA93 convertit (Best fit, ce qui est différent de Translate) le 1147 en 1252

CPYTOPCD FROMFILE(.../QPGMSRC) 
TOFLR(JPL) 
FROMMBR(AAA) 
TODOC(TOTO.TXT) 
REPLACE(*YES) 
TRNTBL(QUSRSYS/QA66BFA93) 

SNDDST TYPE(*DOC) 
DSTD('texte accentué PC850') 
MSG('DÉJÀ PÊCHÉ déjà pêché') 
DOC(TOTO.TXT) 
FLR(JPL) 

Et ça marche ! la pièce jointe reçue est correctement accentuée ... parce que la machine est en QCCSID 65535, mon travail aussi, les travaux serveurs QMSF (Mail Server Framework) et QTMSMT* en 297 ou 500. De ce fait,  comme mon travail est en 65535, il interdit donc à SNDDST de traduire le fichier QDLS TOTO.TXT (qui a un contenu en 1252 dans une enveloppe en 850) avant de le refiller à QMSF, ce qui est l'objectif recherché.

Le jour où je passe en QCCSID correct, je vais avoir des surprises.

Et maintenant, do it youself !

Avec ce code, vous allez fabriquer 4 fichiers :
*************** Beginning of data *************************************
                R EBCDICF                                             
                  EBCDIC        16A         COLHDG('EBCDIC')          
****************** End of data ****************************************
CRTPF FILE(JPLTOOLS/EBCDICP) SRCFILE(JPLTOOLS/JPLTOOLS) SIZE(*NOMAX) 
RUNSQLSTM SRCFILE(JPLTOOLS) SRCMBR(EBCDICDATA)         
CRTDUPOBJ OBJ(EBCDICP) FROMLIB(*LIBL) OBJTYPE(*FILE) NEWOBJ(EBCDIC875) DATA(*YES)                                                                         
CRTDUPOBJ OBJ(EBCDICP) FROMLIB(*LIBL) OBJTYPE(*FILE) NEWOBJ(EBCDIC297) DATA(*YES)                                                                         
CRTDUPOBJ OBJ(EBCDICP) FROMLIB(*LIBL) OBJTYPE(*FILE) NEWOBJ(EBCDIC037) DATA(*YES)                                                                         
chgpf ebcdic037 ccsid(037)   
chgpf ebcdic297 ccsid(297)   
chgpf ebcdic875 ccsid(875)   

et vous allez ensuite consulter ces fichiers avec DSPPFM, RUNQRY, faire varier le CCSID de votre travail, puis lire ces fichiers avec excel. 

Vous devez obtenir ceci :

ccsid files and excel






2021-10-02

c'est bien gentil toutes ces explications qui vont dans tous les sens, mais c'est quoi le problème, est-ce qu'il y a une solution ?

On va y aller tout doucement, avec un peu moins de désordre.
Depuis maintenant 25 ans que le CCSID existe, il y a de plus en plus de personnes qui maitrisent le sujet.

Première chose: changer la sysval QCCSID sans precaution, c'est suicidaire :
Avant, quand qccsid=65535, la base de donnée est erronée, mais tous les fichiers etant erronés de la même manière, on peut se ratrapper.
Après, la base de donnée, qui etait juste erronnée, devient incoherente. pas de rattrapage possible.
Explications
Quand tous les ccsid sont à 65535, la machine fonctionne en mode binaire: l'operating système s'interdit de faire la la moindre convertion de jeu de caractère.
En clair, quand on regarde une adresse email dans un fichier, on a quelques chances de voir le @ transformé en à, et c'est NORMAL:

on prend un peu de recul:

  • le fichier est en CCSID 65535
  • l'ecran 5250 est en 297
  • le job est en 65535
  • quand je saisis mon adresse mail sur l'ecran, le @ (x'40' sous windows, ansi, ccsid 1252) est converti en ebcdic par l'emulateur: x'4a'.ce code est reçu tel quel par le job (ccsid 65535) puis écrit tel quel dans le fichier (ccsid 65535).

    Si je regarde mon fichier avec un émulateur configuré en 37 (CCSID pour les USA), le x'4a' est affiché à, et c'est exactement de cette manière que doivent fonctionner les applications...
    sauf que, croyant voir une faute de frappe, l'utilisateur va corriger le à en @ ...et sur cet enregistrement dans le fichier, l'adresse mail contiendra un à  à la place du  @.
    Quand le batch de nuit va tourner, il va se planter s'il essaie d'envoyer un mail avec cette adresse (ou pire, le mail ne partira pas et on ne s'appercoit de rien).

    le mode binaire part du principe que tous les jobs et tous les emulateurs utilisent le même CCSID. Facile en 1995 en V2R3, avec tous les terminaux sur le même controleur twinax, sans SQL ni internet.

    Le mode binaire (ccsid 65535) est une pirouette inventée par IBM pour permettre la sacro-sainte compatibilité ascendante de l'operating système, et ca marche: 25 ans plus tard, le nombre de systèmes resté en mode V2R3 reste impressionnant.

    le défaut est que dès qu'on tente d'utiliser le système avec un écran ou une connection client-server qui n'est pas exactement configurée pour respecter le CCSID par défaut hérité dela V2R3,les convertions de caractères, que chacun est en droit d'attendre d'un système normal, ne se produisent pas.

    CCSID par defaut avez vous dit ? qu'est-ce que c'est que ce truc encore ? C'est le reste de la pirouette. IBM fourni des commandes capables de manipuler les fichiers: CPYF, DSPPFM, RUNQRY, ...Ces commandes doivent fonctionner correctement même quand qccsid = 65535. IBM a prévu le coup: un job en CCSID 65535 hérite par ailleurs d'un CCSID par défaut, que les commandes IBM vont utiliser pour manipuler les données, en essayant de limiter les dégats:

      Selection or command                                                           
     ===> CHGJOB LANGID(ENU) CNTRYID(US) CCSID(65535)                               
                                                                                   
     
     F3=Exit   F4=Prompt   F9=Retrieve   F12=Cancel   F13=Information Assistant     
     F23=Set initial menu                                                           
                                                                                    

                           Display Job Definition Attributes                        
     
                                                                  
     
    Device recovery action  . . . . . . . . . . . . . :   *DSCMSG                  
     Time slice end pool . . . . . . . . . . . . . . . :   *NONE                    
     Print key format  . . . . . . . . . . . . . . . . :   *PRTHDR                  
     Sort sequence . . . . . . . . . . . . . . . . . . :   *HEX                     
      
     Library . . . . . . . . . . . . . . . . . . . . :                            
     Language identifier . . . . . . . . . . . . . . . :   ENU                      
     Country or region identifier  . . . . . . . . . . :   US                       
     Coded character set identifier  . . . . . . . . . :   65535                    
     Default coded character set identifier  . . . . . :   37                       
     Character identifier control  . . . . . . . . . . :   *JOBCCSID                
     Job message queue maximum size  . . . . . . . . . :   16                       
     Job message queue full action . . . . . . . . . . :   *PRTWRAP                 
     Allow multiple threads  . . . . . . . . . . . . . :   *NO                      
     Auxiliary storage pool group  . . . . . . . . . . :   *NONE                    
     Spooled file action . . . . . . . . . . . . . . . :   *KEEP                    
                                                                      
          More... 
     Press Enter to continue.                                                       
                                                                                    
     F3=Exit   F5=Refresh   F12=Cancel   F16=Job menu                               
                                                                                    

    Le default ccsid dépend du LANGID et/ou du CNTRYID ... fournis par l'emulateur d'ecran. Ce qui fait que les jobs interactifs ont peu de problèmes de CCSID.
    Il en va tout autrement des travaux servers FTP ou ODBC.

    Que faire ?

    une option est de décider de laisser le système en mode binaire, et de prendre en charge au niveau applicatif la gestion de la langue de l'utilisateur (c'est à dire la langue du job).
    C'est un choix respectable, mais lourd en programmation.

    l'autre option est de demander au système de faire le travail. autrement dit de ne plus utiliser le ccsid 65535 nulle part.
    Cette option a l'avantage d'ouvrir la porte à SQL: SQL sur IBMi tolère très mal le CCSID 65535.

    le problème, c'est nulle part. Il ne faut rien oublier.aucun CCSID=65535 ne doit rester.

    Les principaux points à vérifier:

  • chaque fichier, voir chaque zone de chaque fichier, doit avoir un CCSID
  • chaque profil doit avoir un CCSID.Personnellement, j'ai un programme initial qui reconfigure mon job en fonction del'emulateur.
  •   Initial program to call  . . . .   INLPGM        Name, *SAME, *NONE            
       Library  . . . . . . . . . . .     JPLTOOLS    Name, *LIBL, *CURLIB          
  • chaque job doit avoir un CCSID, et plus, faites attention à
  •  Character identifier control . .   *JOBCCSID     *SAME, *USRPRF, *SYSVAL...   
    la valeur *DEVD est parfaite pour un CCSID 65535.
  • chaque display-file a un CCSID, mais faites attention à
  •     Character identifier  . . . . . . . . . . . : CHRID      *DEVD                                                                 

    cette valeur par défaut est parfaite en CCSID 65535.Jetez un oeil à *JOBCCSID.


    C'est quoi la prochaine tuile ?
    les constantes dans le code source de vos programmes. voir when-ccsid-constants-vary, 1 when-ccsid-constants-vary, 2 when-ccsid-constants-vary, 3
    Solution: les recoder en unicode


    Une fois toutes ces adaptations réussies, lancez vous dans une convertion de la base de données à SQL. c'est pas si compliqué, il y a d'excellents outils pour ca (j'aime beaucoup XCASE).