Les catalogues de formats sont souvent des 'boîtes noires' binaires difficiles à versionner.
Cette macro transforme ces métadonnées en actifs exploitables. En imposant un modèle de données rigoureux dès le départ (via %mddl_sas_cntlout) et en nettoyant les tables temporaires systématiquement, elle s'intègre parfaitement dans un pipeline de déploiement continu. C'est l'outil idéal pour extraire, auditer, puis réimporter des formats (CNTLIN) entre différents environnements tout en garantissant que la structure cible reste strictement identique à la source
La macro utilise `PROC FORMAT` avec l'option `cntlout` pour générer un dataset. Les sources primaires sont les définitions de formats SAS disponibles dans la librairie spécifiée par `libcat`, ainsi que les macros utilitaires internes (`%mf_getuniquename`, `%mddl_sas_cntlout`, `%mp_aligndecimal`).
1 Bloc de code
Macro Definition
Explication : Définition de la macro `%mp_cntlout` qui prend des paramètres pour spécifier la librairie/catalogue de formats (`libcat`), le nom du jeu de données de sortie (`cntlout`), une liste de formats spécifiques (`fmtlist`), et une condition d'exécution (`iftrue`). Elle initialise également des noms de tables temporaires uniques.
Explication : Utilise `PROC FORMAT` avec l'option `cntlout` pour générer un jeu de données de contrôle (`&cntlds`) à partir des formats de la librairie spécifiée (`&libcat`). Un bloc `%if` conditionnel permet de sélectionner des formats spécifiques s'ils sont fournis via `&fmtlist`. La référence `libcat` est potentiellement nettoyée si elle contient un suffixe '-FC'.
Copié !
%mddl_sas_cntlout(libds=&ddlds)
%if %index(&libcat,-)>0 and %scan(&libcat,2,-)=FC %then %do;
%let libcat=%scan(&libcat,1,-);
%end;
proc format lib=&libcat cntlout=&cntlds;
%if "&fmtlist" ne "0" and "&fmtlist" ne "" %then %do;
select
%do i=1 %to %sysfunc(countw(&fmtlist,%str( ));
%scan(&fmtlist,&i,%str( ))
%end;
;
%end;
run;
1
%mddl_sas_cntlout(libds=&ddlds)
2
3
%IF %index(&libcat,-)>0 and %scan(&libcat,2,-)=FC %THEN %DO;
4
%let libcat=%scan(&libcat,1,-);
5
%END;
6
7
PROC FORMAT lib=&libcat cntlout=&cntlds;
8
%IF"&fmtlist" ne "0" and "&fmtlist" ne "" %THEN %DO;
9
select
10
%DO i=1 %to %sysfunc(countw(&fmtlist,%str( ));
11
%scan(&fmtlist,&i,%str( ))
12
%END;
13
;
14
%END;
15
RUN;
3 Bloc de code
DATA STEP Data
Explication : Crée le jeu de données de sortie final (`&cntlout`) en combinant les informations des datasets temporaires (`&ddlds`, `&cntlds`). Il effectue un alignement décimal sur les colonnes numériques ('I', 'N') en utilisant la macro `%mp_aligndecimal` et crée un marqueur de ligne (`fmtrow`) pour le tri.
Copié !
data &cntlout/nonote2err;
if 0 then set &ddlds;
set &cntlds;
by type fmtname notsorted;
/* align the numeric values to avoid overlapping ranges */
if type in ("I","N") then do;
%mp_aligndecimal(start,width=16)
%mp_aligndecimal(end,width=16)
end;
/* create row marker. Data cannot be sorted without it! */
if first.fmtname then fmtrow=1;
else fmtrow+1;
run;
1
DATA &cntlout/nonote2err;
2
IF 0 THENSET &ddlds;
3
SET &cntlds;
4
BY type fmtname notsorted;
5
6
/* align the numeric values to avoid overlapping ranges */
7
IF type in ("I","N") THENDO;
8
%mp_aligndecimal(start,width=16)
9
%mp_aligndecimal(END,width=16)
10
END;
11
12
/* create row marker. Data cannot be sorted without it! */
13
IF first.fmtname THEN fmtrow=1;
14
ELSE fmtrow+1;
15
16
RUN;
4 Bloc de code
PROC SORT
Explication : Trie le jeu de données de sortie (`&cntlout`) selon les variables `type`, `fmtname`, et `fmtrow`.
Copié !
proc sort;
by type fmtname fmtrow;
run;
1
PROC SORT;
2
BY type fmtname fmtrow;
3
RUN;
5 Bloc de code
PROC SQL
Explication : Utilise `PROC SQL` pour supprimer les jeux de données temporaires (`&ddlds`, `&cntlds`) créés pendant l'exécution de la macro.
Copié !
proc sql;
drop table &ddlds,&cntlds;
quit;
1
PROC SQL;
2
drop TABLE &ddlds,&cntlds;
3
QUIT;
6 Bloc de code
Macro End
Explication : Termine la définition de la macro `%mp_cntlout`.
Copié !
%mend mp_cntlout;
1
%mend mp_cntlout;
L'Astuce Pro
La création de la variable fmtrow associée à l'alignement décimal via mp_aligndecimal est indispensable pour garantir l'intégrité de vos formats numériques lors d'une future opération CNTLIN. Sans ce marqueur de ligne explicite, un tri standard sur les colonnes START ou END (stockées en caractères dans un dataset CNTLOUT) échouerait à cause de l'ordre lexicographique, provoquant des chevauchements de plages ou des erreurs de chargement. L'utilisation de mf_getuniquename assure par ailleurs que vos tables de travail ne s'écrasent jamais entre elles en environnement multi-utilisateurs.
Ce matériel est fourni "tel quel" par We Are Cas. Il n'y a aucune garantie, expresse ou implicite, quant à la qualité marchande ou à l'adéquation à un usage particulier concernant le matériel ou le code contenu dans les présentes. We Are Cas n'est pas responsable des erreurs dans ce matériel tel qu'il existe maintenant ou existera, et We Are Cas ne fournit pas de support technique pour celui-ci.
SAS et tous les autres noms de produits ou de services de SAS Institute Inc. sont des marques déposées ou des marques de commerce de SAS Institute Inc. aux États-Unis et dans d'autres pays. ® indique un enregistrement aux États-Unis. WeAreCAS est un site communautaire indépendant et n'est pas affilié à SAS Institute Inc.
Ce site utilise des cookies techniques et analytiques pour améliorer votre expérience.
En savoir plus.