macro SAS9

Ejecutar informes condicionales y evitar las trampas de las macros

Simon 24/03/2022 2 vistas

La automatización es el corazón de la programación SAS©. Un escenario clásico consiste en verificar el contenido de una tabla antes de iniciar un procesamiento: "Si mi tabla contiene datos, ejecuta el informe estándar; de lo contrario, ejecuta un informe de anomalías."

Aunque la lógica parece simple, su implementación a través del lenguaje macro puede encontrar dos obstáculos importantes: el alcance de las variables y el comportamiento engañoso de ciertas variables automáticas como SQLOBS.

El Problema: ¿Por qué mi código no detecta el error?

Imaginemos un código estructurado en dos macros:

  1. %Check_Data: Verifica los datos y crea un indicador &error.

  2. %Run_Report: Lee &error y decide qué informe imprimir.

El error frecuente es definir la variable &error dentro de la primera macro sin precaución.

1. La trampa del alcance (Scope) Por defecto, una macro-variable creada dentro de una macro (mediante %LET) es local. Solo existe durante la ejecución de esa macro. Tan pronto como %Check_Data finaliza, la variable &error se destruye. Cuando %Run_Report intenta leer &error, no encuentra nada y el programa falla (error "Apparent symbolic reference not resolved").

La Solución: Es necesario declarar la variable como global al principio del programa o antes de su uso:

1%GLOBAL error;
2%LET error = 0;

La Trampa Técnica: SQLOBS y las Vistas

Otro error sutil concierne el método de conteo. El desarrollador intentaba aquí detectar si una tabla estaba vacía verificando la variable automática &SQLOBS justo después de una instrucción CREATE VIEW.

1PROC SQL;
2 CREATE VIEW work.ma_vue AS SELECT * FROM SOURCE;
3QUIT;
4/* Le développeur pense que &SQLOBS contient le nombre de lignes... */

Es un error lógico. La creación de una vista no lee los datos, solo define una estructura. Por lo tanto, SAS© siempre devuelve SQLOBS = 0 después de la creación de una vista, incluso si la tabla subyacente contiene millones de líneas. El informe de error se activaba sistemáticamente por error.

La Buena Práctica

Para condicionar la ejecución de sus informes (procedimiento PRINT, REPORT, etc.), aquí está el procedimiento a seguir:

  1. No encapsular sus llamadas de macros que contienen procedimientos (Proc Print, etc.) dentro de un paso DATA _NULL_. Las macros se llaman directamente en código abierto.

  2. Contar las líneas correctamente: Para verificar si una tabla está vacía sin leerla completamente (lo cual es costoso en recursos), consulte los metadatos a través de los diccionarios SAS©.

Aquí hay un ejemplo robusto:

1/* 1. Récupérer le nombre d'observations depuis les métadonnées */
2PROC SQL NOPRINT;
3 SELECT (nobs - delobs) INTO :num_obs
4 FROM dictionary.tables
5 WHERE LIBNAME = 'WORK' AND memname = 'MA_TABLE';
6QUIT;
7 
8/* 2. Logique conditionnelle */
9%MACRO Choisir_Rapport;
10 %IF &num_obs > 0 %THEN %DO;
11 %Put --- Lancement du Rapport Standard ---;
12 /* %Rapport_Standard; */
13 %END;
14 %ELSE %DO;
15 %Put --- TABLE vide : Lancement du Rapport d'Erreur ---;
16 /* %Rapport_Erreur; */
17 %END;
18%MEND;
19 
20%Choisir_Rapport;
Este método es a la vez más eficiente (sin lectura de datos innecesaria) y más fiable para gestionar sus flujos de producción.
Referencias y Documentos