<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Reading quoted macro variables from data set SASHELP.VMACRO in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362697#M85704</link>
    <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/76464"&gt;@s_lassen&lt;/a&gt;&amp;nbsp;There is no way to know whether the original macro value has unquoted leading/trailing blanks by looking at the data available in SASHELP.VMACRO view. &amp;nbsp;The %SYMGET() macro that I posted removes the extra unquoted blanks by basically adding a %LET statement. &amp;nbsp;That functionality is not in the simplified %READ() macro posted by&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/16961"&gt;@ChrisNZ&lt;/a&gt;. But if you are careful in how you use the macro then SAS will ignore those extra blanks. &amp;nbsp;So if you avoid constructs like this that would preserve the blanks:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;title "Start %read(mvar) end";&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;And instead use constructs like this that remove them:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let localvar=%read(mvar);
title "Start &amp;amp;localvar end";&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You can avoid adding extra blanks.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Tue, 30 May 2017 13:12:53 GMT</pubDate>
    <dc:creator>Tom</dc:creator>
    <dc:date>2017-05-30T13:12:53Z</dc:date>
    <item>
      <title>Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362415#M85619</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I want to assign a value to a macro variable from the values stored in SASHELP.VMACRO.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Call symputx() seems to work, but I'd rather avoid creating 4GL code, and I'd prefer to keep all code as macro code so I can be called anywhere.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Function getvarc() doesnt quite conserve the quoted value though. Is there a way to do this?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%***  Assign a macro variable ***************;
%let a0=%str(     );

%***  Fetch macro variable value from data set ***************;
data T; set sashelp.vmacro;
  where NAME='A0';
  call symput ('a1',VALUE);
  call symputx('a2',VALUE);
run;
%let dsid=%sysfunc(open( SASHELP.VMACRO(where=(NAME='A0')), is));
%let rc  =%sysfunc(fetch(&amp;amp;dsid));
%let a3  =               %qsysfunc(getvarc(&amp;amp;dsid,%sysfunc(varnum(&amp;amp;dsid,VALUE))))   ;
%let a4  =%qsysfunc(trim(%qsysfunc(getvarc(&amp;amp;dsid,%sysfunc(varnum(&amp;amp;dsid,VALUE)))) ));
%let a5  =%trim(         %qsysfunc(getvarc(&amp;amp;dsid,%sysfunc(varnum(&amp;amp;dsid,VALUE)))) ) ;
%let rc  =%sysfunc(close(&amp;amp;dsid));

%***  Look at values fetched ***************;
%put A0 Len=%length(%superq(a0))*%substr(&amp;amp;a0,1,1)*%substr(&amp;amp;a0,2,1)*&amp;amp;a0*;
%put A1 Len=%length(%superq(a1))*%substr(&amp;amp;a1,1,1)*%substr(&amp;amp;a1,2,1)*&amp;amp;a1*;
%put A2 Len=%length(%superq(a2))*%substr(&amp;amp;a2,1,1)*%substr(&amp;amp;a2,2,1)*&amp;amp;a2*;
%put A3 Len=%length(%superq(a3))*%substr(&amp;amp;a3,1,1)*%substr(&amp;amp;a3,2,1)*&amp;amp;a3*;
%put A4 Len=%length(%superq(a4))*%substr(&amp;amp;a4,1,1)*%substr(&amp;amp;a4,2,1)*&amp;amp;a4*;
%put A5 Len=%length(%superq(a5))*%substr(&amp;amp;a5,1,1)*%substr(&amp;amp;a5,2,1)*&amp;amp;a5*;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;A0 Len=5* * *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&lt;BR /&gt;A1 Len=198* * *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Bad copy &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A2 Len=5* * *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp; Exact copy&lt;BR /&gt;A3 Len=198* * *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Bad copy&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A4 Len=1* ** *&amp;nbsp; Bad copy - Warnings&lt;BR /&gt;A5 Len=0****&amp;nbsp; Bad copy - Warnings&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 29 May 2017 04:15:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362415#M85619</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2017-05-29T04:15:54Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362417#M85620</link>
      <description>&lt;P&gt;Mmm, more tests, and variable A6 seems to be correct.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It seems that the value has to dumped as is&amp;nbsp;&lt;SPAN class="st"&gt;—&lt;/SPAN&gt; &lt;EM&gt;using %sysfunc() rather than %qsysfunc()&lt;/EM&gt; &lt;SPAN class="st"&gt;—&lt;/SPAN&gt; and the quoting is restored from the stored values &lt;SPAN class="st"&gt;—&lt;/SPAN&gt; &lt;EM&gt;probably using the stored quoting characters '01x and '02'x&lt;/EM&gt; &lt;SPAN class="st"&gt;—&lt;/SPAN&gt; without having to quote again.&lt;/P&gt;
&lt;P&gt;Interesting... Comments?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;
%***  Assign a macro variable ***************;
%let a0=%str(   ; ,  );

%***  Fetch macro variable value from data set ***************;
data _null_;
  set SASHELP.VMACRO;
  where NAME='A0';
  call symput ('a1',VALUE);
  call symputx('a2',VALUE);
run;
%let dsid=%sysfunc(open( SASHELP.VMACRO(where=(NAME='A0')), is));
%let rc  =%sysfunc(fetch(&amp;amp;dsid));
%let a3  =               %qsysfunc(getvarc(&amp;amp;dsid,%sysfunc(varnum(&amp;amp;dsid,VALUE))))   ;
%let a4  =%qsysfunc(trim(%qsysfunc(getvarc(&amp;amp;dsid,%sysfunc(varnum(&amp;amp;dsid,VALUE)))) ));
%*let a5  =%trim(         %qsysfunc(getvarc(&amp;amp;dsid,%sysfunc(varnum(&amp;amp;dsid,VALUE)))) ) ;
%let a6  =                %sysfunc(getvarc(&amp;amp;dsid,%sysfunc(varnum(&amp;amp;dsid,VALUE))))  ;
%let rc  =%sysfunc(close(&amp;amp;dsid));

%***  Look at values fetched ***************;
%put A0 Len=%length(%superq(a0))*%substr(%superq(a0),1,1)*%substr(%superq(a0),2,1)*%superq(a0)*;
%put A1 Len=%length(%superq(a1))*%substr(%superq(a1),1,1)*%substr(%superq(a1),2,1)*%superq(a1)*;
%put A2 Len=%length(%superq(a2))*%substr(%superq(a2),1,1)*%substr(%superq(a2),2,1)*%superq(a2)*;
%put A3 Len=%length(%superq(a3))*%substr(%superq(a3),1,1)*%substr(%superq(a3),2,1)*%superq(a3)*;
%put A4 Len=%length(%superq(a4))*%substr(%superq(a4),1,1)*%substr(%superq(a4),2,1)*%superq(a4)*;
%*put A5 Len=%length(%superq(a5))*%substr(%superq(a5),1,1)*%substr(%superq(a5),2,1)*%superq(a5)*;
%put A6 Len=%length(%superq(a6))*%substr(%superq(a6),1,1)*%substr(%superq(a6),2,1)*%superq(a6)*;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A0 Len=8* * *&amp;nbsp;&amp;nbsp; ; ,&amp;nbsp; *&lt;BR /&gt;A1 Len=198* * *&amp;nbsp;&amp;nbsp; ; ,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;BR /&gt;A2 Len=8* * *&amp;nbsp;&amp;nbsp; ; ,&amp;nbsp; *&lt;BR /&gt;A3 Len=198* * *&amp;nbsp;&amp;nbsp; ; ,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;BR /&gt;A4 Len=6* * *&amp;nbsp;&amp;nbsp; ; ,*&lt;BR /&gt;A6 Len=8* * *&amp;nbsp;&amp;nbsp; ; ,&amp;nbsp; *&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 29 May 2017 05:06:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362417#M85620</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2017-05-29T05:06:06Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362448#M85624</link>
      <description>&lt;P&gt;I experimented a bit with that some time ago. In order to get at the macro variables longer than 200 characters, it was necessary (or so I think) to use a data step - it was before DOSUBL, so I used a datastep view, which could be read using OPEN and FETCH.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Using DOSUBL, you can call a datastep in a macro function, so I created an updated version of my code:&lt;/P&gt;&lt;PRE&gt;%macro getmac(name,scope=);
  %local rc wherecls rval exist;
  %let scope=%upcase(&amp;amp;scope);
  %let name=%upcase(&amp;amp;name);
  %if %length(&amp;amp;scope) %then
    %let wherecls=scope="&amp;amp;SCOPE";
  %else
    %let wherecls=scope ne "GETMAC";&lt;BR /&gt;  %let exist=0;
  %let rc=%sysfunc(dosubl(%str(&lt;BR /&gt;    options nonotes;
    data _null_;
      length rval $32767;
      retain rval;
      set SASHELP.VMACRO(where=(name="&amp;amp;name" and &amp;amp;wherecls));
      by scope notsorted;
      substr(rval,_N_*200-199,200)=value;
      if .&amp;lt;dif(offset)&amp;lt;0 or last.scope; /* The dif(offset) in case of a macro calling itself */
      call symputx('rval',rval);&lt;BR /&gt;      call symputx('exist',1); /* this will only be executed if variable exists */
      stop;
    run;
    )));&lt;BR /&gt;%if not &amp;amp;exist %then %do;&lt;BR /&gt;  %if %length(&amp;amp;scope)=0 %then&lt;BR /&gt;    %put WARNING: macro variable &amp;amp;name not found;&lt;BR /&gt;  %else&lt;BR /&gt;    %put WARNING: macro variable &amp;amp;name not found in scope &amp;amp;scope;&lt;BR /&gt;  %let rval=%nrstr(&amp;amp;)&amp;amp;name;&lt;BR /&gt;  %end;
&amp;amp;rval
%mend;&lt;/PRE&gt;&lt;P&gt;It is a pure macro function, which will return the value assigned to macro variable &amp;amp;NAME in the most local scope (except %GETMAC itself), unless the SCOPE parameter is used.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Example of usage:&lt;/P&gt;&lt;PRE&gt;%let a1=GLOBAL;

%macro x(a1);
  %put GLOBAL A1: %getmac(a1,scope=global);
  %put LOCAL A1: %getmac(A1);
%mend;

%x(LOCAL);&lt;/PRE&gt;</description>
      <pubDate>Mon, 29 May 2017 09:36:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362448#M85624</guid>
      <dc:creator>s_lassen</dc:creator>
      <dc:date>2017-05-29T09:36:25Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362514#M85651</link>
      <description>&lt;P&gt;Use this macro.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://github.com/sasutils/macros/blob/master/symget.sas" target="_blank"&gt;https://github.com/sasutils/macros/blob/master/symget.sas&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I created it originally to let me retrieve&amp;nbsp;the value of a macro variable that is currently hidden by SAS's scoping rules by a similarly named local macro variable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 29 May 2017 15:17:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362514#M85651</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2017-05-29T15:17:33Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362517#M85652</link>
      <description>&lt;P&gt;If you try to store unquoted trailing spaces into the macro variable, say by using the older CALL SYMPUT() function.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;* Create macro variable with unquoted trailing spaces ;
data _null_;
  call symput('badmvar','123     ');
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then it will be impossible to recreate the exact value from the view. You will either get extra trailing spaces if you use CALL SYMPUT() or remove the unquoted trailing spaces if you use CALL SYMPUTX().&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Also if the&amp;nbsp;values can be long then you need to check the OFFSET variable in the VMACRO view. &amp;nbsp;In this case even quoted spaces might get trimmed if you are not careful when they&amp;nbsp;fall at the end of one of the earlier observations in the view. &amp;nbsp;If you are willing to limit support to 32K character strings that a data step can handle then you could build the string into one data step variable and then write it back into a macro variable at the end.&lt;/P&gt;</description>
      <pubDate>Mon, 29 May 2017 15:14:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362517#M85652</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2017-05-29T15:14:13Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362590#M85673</link>
      <description>&lt;P&gt;Thanks all for your interest.&lt;/P&gt;
&lt;P&gt;Macro %symget fails on quoted values.&lt;/P&gt;
&lt;P&gt;I think I have solved it. Unless I forgot to consider something?&lt;/P&gt;
&lt;P&gt;Here is a test macro:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%***  Fetch macro variable value from data set ***************;
%macro read(mvar=);
  %*** Init**********************************;
  %global a6;
  %local is_quoted is_ended pos i tmp offset;
  %let a6    =;
  %let offset=-200;
  %let mvar  =%upcase(&amp;amp;mvar);
  %*** Read value of macro variable**********;
  %let dsid=%sysfunc(open( SASHELP.VMACRO(where=(NAME="&amp;amp;mvar")), is));
  %let rc  =%sysfunc(fetch(&amp;amp;dsid));         
  %do %while(&amp;amp;rc=0);                            %* Append successive $200 lengths;
    %let offset=%eval(&amp;amp;offset+200);             %* Remember latest offset;
    %let a6 =%superq(a6)%qsysfunc(getvarc(&amp;amp;dsid,%sysfunc(varnum(&amp;amp;dsid,VALUE)))) ;
    %let rc =%sysfunc(fetch(&amp;amp;dsid));            
  %end;
  %let rc  =%sysfunc(close(&amp;amp;dsid)); 
  %*** Trim variable length******************;
  %* See is variable is quoted. Quotes start with '01'x and end with '02'x;
  %let dsid=%sysfunc(open( SASHELP.VMACRO(where=(NAME="&amp;amp;mvar" and first(VALUE)='01'x)), is));
  %let is_quoted=^%sysfunc(fetch(&amp;amp;dsid));  
  %let rc=%sysfunc(close(&amp;amp;dsid));               
  %if &amp;amp;is_quoted %then %do;                     %* Trim quoted variable;
    %do i= 1 %to 200;                           %* Find position of quote-end;
      %let dsid=%sysfunc(open( SASHELP.VMACRO
         (where=(NAME="&amp;amp;mvar" and OFFSET=&amp;amp;offset and char(VALUE,&amp;amp;i)='02'x)), is));
      %let is_ended=^%sysfunc(fetch(&amp;amp;dsid));  
      %let rc=%sysfunc(close(&amp;amp;dsid));          
      %if &amp;amp;is_ended %then %do;
        %let quoted_length=%eval(&amp;amp;offset+&amp;amp;i-2); %* Store position of quote-end;    
        %let i=200;
      %end;
    %end;
    %let a6=%qsubstr(%superq(a6),1,&amp;amp;quoted_length); %* Trim;  
  %end;
  %else %do;                                    %* Trim unquoted variable;
    %let a6=%qsysfunc(prxchange(s/^(.*?)\s*$/$1/,1,%superq(a6)));
  %end;
%mend;


%***  Test unquoted variable  ;
%let a0=%sysfunc(repeat(a,190))           c ;
%read(mvar=a0);
%let a7=%symget(a0);

%put -&amp;amp;=a0-;
%put -&amp;amp;=a6-;
%put -&amp;amp;=a7-;
%put A0 Len=%length(%superq(a0));
%put A6 Len=%length(%superq(a6));
%put A7 Len=%length(%superq(a7));

%***  Test quoted variable  ;
%let a1=%str( ; , &amp;amp;a0 %"            b   );
%read(mvar=a1);
%let a7=%symget(a0);

%put -&amp;amp;=a1-;
%put -&amp;amp;=a6-;
%put -&amp;amp;=a7-;
%put A1 Len=%length(%superq(a1));
%put A6 Len=%length(%superq(a6));
%put A7 Len=%length(%superq(a7));
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;77&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put -&amp;amp;=a0-;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier"&gt;-A0=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c-&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;78&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put -&amp;amp;=a6-;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;-A6=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c-&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;79&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put -&amp;amp;=a7-;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;-A7=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c-&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;80&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put A0 Len=%length(%superq(a0));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;A0 Len=203&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;81&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put A6 Len=%length(%superq(a6));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;A6 Len=203&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;82&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put A7 Len=%length(%superq(a7));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;A7 Len=203&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;83&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier"&gt;89&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put -&amp;amp;=a1-;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;-A1= ; , &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c "&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b&amp;nbsp;&amp;nbsp; -&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;90&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put -&amp;amp;=a6-;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;-A6= ; , &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c "&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b&amp;nbsp;&amp;nbsp; -&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;91&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put -&amp;amp;=a7-;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;-A7=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c-&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;92&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put A1 Len=%length(%superq(a1));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;A1 Len=226&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;93&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put A6 Len=%length(%superq(a6));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;A6 Len=226&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;94&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put A7 Len=%length(%superq(a7));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;A7 Len=203&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 30 May 2017 02:26:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362590#M85673</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2017-05-30T02:26:24Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362591#M85674</link>
      <description>&lt;P&gt;Ooops apologies.&lt;/P&gt;
&lt;P&gt;%symget works fine.&lt;/P&gt;
&lt;P&gt;I tested the wrong value.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier"&gt;86&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %let a7=%symget(a1);&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;90&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %put -&amp;amp;=a7-;&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;-A7= ; , &lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c "&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b&amp;nbsp;&amp;nbsp; -&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;A7 Len=226&lt;/FONT&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 30 May 2017 02:45:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362591#M85674</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2017-05-30T02:45:26Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362609#M85680</link>
      <description>&lt;P&gt;Using&amp;nbsp;&amp;nbsp; &lt;FONT face="courier new,courier"&gt;%syscall set()&amp;nbsp;&lt;/FONT&gt; makes everything so much more simple and compact.&lt;/P&gt;
&lt;P&gt;This is the final (is it ever?) version of the logic I'll use. It's a tiny macro now. &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro read(mvar);
  %local value dsid rc ;
  %let dsid=%sysfunc(open( SASHELP.VMACRO(where=(NAME=upcase("&amp;amp;mvar"))), is));
  %syscall set(dsid);                
  %let rc=%sysfunc(fetch(&amp;amp;dsid));       
  %do %while(&amp;amp;rc=0);&amp;amp;value%let rc=%sysfunc(fetch(&amp;amp;dsid));%end;
  %let rc=%sysfunc(close(&amp;amp;dsid));             
%mend;&lt;BR /&gt;&lt;BR /&gt;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;FONT face="courier new,courier"&gt;%put Original Len=%length(%superq(a0));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;%put Read&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Len=%length(%read(a0&amp;nbsp; ));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;%put Symget&amp;nbsp;&amp;nbsp; Len=%length(%symget(a0));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;%put Original Len=%length(%superq(a1));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;%put Read&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Len=%length(%read(a1&amp;nbsp; ));&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;%put Symget&amp;nbsp;&amp;nbsp; Len=%length(%symget(a1));&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="courier new,courier"&gt;Original Len=203&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;Read&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Len=203&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;Symget&amp;nbsp;&amp;nbsp; Len=203&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;Original Len=226&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;Read&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Len=226&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="courier new,courier"&gt;Symget&amp;nbsp;&amp;nbsp; Len=226&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 30 May 2017 04:52:21 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362609#M85680</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2017-05-30T04:52:21Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362624#M85683</link>
      <description>&lt;P&gt;The problem with using CALL SET that way is that the macro variables will be padded with unquoted blanks, up to the nearest multiple of 200.&lt;/P&gt;&lt;P&gt;For instance, using the simple %READ macro:&lt;/P&gt;&lt;PRE&gt;65         %let a=55;
 66         %put "%read(a)";
 "55                                                                                                                                 
                                                                      "
 67         %put %length(%read(a));
 2&lt;/PRE&gt;&lt;P&gt;The %length function will trim these unquoted blanks, but they are still there:&lt;/P&gt;&lt;PRE&gt; 56         %put %length(%read(a) b);
 202&lt;/PRE&gt;&lt;P&gt;As Tom remarked, there is no way to get the "correct" number of unquoted trailing blanks (e.g. as created by SYMPUT) from SASHELP.VMACRO - I prefer the datastep SYMPUTX solution (even though it reduces the maximum length of the variable to 32767) which trims these blanks from the final result. The other way you will have a lot of spurious blanks popping up in unexpected places.&lt;/P&gt;</description>
      <pubDate>Tue, 30 May 2017 06:12:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362624#M85683</guid>
      <dc:creator>s_lassen</dc:creator>
      <dc:date>2017-05-30T06:12:53Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362697#M85704</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/76464"&gt;@s_lassen&lt;/a&gt;&amp;nbsp;There is no way to know whether the original macro value has unquoted leading/trailing blanks by looking at the data available in SASHELP.VMACRO view. &amp;nbsp;The %SYMGET() macro that I posted removes the extra unquoted blanks by basically adding a %LET statement. &amp;nbsp;That functionality is not in the simplified %READ() macro posted by&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/16961"&gt;@ChrisNZ&lt;/a&gt;. But if you are careful in how you use the macro then SAS will ignore those extra blanks. &amp;nbsp;So if you avoid constructs like this that would preserve the blanks:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;title "Start %read(mvar) end";&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;And instead use constructs like this that remove them:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let localvar=%read(mvar);
title "Start &amp;amp;localvar end";&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You can avoid adding extra blanks.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 30 May 2017 13:12:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362697#M85704</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2017-05-30T13:12:53Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362909#M85793</link>
      <description>&lt;P&gt;I am not too concerned about trailing spaces, but you are right, one might as well so things properly once and for all.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This (Final V2!) code makes it all clean and dandy.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro read(mvar,innercall);         
  %local value dsid rc result;
  %if %length(&amp;amp;innercall) %then %do;           
    %let dsid=%sysfunc(open( SASHELP.VMACRO(where=(NAME=upcase("&amp;amp;mvar"))), is));
    %syscall set(dsid);                
    %let rc=%sysfunc(fetch(&amp;amp;dsid));       
    %do %while(&amp;amp;rc=0);&amp;amp;value%let rc=%sysfunc(fetch(&amp;amp;dsid));%end;
    %let rc=%sysfunc(close(&amp;amp;dsid));    
    %return;
  %end;   
  %let result=%read(&amp;amp;mvar,1);
  &amp;amp;result
%mend;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I can now use this logic in my main macro. &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Thank you &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/76464"&gt;@s_lassen&lt;/a&gt; and &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt;.&lt;/P&gt;</description>
      <pubDate>Tue, 30 May 2017 22:31:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/362909#M85793</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2017-05-30T22:31:10Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/363673#M86160</link>
      <description>&lt;P&gt;I finally decided to make it into a standalone macro, as Tom did for his.&lt;BR /&gt;The final final final version is below, in case anyone is interested, as an alternative to the one &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt; linked to (though its internal logic is not that different from Tom's).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*********************************************************************************************************************

  Name                symget.sas
  ¯¯¯¯
  Description         This macro retrieves the value of a macro variable regardless if its scope 
  ¯¯¯¯¯¯¯¯¯¯¯         -even if it's hidden by a local macro variable- by reading table SASHELP.VMACRO.

                      Further help is available as part of the macro

  Used as a function  Yes  
  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  Calls another macro No
  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯   
  Generates SAS code  No 
  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  Limitations         
  ¯¯¯¯¯¯¯¯¯¯¯         
*********************************************************************************************************************
 Who             When        What             
*********************************************************************************************************************
 C Graffeuille   2017-06-01  Initial version             
*********************************************************************************************************************/

%macro symget( help
             , mvar     =
             , where    =
             , err_msg  =Macro symget could not find this variable
             , innercall=
             ) ;                        %* innercall is for internal use only.;

  %**************** Help screen *********************;
  %if %length(%superq(help)) or %length(%superq(mvar))=0 %then %do;
    %local mlogic pagesize;
    %let mlogic  =%sysfunc(getoption(mlogic  ));
    %let pagesize=%sysfunc(getoption(pagesize));
    options nomlogic pagesize=500;
    %put %nrstr(                                                                                      );
    %put %nrstr(**************************************************************************************);
    %put %nrstr(*  _____________________________                                                     *);
    %put %nrstr(*  Help screen for macro  symget                                                     *);
    %put %nrstr(*  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯                                                     *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*  This macros retrieves the value of a macro variable                               *);
    %put %nrstr(*  regardless if its scope, even if it%'s hidden by a local macro variable.           *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*  Parameters:                                                                       *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*    macvar=          REQD  Name of the macro variable to read.                      *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*    where=           OPTL  Specify conditions on the SCOPE.                         *);
    %put %nrstr(*                             Default=&amp;lt;blank&amp;gt; (i.e. nearest scope)                   *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*    err_msg=         OPTL  Value returned is teh variable is not found.             *);
    %put %nrstr(*                             Default=Macro symget could not find this variable      *);
    %put %nrstr(*  Examples:                                                                         *);
    %put %nrstr(*            1- %put Value=%symget(mvar=DSN12);                                      *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*            2- %macro outer;                                                        *);
    %put %nrstr(*                 %local mvar; %let mvar=outerval;                                   *);
    %put %nrstr(*                 %inner;                                                            *);
    %put %nrstr(*               %mend;                                                               *);
    %put %nrstr(*               %macro inner;                                                        *);
    %put %nrstr(*                 %local mvar; %let mvar=innerval;                                   *);
    %put %nrstr(*                 %put -&amp;gt; %Symget(mvar=mvar,where=&amp;amp;wh) &amp;lt;- (&amp;amp;=wh);                    *);
    %put %nrstr(*               %mend;                                                               *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*               %let mvar=globalval;                                                 *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*               %let wh=;                                                            *);
    %put %nrstr(*               %outer;                                                              *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*               %let wh=SCOPE ne 'INNER';                                            *);
    %put %nrstr(*               %outer;                                                              *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*               %let wh=SCOPE eq 'GLOBAL';                                           *);
    %put %nrstr(*               %outer;                                                              *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*               %let wh=SCOPE eq 'ZZZ';                                              *);
    %put %nrstr(*               %outer;                                                              *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*               -&amp;gt; innerval &amp;lt;- (WH=)                                                 *);
    %put %nrstr(*               -&amp;gt; outerval &amp;lt;- (WH=SCOPE ne 'INNER')                                 *);
    %put %nrstr(*               -&amp;gt; globalval &amp;lt;- (WH=SCOPE eq 'GLOBAL')                               *);
    %put %nrstr(*               -&amp;gt; Macro symget could not find this variable &amp;lt;- (WH=SCOPE eq 'ZZZ')  *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(*            3- %symget(help) displays this help screen.                             *);
    %put %nrstr(*                                                                                    *);
    %put %nrstr(**************************************************************************************);
    %put %nrstr(                                                                                      );
    options &amp;amp;mlogic. ps=&amp;amp;pagesize.;
    %return;
  %end;

  %**************** Init *************************************;
  %local value scope myscope dsid rc result;

  %**************** Vet input parameters *********************;
  %if %sysfunc(notname(%superq(mvar))) 
    | %sysfunc(anydigit(%superq(mvar)))=1 
    | %length(%superq(mvar)) &amp;gt; 32 %then %do;
    %put %str(E)RROR: Value of parameter MVAR for macro SYMGET is not a valid SAS name.; 
    &amp;amp;err_msg
    %return;
  %end;

  %**************** Start processing *************************;
  %if %length(&amp;amp;innercall) %then %do;    %* Recursed logic. The work is done here.;       
    %let dsid=%sysfunc(open( SASHELP.VMACRO(where=(NAME=upcase("&amp;amp;mvar") 
                                                 and SCOPE ne 'SYMGET'
          %sysfunc(ifc(%length(%superq(where) ), and %superq(where), ))
                                           )), is));
    %if &amp;amp;dsid=0 %then %do;              %* Could not open SASHELP.VMACRO;
       %put %str(E)RROR: Value of parameter WHERE for macro SYMGET is invalid.; 
       &amp;amp;err_msg
       %return;                         %* This can only be due to a bad where clause;
    %end;                 
    %syscall set(dsid);                 %* Populate variables value and offset automatically;
    %let rc=%sysfunc(fetch(&amp;amp;dsid));     %* Fetch variables in data set;
    %if &amp;amp;rc. %then &amp;amp;err_msg.;           %* No macro variable with that name found in data set;
    %let myscope=&amp;amp;scope;                %* Ensure that only one scope is parsed;
    %do %while(&amp;amp;rc=0);&amp;amp;value            %* Write out fetched value;
      %let rc=%sysfunc(fetch(&amp;amp;dsid));   %* Fetch variables in data set; 
      %if &amp;amp;scope ne &amp;amp;myscope %then %let rc=1; %* Stop. Variable name found in higher scope;
    %end;                               %* Loop until no more records (or higher scope);                 
    %let rc=%sysfunc(close(&amp;amp;dsid));     %* Close table;
    %return;                            %* The recursion logic stops here;
  %end;   

  %* Use intermediate variable "result" to trim trailing blanks;
  %* Doing this means we must recurse for some reason;
  %let result=%symget(mvar=&amp;amp;mvar,where=%superq(where),innercall=1);
  &amp;amp;result
%mend;


&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 02 Jun 2017 02:30:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/363673#M86160</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2017-06-02T02:30:50Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/364021#M86273</link>
      <description>&lt;P&gt;The current logic in this version will concatenate the values from all of the instances of the same macro name in different scopes that happen to have the same scope name. That can happen if you use recursive or nested macro calls. &amp;nbsp;You need stop when you find another observation with OFFSET=0. That indicates you have started the value for a new macro variable.&lt;/P&gt;</description>
      <pubDate>Sat, 03 Jun 2017 15:47:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/364021#M86273</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2017-06-03T15:47:20Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/364042#M86284</link>
      <description>You are right of course &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt;. I was doing just that and then I "simplified" the code. Thank you!</description>
      <pubDate>Sat, 03 Jun 2017 21:44:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/364042#M86284</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2017-06-03T21:44:01Z</dc:date>
    </item>
    <item>
      <title>Re: Reading quoted macro variables from data set SASHELP.VMACRO</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/364411#M86435</link>
      <description>&lt;P&gt;So the&amp;nbsp;final&amp;nbsp;final&amp;nbsp;final&amp;nbsp;final version....&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  %**************** Init *************************************;
  %local value offset thisoffset dsid rc result; %* value and offset are populated by %syscall set();
  %let thisoffset=-1;

  %**************** Vet input parameters *********************;
  %if %sysfunc(notname(%superq(mvar))) 
    | %sysfunc(anydigit(%superq(mvar)))=1 
    | %length(%superq(mvar)) &amp;gt; 32 %then %do;
    %put %str(E)RROR: Value of parameter MVAR for macro SYMGET is not a valid SAS name.; 
    &amp;amp;err_msg
    %return;
  %end;

  %**************** Start processing *************************;
  %if %length(&amp;amp;innercall) %then %do;    %* Recursed logic. The work is done here.;       
    %let dsid=%sysfunc(open(SASHELP.VMACRO(where=( NAME  eq upcase("&amp;amp;mvar") 
                                                 &amp;amp; SCOPE ne 'SYMGET'    
                                                 &amp;amp; %sysfunc(coalescec(%superq(where),1))
                                           )), is));
    %if &amp;amp;dsid=0 %then %do;              %* Could not open SASHELP.VMACRO;
       %put %str(E)RROR: Value of parameter WHERE for macro SYMGET is invalid.; 
       &amp;amp;err_msg
       %return;                         %* This can only be due to a bad where clause;
    %end;                 
    %syscall set(dsid);                 %* Populate variables value and offset automatically;
    %let rc=%sysfunc(fetch(&amp;amp;dsid));     %* Fetch variables in data set;
    %if &amp;amp;rc. %then &amp;amp;err_msg.;           %* No macro variable with that name found in data set;
    %do %while(&amp;amp;rc=0);
      %if &amp;amp;thisoffset &amp;lt; &amp;amp;offset %then %do; %* Ensure that only one variable is parsed;
        %let thisoffset=&amp;amp;offset;&amp;amp;value  %* Write out fetched value;
        %let rc=%sysfunc(fetch(&amp;amp;dsid)); %* Fetch variable values in data set; 
      %end;
      %else %let rc=1;                  %* Stop. Same variable name found in higher scope;
    %end;                               %* Loop until no more records (or higher scope);                 
    %let rc=%sysfunc(close(&amp;amp;dsid));     %* Close table;
    %return;                            %* The recursion logic stops here;
  %end;   

  %* Use intermediate variable "result" to trim trailing blanks;
  %* Doing this means we must recurse for some reason;
  %let result=%symget(mvar=&amp;amp;mvar,where=%superq(where),innercall=1);
  &amp;amp;result
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 05 Jun 2017 23:41:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Reading-quoted-macro-variables-from-data-set-SASHELP-VMACRO/m-p/364411#M86435</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2017-06-05T23:41:13Z</dc:date>
    </item>
  </channel>
</rss>

