BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Roberto_BM
Obsidian | Level 7

Buen día miembros
Tengo una duda que dejaré en unas imágenes, la primera muestra que el código se ejecuta y asigna a la macro variable el valor correcto. Sin embargo, cuando hago solo el cambio de nombre de la variable, deja de funcionar correctamente y ahora la macro variable tiene un valor distinto tal y como se muestra en la segunda imagen (las cuales están contenidas en el archivo PDF adjunto).
Deseo entender ¿qué es lo que sucede?
Gracias de antemano.

1 ACCEPTED SOLUTION

Accepted Solutions
Hlm2019
SAS Employee

Hola Roberto

 

En el primer paso DATA envía resultados porque la variable macro &valor ya tenía el valor asignado ANTES de la ejecución del paso DATA.

 

La sentencia dentro del paso DATA

 

valor = today();

 

No asigna un valor a la variable macro, sino que crea una variable dentro del data set "tmp" llamada "valor"  y le asigna el resultado de la ejecución de la función today().

 

En cuanto se hace el cambio del nombre de la variable dentro del paso DATA, sólo se cambia el nombre de la variable del data set de salida, sin embargo esta acción no genera la variable macro &fecha_hoy ni le asigna valor alguno.

 

Las sentencias macros como el %LET y el %PUT dentro del paso DATA se ejecutan en tiempo de compilación por el procesador de macros y posteriormente ya no se ejecuta en el compilador.

 

Para poder manejar los valores de las variables macros dentro del paso DATA se usan las rutinas 

 

Call SymPutX()

Call SymGet()

 

Call SymPutX() tiene la misma función que %LET, es decir, asigna un valor a una variable macro por el compilador durante la ejecución del paso DATA.

 

Call SymGet() sirve para obtener el valor almacenado en una variable macro durante la ejecución del paso DATA.

 

Por lo tanto, para manejar los valores de las variables macros dentro del paso DATA, el primer paso DATA el ejemplo que mandaste, hay que reemplazar el %LET por la rutina Call SymputX() y el %PUT hay que ponerlo fuera del paso data ya que lo ejecuta el procesador de macros:

 

DATA tmp;
   valor = today();
   Call SymPutX( 'miMacroVariable', CatS( 'Archivo', valor ) );
RUN;
%Put La macrovariable es &miMacroVariable;
 
Con esto, si se cambia el nombre de la variable "valor" por "fecha_hoy", el paso DATA quedaría de la siguiente manera.
 
DATA tmp;
   fecha_hoy = today();
   Call SymPutX( 'miMacroVariable', CatS( 'Archivo', fecha_hoy ) );
RUN;
%Put La macrovariable es &miMacroVariable;
 
Saludos.

View solution in original post

8 REPLIES 8
Kurt_Bremser
Super User

Macro code is resolved before the code is compiled; you cannot use DATA step variables in macro code, as they do not yet exist.

Your first example "worked" because the macro variable was already created by some other means.

 

Pardon my posting in English, I don't speak Spanish.

Roberto_BM
Obsidian | Level 7
Don't worry, thank you very much, I will analyze, review and test carefully.
Hlm2019
SAS Employee

Hola Roberto

 

En el primer paso DATA envía resultados porque la variable macro &valor ya tenía el valor asignado ANTES de la ejecución del paso DATA.

 

La sentencia dentro del paso DATA

 

valor = today();

 

No asigna un valor a la variable macro, sino que crea una variable dentro del data set "tmp" llamada "valor"  y le asigna el resultado de la ejecución de la función today().

 

En cuanto se hace el cambio del nombre de la variable dentro del paso DATA, sólo se cambia el nombre de la variable del data set de salida, sin embargo esta acción no genera la variable macro &fecha_hoy ni le asigna valor alguno.

 

Las sentencias macros como el %LET y el %PUT dentro del paso DATA se ejecutan en tiempo de compilación por el procesador de macros y posteriormente ya no se ejecuta en el compilador.

 

Para poder manejar los valores de las variables macros dentro del paso DATA se usan las rutinas 

 

Call SymPutX()

Call SymGet()

 

Call SymPutX() tiene la misma función que %LET, es decir, asigna un valor a una variable macro por el compilador durante la ejecución del paso DATA.

 

Call SymGet() sirve para obtener el valor almacenado en una variable macro durante la ejecución del paso DATA.

 

Por lo tanto, para manejar los valores de las variables macros dentro del paso DATA, el primer paso DATA el ejemplo que mandaste, hay que reemplazar el %LET por la rutina Call SymputX() y el %PUT hay que ponerlo fuera del paso data ya que lo ejecuta el procesador de macros:

 

DATA tmp;
   valor = today();
   Call SymPutX( 'miMacroVariable', CatS( 'Archivo', valor ) );
RUN;
%Put La macrovariable es &miMacroVariable;
 
Con esto, si se cambia el nombre de la variable "valor" por "fecha_hoy", el paso DATA quedaría de la siguiente manera.
 
DATA tmp;
   fecha_hoy = today();
   Call SymPutX( 'miMacroVariable', CatS( 'Archivo', fecha_hoy ) );
RUN;
%Put La macrovariable es &miMacroVariable;
 
Saludos.
Roberto_BM
Obsidian | Level 7
Muchas gracias, voy a analizarlo, revisarlo y probarlo para tenerlo siempre presente.
Roberto_BM
Obsidian | Level 7

Muchas gracias Hlm2019, he probado el código y funciona correctamente, pero lo más valioso es que he logrado comprender que en SAS algunas cosas se resuelven en distintos tiempos (compilación y ejecución).

FreelanceReinh
Jade | Level 19

Hello @Hlm2019,

 

Minor correction: SYMGET is not a CALL routine, but a function.

 

Example (for @Roberto_BM):

data _null_;
set sashelp.class;
mvar='age'||put(age,2.);
if not symexist(mvar) then call symputx(mvar,name);
else call symputx(mvar,catx(' ',symget(mvar),name));
run;

%put &=age11;
%put &=age12;
%put &=age13;
...
Roberto_BM
Obsidian | Level 7

Thanks, FreelanceReinh. I'll check out your example. You're right, since technically, a routine isn't the same as a function. Anyway, I appreciate both of you for your support.

Hlm2019
SAS Employee

You're correct. Thanks for the correction. Regards.

Catch up on SAS Innovate 2026

Nearly 200 sessions are now available on demand in the Innovate Hub.

Watch Now →
Discussion stats
  • 8 replies
  • 2137 views
  • 2 likes
  • 4 in conversation