Aller au contenu

%OPEN

Savoir si un fichier est ouvert

Renvoie *ON si le fichier indiqué est actuellement ouvert dans le programme, *OFF sinon.

Syntaxe

%OPEN(nom-fichier)
nom-fichier
Le nom du fichier déclaré par dcl-f.
Résultat
Un indicateur : *ON si le fichier est ouvert, *OFF s'il est fermé ou pas encore ouvert.

À quoi ça sert

Un fichier déclaré avec usropn n'est pas ouvert au démarrage : c'est au programme d'exécuter open (et éventuellement close). %OPEN permet d'ouvrir à la demande, une seule fois, depuis une procédure appelée plusieurs fois.

Exemple 1 : Ouverture à la demande dans une procédure

**free
// %OPEN : savoir si un fichier est ouvert, et ne l'ouvrir qu'au besoin (USROPN).
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);

dcl-f client keyed usropn;      // ouverture a la charge du programme
dcl-f f_client keyed;           // ouverture automatique au demarrage

snd-msg 'CLIENT ouvert au depart : ' + %char(%open(client));
snd-msg 'F_CLIENT ouvert au depart : ' + %char(%open(f_client));

snd-msg 'Client 200 : ' + nomclient(200);
snd-msg 'CLIENT ouvert apres l''appel : ' + %char(%open(client));
snd-msg 'Client 999 : ' + nomclient(999);

close client;
snd-msg 'CLIENT ouvert apres CLOSE : ' + %char(%open(client));

*inlr = *on;

dcl-proc nomclient;
  dcl-pi *n varchar(30);
    cle packed(5:0) const;
  end-pi;

  if not %open(client);
    open client;
  endif;
  chain (cle) client;
  if %found(client);
    return %trim(nom);
  endif;
  return '(inconnu)';
end-proc;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

CLIENT ouvert au depart : 0
F_CLIENT ouvert au depart : 1
Client 200 : Martin et fils
CLIENT ouvert apres l'appel : 1
Client 999 : (inconnu)
CLIENT ouvert apres CLOSE : 0

CLIENT est déclaré avec usropn : il est fermé au départ, alors que F_CLIENT (sans usropn) est déjà ouvert. La procédure ouvre CLIENT au premier appel ; au second, %OPEN vaut déjà 1 et l'open est sauté. Après le close, il repasse à 0.

Exemple 2 : %OPEN contre les erreurs 1211 et 1215

**free
// %OPEN protege d'un OPEN sur un fichier deja ouvert (statut 1215).
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);

dcl-f client keyed usropn;

// Lecture sur un fichier pas encore ouvert
chain(e) (100) client;
snd-msg 'CHAIN avant OPEN : %ERROR = [' + %char(%error) + '] statut ' + %char(%status(client));

open client;

// Deuxieme OPEN sans se poser la question
open(e) client;
snd-msg 'OPEN en double   : %ERROR = [' + %char(%error) + '] statut ' + %char(%status(client));
snd-msg 'Fichier toujours ouvert : ' + %char(%open(client));

// Avec la garde, aucune erreur
if not %open(client);
  open(e) client;
endif;
chain(e) (100) client;
snd-msg 'CHAIN apres garde : %ERROR = [' + %char(%error) + '] ' + %trim(nom);

close client;
*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

CHAIN avant OPEN : %ERROR = [1] statut 1211
OPEN en double   : %ERROR = [1] statut 1215
Fichier toujours ouvert : 1
CHAIN apres garde : %ERROR = [0] Dupont SA

Un CHAIN sur un fichier usropn pas encore ouvert donne le statut 1211. Un second open sur un fichier déjà ouvert donne le statut 1215. La garde if not %open(...) évite le second cas.

Le piège

Un fichier usropn ne s'ouvre pas tout seul. Chercher dans CLIENT avant l'open donne l'erreur 1211 (visible ici parce que l'exemple utilise l'extension (E)).

Deux open de suite sont une erreur (statut 1215). Si l'ouverture peut se faire à plusieurs endroits, on la protège toujours par if not %open(fichier).