Publié le :

Analyse de code SAS composite et macros imbriquées

Snippet validé
Le script principal exécute des commandes SAS© de base, y compris des définitions de macro-variables avec des caractères spéciaux et des affichages dans le log. Il référence la macro `macro_without_brief_tag` qui affiche simplement un paramètre, la macro `mm_getdetails` pour l'extraction de métadonnées CAS, et une macro JSON prédéfinie `_FILE` pour la suppression de guillemets. Une macro imbriquée nommée `unbelievable` est présente, ce qui est considéré comme une mauvaise pratique en SAS©.
Analyse des données

Type : CREATION_INTERNE


Le code n'utilise pas de données externes non gérées. Les opérations se concentrent sur des variables macro, des structures de données internes (tables de métadonnées CAS 'work.attributes' et 'work.associations'), et des affichages dans le log. La macro `_file` agit sur des chaînes de caractères passées en argument.

1 Bloc de code
Main (Macro-définitions, Data Step _NULL_)
Explication :
Ce bloc principal initialise plusieurs variables macro (`badpw`, `contains`, `a`) avec des chaînes contenant des caractères spéciaux ou d'échappement. Un DATA step `_NULL_` est utilisé pour écrire des messages dans le log, démontrant l'utilisation de `putlog`. La macro `nobrackets` est définie, incluant une boucle simple et, de manière notable, une macro imbriquée (`unbelievable`), ce qui est une pratique déconseillée en SAS car elle peut rendre le code difficile à maintenir et à déboguer.
Copié !
1%put here is some code from an arbitrary program;
2 
3%let badpw={sas002}asdfasdfasdfasdf;
4 
5%let contains=a tab;
6 
7%let a=hexchar;
8 
9DATA _null_;
10 putlog "It doesn't matter IF there are extra apostrophes";
11 putlog "lines can also be really loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong";
12RUN;
13 
14%macro nobrackets;
15 %local i;
16 %DO i=1 %to 10;
17 %put stuff&i;
18 %END;
19 %macro unbelievable();
20 %put one should know better than DO DO this!!!;
21 %mend unbelievable;
22%mend nobrackets;
2 Bloc de code
MACRO macro_without_brief_tag
Explication :
Cette macro simple, nommée `macro_without_brief_tag`, prend un paramètre `i_desc` et affiche sa valeur dans le log à l'aide de la fonction `%PUT`. Elle est souvent utilisée pour des tests ou des affichages de débogage.
Copié !
1%MACRO macro_without_brief_tag (i_desc);
2%put &i_desc.;
3%MEND macro_without_brief_tag;
4 
3 Bloc de code
MACRO mm_getdetails Data
Explication :
La macro `mm_getdetails` est conçue pour extraire des métadonnées détaillées d'un URI d'objet SAS. Elle crée deux jeux de données de sortie : `outassocs` (par défaut `work.associations`) pour les associations de l'objet et `outattrs` (par défaut `work.attributes`) pour ses attributs et propriétés. Elle utilise les fonctions `metadata_getnasl`, `metadata_getnasn`, `metadata_getattr`, `metadata_getnprp`, et `metadata_getnatr` pour interroger le référentiel de métadonnées. Deux `PROC SORT` sont utilisées pour ordonner les jeux de données résultants.
Copié !
1%macro mm_getdetails(uri
2 ,outattrs=work.attributes
3 ,outassocs=work.associations
4 ,sortoptions=
5)/*/STORE SOURCE*/;
6 
7DATA &outassocs;
8 keep assoc assocuri name;
9 LENGTH assoc assocuri name $256;
10 call missing(of _all_);
11 rc1=1;n1=1;
12 DO while(rc1>0);
13 /* Walk through all possible associations of this object. */
14 rc1=metadata_getnasl("&uri",n1,assoc);
15 rc2=1;n2=1;
16 DO while(rc2>0);
17 /* Walk through all the associations on this machine object. */
18 rc2=metadata_getnasn("&uri",trim(assoc),n2,assocuri);
19 IF (rc2>0) THEN DO;
20 rc3=metadata_getattr(assocuri,"Name",name);
21 OUTPUT;
22 END;
23 call missing(name,assocuri);
24 n2+1;
25 END;
26 n1+1;
27 END;
28RUN;
29PROC SORT &sortoptions;
30 BY assoc name;
31RUN;
32 
33DATA &outattrs;
34 keep type name value;
35 LENGTH type $4 name $256 value $32767;
36 rc1=1;n1=1;type='Prop';name='';value='';
37 DO while(rc1>0);
38 rc1=metadata_getnprp("&uri",n1,name,value);
39 IF rc1>0 THEN OUTPUT;
40 n1+1;
41 END;
42 rc1=1;n1=1;type='Attr';
43 DO while(rc1>0);
44 rc1=metadata_getnatr("&uri",n1,name,value);
45 IF rc1>0 THEN OUTPUT;
46 n1+1;
47 END;
48RUN;
49PROC SORT &sortoptions;
50 BY type name;
51RUN;
52 
53%mend mm_getdetails;
4 Bloc de code
MACRO _FILE
Explication :
Ce bloc définit la macro SAS `%_file`. Elle accepte un paramètre `arg1`. À l'intérieur, la fonction macro `%SCAN` est utilisée pour analyser la valeur de `arg1`. Le troisième argument de `%SCAN` (`''""`) spécifie que les guillemets simples et doubles doivent être traités comme des délimiteurs, ce qui a pour effet de supprimer ces guillemets de la chaîne si elle en contient.
Copié !
1%macro _file(arg1);
2 
3%*strip quoting since the returned value will be unquoted;
4%scan(&arg1, 1, ''"")
5 
6%mend _file;
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.
Informations de Copyright : Copyright 2010-2023 HMS Analytical Software GmbH (pour macro_without_brief_tag.sas), Copyright (c) 2004 Rodney Sparapani (pour _file.json).


Banner
Le Conseil de l'Expert
Expert
Simon
Expert SAS et fondateur.
« Développer en langage macro SAS demande une rigueur particulière, car la frontière entre un code puissant et un programme instable est mince. L'analyse de ce script révèle des pratiques avancées, mais aussi des zones de risque technique majeur qu'un développeur senior doit savoir identifier. »