1
votes

I'm tired of manually navigating to the current working folder and would like to create a hotkey in SAS to get me there. I have designed a command to open the current folder from within SAS. However, I cannot get it to execute via a hotkey.

I have created (stolen) the macro:

%macro GetPwd();
  %qsubstr(
      %sysget(SAS_EXECFILEPATH)
    , 1
    , %length(%sysget(SAS_EXECFILEPATH))-%length(%sysget(SAS_EXECFILENAME))
  )
%mend;

I have saved the above as GetPwd.sas in my autocall library.

In interactive mode, I can then use the following to open Windows Explorer to the current SAS working folder:

/*The Call:*/
%sysexec(start explorer.exe "%GetPwd()" && exit);

The problem arises when I place the above call in the KEYS menu.

enter image description here

When I issue the call via the hotkey (SHF F9), Windows Explorer opens to "Computer" and I get the following error in SAS:

WARNING: Argument 2 to macro function %QSUBSTR is out of range.
WARNING: Argument 3 to macro function %QSUBSTR is out of range.

Why does this error occur when the call is issued from a hotkey and not occur when submitted via the editor?


I have had success with the similar task of opening the SAS Temporary folder location using:

%sysexec(start explorer.exe "%sysfunc(pathname(work))" && exit);

See F9 in the KEYS menu image above.

2
I don't have access to SAS right now so I can't test it, but I'd try putting the %sysexec call directly in the macro routine and assigning it to the shortcut, c.g. submit '%OpenPwd;'Dominic Comtois

2 Answers

1
votes

As user2877959 points out in comments, SAS_EXECFILEPATH and SAS_EXECFILENAME are not available except if you're in an already saved program - so they're not available, they don't have a value. Notably, in the KEYS environment, they're never available (since those aren't stored in a file!). You can see this by running your code in a new editor window that hasn't been saved yet.

You can use a keyboard macro to accomplish what you want, more or less; assign that same text to a keyboard macro, and it will then put the code to call your program in the current editor window, which you can then execute and optionally delete. (You could even embed it in a /* */ block so it doesn't have to be deleted).

Alternatively, you could have your programs always change the current working directory to their own directory at the start of the program (you submit a cd command with the same path), which then will allow you to open the explorer and have it start in the right place; or (depending on how you start SAS) you could set it up that SAS is started with the right directory to start with (in the shortcut). That's only really useful if you have only a few places it needs to start in.

1
votes

As indicated by @user2877959, it appears that a direct solution is not possible. Here I describe, what I consider to be, the second best solution. It requires a trick which I call an "abbreviation macro," which combines the power of keyboard macros and SAS Abbreviations. This assumes the Enhanced Editor is being used.

  1. Add an abbreviation by going to Tools > Add Abbreviation...
  2. In the "Abbreviation" field put \pwd. For "Text to insert for abbreviation", enter the call %sysexec(start explorer.exe "%GetPwd()" && exit);

This is where the trick appears.

  1. Navigate to Tools > Keyboard Macros > Macros.... Notice that \pwd now appears in the list. This means that not only can \pwd act as an abbreviation, i.e. a shorthand for a code snippet, it can also act as a trigger for a sequence of keyboard macro commands.
  2. Select the entry for \pwd and select "Edit". From the available commands, assign the following to "Keyboard macro contents:" and press "OK".

Move cursor to end of line 
Insert carriage return 
Insert the string "%sysexec(start explorer..." 
Extend selection to beginning of line

Now, when the \pwd abbreviation is used, the call is placed on the next line and highlighted automatically. The abbreviation may be issued anywhere, even in the middle of a line of code, and will not disrupt what has already been written. To remove the line, create a keyboard macro for "Delete line". This will remove the line which created by \pwd and return the source code to its original state.