2016-03-01 120 views
2

我目前在使用遞增數據範圍輸出表時遇到問題,該表使用充滿JobOffers的電子郵件表填充已使用VBA重命名的表 - 這更適合我自己的學習。SAS SQL宏增量日期範圍

我想通過幾天的代碼迴路我可以在宏命令

%EmailDump('01Jan2015'd,'02Jan2015') 

設置它將運行在下面的代碼宏並允許我在此期限內拉回來所有的電子郵件和導出(我明白我每次都在寫表 - 但是這將出口(每個出口應該是不同的,因爲它有內它EmailStart宏)

因此,對於這個有些假數據會看起來像

主題EmailS tartDate

工作機會2015年12月1日

工作機會25/01/2015

工作機會2015年12月5日

使用的代碼是低於

%Macro EmailDump(begindate,endindate); 

%do 
EmailStart = &begindate. 
%to &endindate. 
%by 1; 

%end; 

PROC SQL; 

CREATE TABLE WORK.EMAILDUMP AS 

SELECT * FROM WORK.EMAILS 

WHERE TOPIC = 'JobOffer' 

and EmailStartDate = &EmailStart 

;QUIT; 

proc export data=work.EMAILDUMP 

dbms=XLSX 

outfile="/p01/Output File &EmailStart " replace; 

run; 

%Mend EmailDump; 

%EmailDump('01Jan2015'd,'02Jan2015'd); 

錯誤信息如下所示

錯誤:在需要數字操作數的%EVAL函數或%IF條件中找到字符操作數。條件是: & begindate。 錯誤:%DO EmailStart循環的%FROM值無效。 錯誤:在需要數字操作數的%EVAL函數或%IF條件中找到字符操作數。條件是: & endindate。 錯誤:%DO EmailStart循環的%TO值無效。 錯誤:宏EmailDump將停止執行


不知道是否有人能幫助我嗎?非常感謝任何幫助!

+0

您應該更具體地描述您遇到的問題。遇到錯誤消息時分享。具體說明你想要的代碼。 – floydn

+0

從代碼的粗略看來,我發現應該將%end語句向下移動並放置在proc導出之後。假設你想要proc sql和proc export在循環中每天運行。當然,我只能假設,因爲你沒有分享你對代碼的期望。 – floydn

+0

通過移動%end語句,您的宏將爲每一天生成一對proc sql和proc導出語句,但work.emaildump和Excel文件將在每次執行循環期間被覆蓋。無論您循環使用多少天,這兩個文件將只包含循環中的最後一天。除非您澄清該計劃的目的和預期結果,否則我不會再評論。 – floydn

回答

3

下面是你的代碼簡化爲僅包含需要什麼來重現問題:如果我們用文字把它

%macro emaildump(begindate,endindate); 
    %do emailstart = &begindate %to &endindate; 
    %put &emailstart; 
    %end; 
%mend emaildump; 

,我們得到你所描述的消息:

%emaildump('01jan2015'd,'02jan2015'd); 

得到:

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric 
     operand is required. The condition was: &begindate 
ERROR: The %FROM value of the %DO EMAILSTART loop is invalid. 
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric 
     operand is required. The condition was: &endindate 
ERROR: The %TO value of the %DO EMAILSTART loop is invalid. 
ERROR: The macro EMAILDUMP will stop executing. 

但是,如果我們傳遞原始日期值(它們僅表示爲整數)它工作正常。我們可以使用mdy()函數計算原始日期值。因爲我們的宏語言這樣做,我們將需要包裝mdy()%sysfunc()

%let start = %sysfunc(mdy(1,1,2015)); 
%let end = %sysfunc(mdy(1,2,2015)); 
%emaildump(&start,&end); 

即爲所需的輸出:

20089 
20090 

另外,您還可以使用%sysevalf()評價文字並將其轉換爲數字是這樣的:

%let start = %sysevalf('01Jan2015'd); 
%let end = %sysevalf('02Jan2015'd); 
%emaildump(&start,&end); 

如昆汀在下面的評論指出......發生這種情況的原因是因爲:

it's a limitation of the fact that %DO statement implicitly calls %EVAL , and %EVAL can't handle date literals.

+0

這是完美的 - 非常感謝你! – Brecon

+3

我不認爲這是一個錯誤。但是,這是%DO語句隱式調用%EVAL並且%EVAL無法處理日期文字的一個限制。 '%put%eval('01Jan2015'd);'會報錯,但'%put%sysevalf('01Jan2015'd);'不會。建議可能'%做emailstart =%sysevalf(&begindate)%到%sysevalf(&endindate);'是一個選項。 – Quentin

+0

啊,真棒,感謝昆汀,我總是想知道幕後發生了什麼事情導致這個問題。我會更新答案以包含此信息。 –