BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Bahr
Calcite | Level 5

Hi,

 

I sometimes work on my desktop and sometimes on my laptop.  When I work on my laptop, I access files on the desk via the network, both the data and the jobs.

 

So when I am on the desktop I have this, accessing the data which is on desktop:

 

libname data1 "d:\data1";

libname data2 "d:\data2";

libname data3 "d:\data3";

libname data4 "d:\data4";

etc.

 

When I am on the laptop, I access the data on the desktop using the name for the desktop on the network:

 

libname data1 "\\SmithDT\data1";

libname data2 "\\SmithDT\data2";

libname data3 "\\SmithDT\data3";

libname data4 "\\SmithDT\data4";

 

What that means is every time I switch back and forth between the desktop and the laptop, I have to change or comment out the libname that is not correct.  I would like be able to set it up where I only make one change, the drive name (depending on whether I am on the desktop or laptop), and have it concatenate with the subdirectory.

 

I have tried using %Let Drive="d:\" or %Let Drive="\\SmithDT" , and %Let SubDir="data", but then it does not seem possible to concatenate &Drive and &Subdir, because the ' becomes part of the value of the macro variable.  

 

Thanks for any ideas, I'm using SAS 9.4

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

In macro code quotes are just like any other character (although strings inside of single quotes are not processed by the macro processor).  So you should NOT include the quotes in the value of your macro variable.

%let top=D:;
libname data1 "&top\data1";
libname data2 "&top\data2";
libname data3 "&top\data3";

 

In regular SAS code you need quotes around strings so that the compiler knows you mean a sting literal and not a name or keyword. But  the macro processor just looks for & and % triggers to know when it needs to take action so there is no need to add the quotes.  Just add quotes into the code that you are using the macro variables (or macro code) to generate where SAS itself needs the quotes. Like the quotes around the path in the LIBNAME statement above.

View solution in original post

12 REPLIES 12
Reeza
Super User

Don't put quotes around the macro variable and that's all. You can also just add some conditional logic for the program to detect where you're running from and then conditionally run one set of the code.

%let drive =D:\;

libname data1 = "&drive.\data1";



You can also use the LIBNAME function in a data step which allows you to dynamically build your string.

In general, a lot of options to solve this issue.

SASKiwi
PROC Star

Using a UNC path should work on both computers -  libname data1 "\\SmithDT\data1"; -  then you wouldn't need to change any code.

Tom
Super User Tom
Super User

In macro code quotes are just like any other character (although strings inside of single quotes are not processed by the macro processor).  So you should NOT include the quotes in the value of your macro variable.

%let top=D:;
libname data1 "&top\data1";
libname data2 "&top\data2";
libname data3 "&top\data3";

 

In regular SAS code you need quotes around strings so that the compiler knows you mean a sting literal and not a name or keyword. But  the macro processor just looks for & and % triggers to know when it needs to take action so there is no need to add the quotes.  Just add quotes into the code that you are using the macro variables (or macro code) to generate where SAS itself needs the quotes. Like the quotes around the path in the LIBNAME statement above.

Bahr
Calcite | Level 5
Wow, that was simple but exactly what I wanted, thanks very much.
Bahr
Calcite | Level 5

thanks, I hadn't realized that yet.

ScottBass
Rhodochrosite | Level 12

You've had replies about how macro variables are just literal text that get resolved during program compilation.

 

You've also had the suggestion to use the UNC path for both scenarios.

 

If that doesn't work for some reason, you can try this approach:

 

%macro allocate_libraries;
   %let computername=%sysget(COMPUTERNAME);
   %if (&computername eq FOO) %then %do;
      libname data1 "d:\data1";
      libname data2 "d:\data2";
      libname data3 "d:\data3";
      libname data4 "d:\data4";
   %end;
   %else
   %if (&computername eq BAR) %then %do;
      libname data1 "\\SmithDT\data1";
      libname data2 "\\SmithDT\data2";
      libname data3 "\\SmithDT\data3";
      libname data4 "\\SmithDT\data4";
   %end;
%mend;
%allocate_libraries

Substitute FOO and BAR with your desktop and laptop computer names.

 

This assumes that you're running Base SAS (i.e. DMS) on both machines.  If you're running EG, then COMPUTERNAME would be the name of the server.


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
Bahr
Calcite | Level 5
Thanks, actually I have three different ways to do it, all of which
are very interesting for other reasons as well. I didn't know about
the =%sysget(COMPUTERNAME) thing, which is interesting for several
reasons (it can create an indicator in the Log which computer was
being used). Thanks again.
ballardw
Super User

I don't want to add confusion but you may want to be careful using the phrase "concatenated libname" as in your subject line as that sounds like you want to concatenate libraries, i.e. reference multiple storage areas with a single library name.

 

The libname does that by something such as

 

libname all ( "d:\data1"  "d:\data2"  "d:\data3"  "d:\data4");

 

Not a good idea if you have multiple data sets with the same name but can be useful to reference data sets stored in separate locations without having to keep track of which set is in which library.

Bahr
Calcite | Level 5
Thanks, you're right, I didn't mean to concatenate the libname but
concatenate the, well, I don't know what it could be called, the
actual library name, like you do a character variable.

but actually, that may do what I wanted:

libname test ("\\Desktop\data" "d:\data\");

If that were on the laptop with access to the network, then it would
go to the Desktop via the network, but if it did not have access to
the network, then it would go to the second choice.


>Hi Bahr,
>
>ballardw (Super User) posted a new reply in
>SAS
>Programming on 06-14-2019 04:19 PM :
>
>
>----------
>
>
>Re:
>Creating a concatenated Libname using a macro (%let)
>
>
>
>I don't want to add confusion but you may want to be careful using
>the phrase "concatenated libname" as in your subject line as that
>sounds like you want to concatenate libraries, i.e. reference
>multiple storage areas with a single library name.
>

>
>The libname does that by something such as
>

>
>libname all (Â "d:\data1"Â Â "d:\data2" Â "d:\data3" Â "d:\data4");
>

>
>Not a good idea if you have multiple data sets with the same name
>but can be useful to reference data sets stored in separate
>locations without having to keep track of which set is in which library.
>
>Reply
>|
>Accept
>as Solution |
>Like
>this message
>
>
>
>----------
>SAS Support Communities sent this message to
>bahr.weiss@gmail.com.
>You are receiving this email because a new message matches your
>subscription to a topic.
>To control which emails we send you please go to,
>manage
>your subscription
>
>
Patrick
Opal | Level 21

@Bahr wrote:
...



but actually, that may do what I wanted:

libname test ("\\Desktop\data" "d:\data\");

If that were on the laptop with access to the network, then it would
go to the Desktop via the network, but if it did not have access to
the network, then it would go to the second choice.


@Bahr 

That's not going to work. If one of the paths is invalid then the libname will throw an error. 

Bahr
Calcite | Level 5
Actually, on my version of SAS it generates a warning but not an
error, and writes to the first sub-directory that is valid.

810 libname test ('d:\data\Recap III' 'd:\data\recap');
WARNING: One or more libraries specified in the concatenated library
TEST do not exist. These libraries were removed from the concatenation.
NOTE: Libref TEST was successfully assigned as follows:
Levels: 1
Engine(1): V9
Physical Name(1): d:\data\recap
811 data test.temp;x=1;run;

NOTE: The data set TEST.TEMP has 1 observations and 1 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds


812 proc contents data=test.temp;run;

NOTE: PROCEDURE CONTENTS used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds


Bahr
Calcite | Level 5

Thanks everyone for all of the very interesting solutions.  They were useful not only for this particular issue but also for better understanding of the libname command and the %let macro.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 12 replies
  • 7920 views
  • 5 likes
  • 7 in conversation