Sas 计算内部字符值

Sas 计算内部字符值,sas,sas-macro,Sas,Sas Macro,我有类似“sometext{5+1.5}”的字符串值,并希望在数据步骤中计算它。(此值来自列,但无所谓) 我有一段代码,执行正确,但宏中有错误。但如果在没有宏的情况下执行,则不会出现错误。我想在宏内部执行它,如何修复错误?在不使用选项的情况下,NOERRORABEND NODMSSYNCHK NOSYNTEXCHECK。算法是使用tranwrd“{”更改为%sysevalf(“和“}”更改为”) 正常工作的代码,但日志中有错误: %macro t; data have_in_macro; %le

我有类似“sometext{5+1.5}”的字符串值,并希望在数据步骤中计算它。(此值来自列,但无所谓)

我有一段代码,执行正确,但宏中有错误。但如果在没有宏的情况下执行,则不会出现错误。我想在宏内部执行它,如何修复错误?在不使用
选项的情况下,NOERRORABEND NODMSSYNCHK NOSYNTEXCHECK。算法是使用
tranwrd
“{”
更改为
%sysevalf(“
“}”
更改为

正常工作的代码,但日志中有错误:

%macro t;
data have_in_macro;
%let value=%sysfunc(tranwrd(
                          %sysfunc(tranwrd(
                                        "some text {5+1.5}",%str(}),%str(%))
                              )),%str({),%str(sysevalf)%str(%()
                ));

                %let value=%sysfunc(tranwrd(
                            %str(&value),%str(sysevalf),%str(%%)%str(sysevalf)
                ));
                t=&value;
run;
%mend t;

%t;
data have;
%let value=%sysfunc(tranwrd(
                          %sysfunc(tranwrd(
                                        "some text {5+1.5}",%str(}),%str(%))
                              )),%str({),%str(sysevalf)%str(%()
                ));

                %let value=%sysfunc(tranwrd(
                            %str(&value),%str(sysevalf),%str(%%)%str(sysevalf)
                ));
                t=&value;
run;
无错误但不使用宏的代码:

%macro t;
data have_in_macro;
%let value=%sysfunc(tranwrd(
                          %sysfunc(tranwrd(
                                        "some text {5+1.5}",%str(}),%str(%))
                              )),%str({),%str(sysevalf)%str(%()
                ));

                %let value=%sysfunc(tranwrd(
                            %str(&value),%str(sysevalf),%str(%%)%str(sysevalf)
                ));
                t=&value;
run;
%mend t;

%t;
data have;
%let value=%sysfunc(tranwrd(
                          %sysfunc(tranwrd(
                                        "some text {5+1.5}",%str(}),%str(%))
                              )),%str({),%str(sysevalf)%str(%()
                ));

                %let value=%sysfunc(tranwrd(
                            %str(&value),%str(sysevalf),%str(%%)%str(sysevalf)
                ));
                t=&value;
run;
输入:

一些文本{5+1.5}

输出:

一些文本6.5

使用宏时出错:

错误:%SYSEVALF后面必须跟一个包含在 括号


p.S.此代码只是调用算法调用
tranwrd

得到的调用示例错误。如果您使用的是
data\u null\ucode>步骤,则可以使用数据步骤函数,而不是宏函数

这对我很有效-没有错误

我将其分为两行,第一行是将
{
替换为
%sysevalf(
}
替换为

编辑:使用RESOLVE()计算字符串

data have;
yourStringVariable = "some text {5+1.5}";
run;
    
  %macro t(input_dsn= , output_dsn = );  
    data &output_dsn.;
    set &input_dsn.;
     *replace {;
     text_string2 = tranwrd(yourStringVariable, '{', '%sysevalf(');
     *replace };
     text_string3 = resolve(tranwrd(text_string2, '}', ')'));

    run;
    
%mend t;

%t(input_dsn=have, output_dsn=want);;

proc print data=want;
run;

如果使用的是
data\u null\u
步骤,则可以使用数据步骤函数,而不是宏函数

这对我很有效-没有错误

我将其分为两行,第一行是将
{
替换为
%sysevalf(
}
替换为

编辑:使用RESOLVE()计算字符串

data have;
yourStringVariable = "some text {5+1.5}";
run;
    
  %macro t(input_dsn= , output_dsn = );  
    data &output_dsn.;
    set &input_dsn.;
     *replace {;
     text_string2 = tranwrd(yourStringVariable, '{', '%sysevalf(');
     *replace };
     text_string3 = resolve(tranwrd(text_string2, '}', ')'));

    run;
    
%mend t;

%t(input_dsn=have, output_dsn=want);;

proc print data=want;
run;

您对宏的
tranwrd
调用过于复杂,您在
sysevalf
中引入的
%
是在之后而不是之前进行的

代码示例(下面更进一步)有一个更简单的表达式,用于解析硬编码的

"some text {5+1.5}"
转化为内部中间产物

"some text %sysevalf(5+1.5)"
在最外层的sysfunc
上下文中。因为最外层是
%SYSFUNC
,而不是
%QSYSFUNC
,所以宏系统将隐式地进一步将中间值解析为符号
的最终宏赋值

 "some text 6.5"
示例代码:

%macro t;
data have_in_macro;

    %let value = %sysfunc(tranwrd(
                          %sysfunc(tranwrd(
                                          "some text {5+1.5}",
                                          },
                                          %str(%))
                                          )
                          ),
                          {,
                          %nrstr(%sysevalf%()
                ));

%put NOTE: (MACRO &sysmacroname.) value=%superq(value);

                t=&value;
run;
%mend t;

%t

ods listing;

proc print data=have_in_macro;
run;
日志

输出

The SAS System

Obs          t

 1     some text 6.5

您对宏的
tranwrd
调用过于复杂,您在
sysevalf
中引入的
%
是在之后而不是之前进行的

代码示例(下面更进一步)有一个更简单的表达式,用于解析硬编码的

"some text {5+1.5}"
转化为内部中间产物

"some text %sysevalf(5+1.5)"
在最外层的sysfunc
上下文中。因为最外层是
%SYSFUNC
,而不是
%QSYSFUNC
,所以宏系统将隐式地进一步将中间值解析为符号
的最终宏赋值

 "some text 6.5"
示例代码:

%macro t;
data have_in_macro;

    %let value = %sysfunc(tranwrd(
                          %sysfunc(tranwrd(
                                          "some text {5+1.5}",
                                          },
                                          %str(%))
                                          )
                          ),
                          {,
                          %nrstr(%sysevalf%()
                ));

%put NOTE: (MACRO &sysmacroname.) value=%superq(value);

                t=&value;
run;
%mend t;

%t

ods listing;

proc print data=have_in_macro;
run;
日志

输出

The SAS System

Obs          t

 1     some text 6.5

抱歉,若问题中不清楚,但我需要在dataset变量和内部宏中输出它;(这更容易:)抱歉,如果问题不清楚,但我需要在dataset变量和内部宏中输出它;(这更容易:)这两个%LET语句将在数据步骤开始运行之前执行,因此,如果将它们放在数据语句之前,阅读程序的人会更清楚。@Tom我在执行数据步骤之前,使用
getvarc
open
,所以%let语句只用于调用我得到的错误。不确定您的答复对我的评论有何影响。您是说您正在使用宏逻辑从数据集读取数据并生成数据步骤代码以创建另一个数据集?如果是,那么如果希望生成的数据集具有多个观测值,请确保生成输出语句。是的,请确保。我生成输出语句,thanx:)两个%LET语句将在数据步骤开始运行之前执行,因此,如果将它们放在数据语句之前,阅读程序的人会更清楚。@Tom我在执行数据步骤之前,使用
getvarc
open
,读取数据集,所以%let语句只用于调用我得到的错误。不确定您的答复对我的评论有何影响。您是说您正在使用宏逻辑从数据集读取数据并生成数据步骤代码以创建另一个数据集?如果是,那么如果希望生成的数据集具有多个观测值,请确保生成输出语句。是的,请确保。我生成输出语句,thanx:)