BookmarkSubscribeRSS Feed
mathias
Quartz | Level 8

Hi,

in graph proc templatet this entrytitle works :

entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,%sysfunc(inputn(2013-12-21,IS8601DA10.)),1, same))-1),IS8601DA10.))"  ;

_byval_ is a dynamic variable: dynamic  _byval_;

(= a date like this 2013-12-21)

&timeFrame = semiyear

-> From 2013-01-01 To 2014-06-20

but I would like to replace 2013-12-21 with the value of dynamic variable _byval_

I tried these 3 things :

> entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,%sysfunc(inputn(_byval_,IS8601DA10.)),1, same))-1),IS8601DA10.))"  ;

> entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,%sysfunc(inputn(" _byval_ ",IS8601DA10.)),1, same))-1),IS8601DA10.))"  ;

> %let byval=_byval_;

> entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,%sysfunc(inputn(&byval,IS8601DA10.)),1, same))-1),IS8601DA10.))"  ;

but it does not work.

Would any of you have an idea how to solve my problem ?

Many thanks !

guest.png

Here is the full template code --------------------------------------------

proc template; define statgraph &template_map;

    dynamic _BYLINE_ _byval_;

    begingraph;

        title;footnote;

        /*entrytitle _byval_;

       

        entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,%sysfunc(inputn(2013-12-21,IS8601DA10.)),1, same))-1),IS8601DA10.))"  ;

        */

        %let test=_byval_;

        entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,%sysfunc(inputn(&test,IS8601DA10.)),1, same))-1),IS8601DA10.))"  ;

       

        rangeattrmap name="densityrange" ;

            range 0 - &maxIncidence /

                rangealtcolormodel=threecolorramp ;

            endrangeattrmap;

        rangeattrvar attrvar=range_estimate var=z

            attrmap="densityrange" ;

        layout overlay /

            xaxisopts=(display=none)

            yaxisopts=(display=none)

            /*wallcolor=black*/;

            scatterplot x = x y = y /

                markercolorgradient = range_estimate

                markerattrs=(symbol=squarefilled

                    size=%sysevalf(1+2*&gridSize/1000))

                name = "kriging"

                ;

            *contourplotparm x=gxc y=gyc z=rangevar /

                name="kriging"

                contourtype=gradient

                ;

            continuouslegend "kriging" /

                orient = vertical

                location = outside

                title="[Cases / 1e5 inhabitants / &timeStep]"

                ;

            *scatterplot x= x y = y /

                markerattrs=(size=1 color=black)

                ;

            endlayout;

        endgraph;

    end;run;

11 REPLIES 11
ballardw
Super User

Is your variable referenced in the BY text, i.e. "2013-12-31"  or a numeric formatted as such?

And when you say "doesn't work" do you get error messages or unexpected output? If so, post the results.

mathias
Quartz | Level 8

Yes it is text : "2013-12-31"

I get errors, but nothing helpfull there.

mathias
Quartz | Level 8

First error:

WARNING: Argument 1 to function INPUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is out of range.
NOTE: Mathematical operations could not be performed during %SYSFUNC function execution. The result of the operations have been set to a missing value.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: .-1
ERROR: %SYSEVALF function has no expression to evaluate.
ERROR: Argument 1 to function PUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is not a number.
ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list. Execution of %SYSCALL statement or %SYSFUNC or %QSYSFUNC function reference is terminated.
ERROR: The macro TIMEKRIGE will stop executing.

Second error:

cannot compile macro :

WARNING: An argument to the function INTNX referenced by the %SYSFUNC or %QSYSFUNC macro function is

         out of range.

NOTE: Mathematical operations could not be performed during %SYSFUNC function execution. The result

      of the operations have been set to a missing value.

22       

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand

       is required. The condition was: .-1

ERROR: %SYSEVALF function has no expression to evaluate.

ERROR: Argument 1 to function PUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is not a

       number.

ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list.  Execution of

       %SYSCALL statement or %SYSFUNC or %QSYSFUNC function reference is terminated.

Third error:

WARNING: Argument 1 to function INPUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is out of range.
NOTE: Mathematical operations could not be performed during %SYSFUNC function execution. The result of the operations have been set to a missing value.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: .-1
ERROR: %SYSEVALF function has no expression to evaluate.
ERROR: Argument 1 to function PUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is not a number.
ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list. Execution of %SYSCALL statement or %SYSFUNC or %QSYSFUNC function reference is terminated.
ERROR: The macro TIMEKRIGE will stop executing.

ballardw
Super User

You didn't show WHICH line generated the errors.

mathias
Quartz | Level 8

Just to be sure there no format problem I tried to use _byval_as if it was a number :

entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,_byval_,1, same))-1),IS8601DA10.))" ;

ERROR: Argument 2 to function INTNX referenced by the %SYSFUNC or %QSYSFUNC macro function is not a number.
ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list. Execution of %SYSCALL statement or %SYSFUNC or %QSYSFUNC function reference is terminated.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: .-1
ERROR: %SYSEVALF function has no expression to evaluate.
ERROR: Argument 1 to function PUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is not a number.
ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list. Execution of %SYSCALL statement or %SYSFUNC or %QSYSFUNC function reference is terminated.
ERROR: The macro TIMEKRIGE will stop executing.

ballardw
Super User

This one we know the error is because the value of _byval_ is not numeric, so not unexpected.

I suspect you may be using macro functions where they aren't needed. Have you tried using the GTL Eval with the functions and no macro functions?

mathias
Quartz | Level 8

The errors are respectively for the 3 tests I made :

I tried these 3 things :

> entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,%sysfunc(inputn(_byval_,IS8601DA10.)),1, same))-1),IS8601DA10.))"  ;

> entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,%sysfunc(inputn(" _byval_ ",IS8601DA10.)),1, same))-1),IS8601DA10.))"  ;

> %let byval=_byval_;

> entrytitle "From " _byval_ " To %sysfunc(putn(%eval(%sysfunc(INTNX(&timeFrame,%sysfunc(inputn(&byval,IS8601DA10.)),1, same))-1),IS8601DA10.))"  ;

I didn't knew about eval but reading the documentation I cannot figure how to use it in my case.

So researched a little bit further.

I think I'am close, it's just a matter of format of _byval_

entrytitle "From " _byval_ " To %sysfunc(INTNX(Week," _byval_ ",1, same))";

--> "From 2013-01-01 To ."

ERROR: Argument 2 to function INTNX referenced by the %SYSFUNC or %QSYSFUNC macro function is not a number.

entrytitle "From " _byval_ " To %sysfunc(inputn(" _byval_ ",IS8601DA10.))";

--> "From 2013-01-01 To ."

WARNING: Argument 1 to function INPUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is out of range.

entrytitle "From " _byval_ " To %sysfunc(inputn(2013-01-01,IS8601DA10.))";

--> "From 2013-01-01 To 19359"

No errors

entrytitle "From " _byval_ " To %sysfunc(inputn(%sysfunc(trim(" _byval_ ")),IS8601DA10.))";

--> "From 2013-01-01 To ."

WARNING: Argument 1 to function INPUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is out of range.

With these 4 tests I can conclude that _byval_ is not a number and is not = to 2013-01-01.

But what is it ? how can I figure ?

entrytitle "From " _byval_ " To %sysfunc(trim(" _byval_ "))";

--> "From 2013-01-01 To 2013-01-01"

jteres
Obsidian | Level 7

I am a little bit out on a limb here, but I think this has to do with what's available at runtime and what's available at compile time. I believe that dynamics exist only at runtime, when the template is used in an SGRender statement, whereas the macro logic tries to resolve at compile time, when the template code is created. But the system dynamic variable _byvar_ has no meaning at that time.

DanH_sas
SAS Super FREQ

I believe jteres is correct. I do not have the data to try this, but can you boil away the macros to something like this?


entrytitle "From " _BYVAL_ " To " eval(putn((INTNX(TIMEFRAME,inputn(_BYVAL_,IS8601DA10.),1, same)-1),IS8601DA10.))


You will have to make TIMEFRAME a dynamic that is passed into SGRENDER.


Hope this works,

Dan

mathias
Quartz | Level 8

I'am afraid eval does not work here.

I tried a simplified one :

entrytitle "From " _BYVAL_ " To " eval(inputn(_BYVAL_,IS8601DA10.)) ;

ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant, a missing value, (, +, -, INPUT, NOT, PUT, ^, ~. 
ERROR 76-322: Syntax error, statement will be ignored.

RSJag
Calcite | Level 5


Hi,

Another way of doing this is to get rid of the by statement in the proc sgrender, and use a do loop to go through the data.
This will enable you to create the macrovar you want, and use it in a title statement.
I'm not sure if this is still relevant for Mathias (after two years), but just in case here is an example;

/*--------------------------------------------------------*/

ods path(prepend) work.templat(update);

 

%let timeframe=semiyear;

 

proc template;
define statgraph sgnoby;
begingraph;
 layout overlay;
  scatterplot x=PAN y=PANF / name='scatter' ;
 endlayout;
endgraph;
end;
run;


data _null_;
set SASHELP.CITIYR end=last;
 call symput ('date'||strip(put(_n_,best.)),date);
 if last then
  call symput('ndates',strip(put(_n_,best.)));
run;


%macro noby;

 

%do i=1 %to &ndates;

 

data _null_;
set SASHELP.CITIYR(where=(date=&&date&i));
 call symput('realdate',strip(put(date,date9.)));
 call symput('mdupdate',strip(put((INTNX("&timeframe",(date),1)),date9.)));
run;

 

title "&realdate" ' - ' "&mdupdate";
proc sgrender data=SASHELP.CITIYR(where=(date=&&date&i)) template=sgnoby;
options nobyline;
run;

 

%end;

 

%mend noby;

%noby

/*--------------------------------------------------------*/

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 11 replies
  • 3191 views
  • 0 likes
  • 5 in conversation