Tôi sẽ trả lời câu hỏi cốt lõi Bambi hỏi trong ý kiến:
mối quan tâm chính của tôi ở đây là làm thế nào để trả về một giá trị từ một macro.
Tôi sẽ phân biệt với Dirk ở đây một cách quan trọng. Anh ấy nói:
Một macro chèn mã. Nó không bao giờ có thể trả về một giá trị, mặc dù trong một số trường hợp, bạn có thể bắt chước các hàm
Tôi không đồng ý. Một macro SAS trả về văn bản được chèn vào luồng xử lý. Trả về hoàn toàn là một thuật ngữ thích hợp cho điều đó. Và khi văn bản xảy ra là một số duy nhất, thì tốt hơn là nói rằng nó trả về một giá trị.
Tuy nhiên, macro chỉ có thể trả về một giá trị nếu macro chỉ có câu lệnh macro ngoài giá trị đó. Có nghĩa là, mỗi dòng phải bắt đầu bằng một số %
. Bất cứ điều gì không bắt đầu với %
sẽ được trả lại (và một số thứ bắt đầu với %
cũng có thể được trả lại).
Vì vậy, câu hỏi quan trọng là, Làm cách nào để trả lại chỉ giá trị từ macro.
Trong một số trường hợp, như thế này, nó hoàn toàn có thể xảy ra với chỉ mã vĩ mô. Trong thực tế, trong nhiều trường hợp, điều này là có thể về mặt kỹ thuật - mặc dù trong nhiều trường hợp nó hoạt động nhiều hơn bạn nên làm.
Kết nối của Jack Hamilton paper bao gồm ví dụ phù hợp tại đây. Ông bác bỏ ví dụ này, nhưng đó là phần lớn vì bài báo của ông là về việc đếm các quan sát trong trường hợp NOBS sai - hoặc với mệnh đề WHERE hoặc trong một số trường hợp khác mà bộ dữ liệu đã được sửa đổi mà không cần cập nhật siêu dữ liệu NOBS.
Trong trường hợp của bạn, bạn có vẻ hoàn toàn hạnh phúc khi tin tưởng NOBS - vì vậy ví dụ này sẽ thực hiện.
Một vĩ mô mà trả về một giá trị phải có chính xác một tuyên bố rằng một trong hai không phải là một tuyên bố cú pháp vĩ mô, hoặc là một tuyên bố cú pháp vĩ mô mà trả về một giá trị vào trong dòng xử lý. %sysfunc
là một ví dụ về một tuyên bố làm như vậy. Những thứ như %let
, %put
, %if
, v.v. là các câu lệnh cú pháp không trả lại bất kỳ thứ gì (tự mình); vì vậy bạn có thể có nhiều thứ như bạn muốn.
Bạn cũng có để có một tuyên bố đặt giá trị trong luồng xử lý: nếu không bạn sẽ không nhận được bất kỳ thứ gì ngoài macro của mình.
Đây là một phiên bản rút gọn vĩ mô của Jack vào cuối trang 3, đơn giản để loại bỏ các nlobsf
rằng anh ta đang thấy là sai:
%macro check;
%let dsid = %sysfunc(open(sashelp.class, IS));
%if &DSID = 0 %then
%put %sysfunc(sysmsg());
%let nlobs = %sysfunc(attrn(&dsid, NLOBS));
%put &nlobs;
%let rc = %sysfunc(close(&dsid));
%mend;
Đó vĩ mô là không macro chức năng phong cách. Nó không trả lại bất kỳ thứ gì cho luồng xử lý! Nó rất hữu ích cho việc xem nhật ký, nhưng không hữu ích cho bạn một giá trị mà bạn có thể lập trình. Tuy nhiên, đó là một khởi đầu tốt cho một macro kiểu hàm, bởi vì những gì bạn thực sự muốn là &nlobs
, phải không?
%macro check;
%let dsid = %sysfunc(open(sashelp.class, IS));
%if &DSID = 0 %then
%put %sysfunc(sysmsg());
%let nlobs = %sysfunc(attrn(&dsid, NLOBS));
&nlobs
%let rc = %sysfunc(close(&dsid));
%mend;
Bây giờ đây là một macro chức năng phong cách: nó có một tuyên bố đó không phải là một tuyên bố cú pháp vĩ mô, &nlobs.
trên một dòng đơn giản tất cả của chính nó.
Nó thực sự nhiều hơn bạn cần bởi một tuyên bố; nhớ cách tôi nói rằng %sysfunc
trả về một giá trị cho luồng xử lý?Bạn có thể loại bỏ các %let
phần của tuyên bố rằng, để lại cho bạn
%sysfunc(attrn(&dsid, NLOBS))
Và sau đó giá trị sẽ được đặt ngay trong luồng xử lý riêng của mình - cho phép bạn sử dụng nó trực tiếp. Tất nhiên, nó không phải là dễ dàng để gỡ lỗi nếu có điều gì sai, nhưng tôi chắc chắn bạn có thể làm việc xung quanh đó nếu bạn cần. Cũng lưu ý sự vắng mặt của dấu chấm phẩy ở cuối câu lệnh - điều này là do dấu chấm phẩy không bắt buộc đối với các hàm macro để thực thi và chúng tôi không muốn trả về bất kỳ dấu chấm phẩy không liên quan nào.
Hãy cũng được cư xử và thêm một vài %local
s để có được điều này tốt đẹp và an toàn, và làm cho tên của bộ dữ liệu một tham số, bởi vì bản chất abhors một vĩ mô không có tham số:
%macro check(dsetname=);
%local dsid nlobs rc;
%let dsid = %sysfunc(open(&dsetname., IS));
%if &DSID = 0 %then
%put %sysfunc(sysmsg());
%let nlobs = %sysfunc(attrn(&dsid, NLOBS));
&nlobs
%let rc = %sysfunc(close(&dsid));
%mend;
%let classobs= %check(dsetname=sashelp.class);
%put &=classobs;
Ở đó bạn có nó : macro kiểu hàm sử dụng hàm nlobs
để tìm hiểu số lượng hàng trong bất kỳ tập dữ liệu cụ thể nào.
Tôi thích chức năng macro của Jack Hamilton để đếm số lần truy cập: http://www2.sas.com/proceedings/sugi26/p095-26.pdf – Quentin
Cảm ơn bạn đã liên kết. Mối quan tâm chính của tôi ở đây là làm thế nào để trả về một giá trị từ một macro. Tôi cũng thực sự muốn biết làm thế nào để làm cho "vào" biến (trong một sql proc) địa phương và không toàn cầu. Đây là hai điều tôi cần phải làm liên tục với các macro khác. – bambi
Bạn có chắc bạn cần biết bao nhiêu? Thông thường tôi chỉ muốn biết không ai hay không. Bạn sẽ làm gì với NOBS? –