Viewing SAS macro variables in SAS Enterprise Guide

56

The SAS macro variable viewer is a tool that's part of SAS Enterprise Guide. You can use it to view the current values for all SAS macro variables that are defined within your SAS session. You can also evaluate "immediate" macro expressions in a convenient quick view window. If you develop or run SAS macro programs, this task can be a valuable debugging and learning tool. If you want to learn how to use the tool and see it in action, watch my SAS Tip tutorial on YouTube.

SAS Macro Variable viewer: features and function

This tool offers the following main features:

Always-visible window: Once you open the task from the Tools menu, you can leave it open for your entire SAS Enterprise Guide session. The window uses a "modeless" display, so you can still interact with other SAS Enterprise Guide features while the window is visible. This makes it easy to switch between SAS programs and other SAS Enterprise Guide windows and the macro variable viewer to see results.

Select active SAS server: If your SAS environment contains multiple SAS workspace connections, you can switch among the different servers to see macro values on multiple systems.

One-click refresh: Refresh the list of macro variables by clicking on the Refresh button in the toolbar.

View by scope or as a straight list: View the macro variables in their scope categories (for example, Global and Automatic) or as a straight list, sorted by variable name or current value. Click on the column headers to sort the list.

Filter results: Type a string of characters in the "Filter results" field, and the list of macro variable results will be instantly filtered to those that contain the sequence that you type. The filtered results will match on variable names as well as values, and the search is case-insensitive. This is a convenient way to narrow the list to just a few variables that you're interested in. To clear the filter, click on the X button next to the "Filter results" field, or "blank out" the text field.

Set window transparency: You can make the window appear "see-through" so that it doesn't completely obscure your other windows as you work with it.

Copy macro variables as %LET statements: Select one or more macro variables within the window, right-click and select Copy assignments. This generates a series of %LET statements -- one for each macro variable/value pair -- which you can then paste into a SAS program.

Macro expression "quick view": Have you ever wanted to test out a macro expression before using it in a longer program? This window allows you to get immediate feedback on a macro expression, whether a simple macro reference or a more complex expression with nested functions. If the expression generates a SAS warning or error, the feedback window shows that as well. Note: the expression can be any macro expression that is valid for the right-side of a macro variable assignment (%let statement).

Source code available on GitHub

I created this tool years ago as a custom task, but it's been included with SAS Enterprise Guide as an "official" tool for several releases. I built the task using the custom task APIs and Microsoft .NET. If you're interested, I've shared a version of the source code behind this task on GitHub.

Share

About Author

Chris Hemedinger

Director, SAS User Engagement

+Chris Hemedinger is the Director of SAS User Engagement, which includes our SAS Communities and SAS User Groups. Since 1993, Chris has worked for SAS as an author, a software developer, an R&D manager and a consultant. Inexplicably, Chris is still coasting on the limited fame he earned as an author of SAS For Dummies

56 Comments

  1. This would be so convenient when trying to troubleshoot what your macro was doing versus what you think it was doing. When you pick up someone else's code this is especially useful.

    I'm anxious to try it.

    Thanks for the tip!

  2. Hi Chris,

    This is great for debugging purposes and very useful, thank you! I have some comments and suggestions:
    - Variables defined as %local in a Macro are not shown, but this is probably expected behavior because you cannot evaluate them outside the macro?
    - A search text field would be a nice addition to limit the list of variables. so for instance, when the user types 'TMP' all variables are shown that have 'TMP' in the name.
    - 'Toggle groups' is not remenbered when you click 'Refresh', it always switches back to the group view.

    Rudolf.

    • Chris Hemedinger
      Chris Hemedinger on

      Rudolf, these are great suggestions!

      Yes, you're correct that %local variables won't show, because they are, by definition, out of scope with the way this tool operates. I had a plan for the "search" field, as well as to fix the toggle groups setting. I decided to leave those options for "version 2". It's great to hear you suggest them though, as that validates the ideas I've yet to implement...

    • Chris Hemedinger
      Chris Hemedinger on

      Rudolf, I've updated the task with your suggested features. Grab a new copy and tell me what you think!

  3. Hi Chris,

    Thanks a lot, this nice feature should now be part of EG. Very helpful and well-designed. I like very much the inspector display in a "floating" window : a real value add-on imho. Will definitively replace the tedious "%put _all_" line I'm used to type.

    Ronan

  4. Here are my suggestions:
    - fix the following bug: click 'toggle groups', sort the view by clicking on column header 'Macro variable', click 'toggle groups' again and the content of the view completely disappears.
    - add another column with the variable scope. When the variables are not grouped by scope, you don't know the actual scope.
    - add an option to hide automatic global variables which are used by EG like _client*.
    - you could also add some information which Macros are already compiled in your session. You can get that information from the SQL Dictionary Tables:
    proc sql;
    create table info as
    select *
    from dictionary.catalogs
    where objtype = "MACRO";
    quit;

    - the same addin would be nice for SAS Options. It would be nice if i could see the SAS options effecting my current session without writing some SAS Code with proc options or querying the Dictionary/SASHELP Views.

    - last but not least i would really like to see the .net source code of this addin. Is there any chance to contribute to some nice addins like this? If the source was public i think some people like me would be willing to fix some bugs and help to enhance the addin.

    Andreas

  5. Nice job Chris, extremely useful, especially with the ability to evaluate macro expressions on the fly. I like the suggestions others have made too. In my opinion EG is fast becoming the tool of choice for the SAS programmer....

  6. Chris
    this is great!
    It replaces the first thing I would set up in a DM environment - a customized FSview of a customised sashelp.vmacro!
    And it provides the macro expression evaluator!

  7. Hey Chris! I just happened to be teaching our macro course this week to a bunch of EG users... How timely! Can't wait to show them this task.

  8. Thank you Chris for this handy tool!
    One question, which permissions are required by the tool? It works flawlessly when connected to our dev-system but will only show automatic variables when connected to the prod-system?

    br Thomas

    • Chris Hemedinger
      Chris Hemedinger on

      Thomas, the tool queries the SASHELP.VMACRO view to retrieve the current values for all macro variables. No special permissions are necessary. However, if you invoke the tool as the first task before doing any other operation on the SAS session, you should know that no EG-specific autoexec or initialization code has been run yet. If you submit a small program and then refresh the macro viewer, you'll see some additional values.

      If it still seems to have problems, let me know. A report of what's in SASHELP.VMACRO would help to diagnose, in case the task is somehow misinterpreting the results of the query.

      • Kiran Kumar on

        Hi Chris,

        Thanks you so much for useful information. I want to create a new global macro variables and have it store it as onetime compiled macro. When I look at the sashelp.vmacros I could see existing global macro variables but not sure how add the new global macro variable to it. Please advise. Thanks

  9. Hi Chris, I'm just teaching PRG1 in the EG environment and the customers have to submit lots of code with predefined macro variables. We have already found a mistake... Thank you, this is really helpful and we all enjoy this supporting tool!

  10. Pingback: A SAS options viewer for SAS Enterprise Guide - The SAS Dummy

  11. Pingback: Traffic report: the most visited posts of 2011 - The SAS Dummy

  12. Pingback: Implement BY processing for your entire SAS program - The SAS Dummy

  13. Pingback: Improving on a SAS programming pattern - The SAS Dummy

  14. Venkata R Potluri on

    Hi Chris,
    Taking SAS EG Custom tasks as example. I have build a SAS EG Custom Task Addin.
    Which is working fine. I'm sure SAS custom built Tasks are going to change the way you can work with SAS EG. I just want to expand its functionality. Can you please tell me how to messages to SAS EG Task Status.

    • Chris Hemedinger
      Chris Hemedinger on

      Venkata,

      I assume that you mean that you want to update the task status window that you see when you select View->Task Status.

      There are two ways to update that content. When running a SAS program, you can use the SYSECHO statement to annotate your SAS code. As the statements execute, the comments you add to SYSECHO will appear in the status window. This approach is discussed more in Tracking progress in SAS programs in SAS Enterprise Guide.

      Within a custom task that "does its own work", without running a SAS program, there is another way to update the status window. The task should implement ISASTaskExecution, which allows EG to "delegate" the ability to "run yourself" to the task. The custom tasks API page has an example that you can download: Custom Execution and Results.

      But while this example shows how a task can run its own custom operation, it does not show how to update the status window. To update the status window, you must implement ISASTaskExecution2 (instead of ISASTaskExecution) and raise an event to the application.

      In your task class, add this handler:

      private event TaskExecutionStatusChangedHandler _statusChanged = null;
      public event TaskExecutionStatusChangedHandler StatusChanged
      {
        add { _statusChanged += value; }
        remove { _statusChanged -= value; }
      }
      

      Then in your task's Run method, periodically update the status during the task's operation, like this:

      // raise the event for the application status window
      if (_statusChanged != null)
          _statusChanged(this, new TaskExecutionStatusEventArgs("Accessing records from database"));
      

      • Venkata R Potluri on

        Thank you very much for your response.
        I'm not a C sharp Programmer I'm a Visual basic person.
        Still I hope I can understand and do what I want to do.
        Basically I build a PCA tool which takes user inputs to run
        Post Camapaign Analysi and output results to Excel Templates ,
        for Market Analyics team.

      • Venkata R Potluri on

        Hi Chris,
        Thank you for the response.
        May be until your book on Developing Custom Tasks for SAS EG is in the market
        I may ask you few questions through this blog. Once again thank you very much you are very helpful.
        When I'm submitting SAS Code I'm using model.SubmitSASProgramAndWait to make my application work right. If use model.SubmitSASProgram I'm not achieving the result as I want. Because of this the screen looks frozen until SAS program is executed fully and user gets confused , is there any way that I can show Application.UseWaitCursor = False while my sas program is executing and still I can use model.SubmitSASProgramAndWait . You help in this regard is highly appreciated.

        Ramana

        • Chris Hemedinger
          Chris Hemedinger on

          Ramana,
          If you want the UI to remain responsive (not frozen), you must use the asynchronous approach: SubmitSasProgram(). When using the async approach, you must take care to redirect any UI update operations back to the main UI thread.

          Here is a snippet of an example:

           private void btnRunAsync_Click(object sender, EventArgs e)
           {
            // use your SAS program here
            string sasProgram = "proc options; run;"
            SasSubmitter submitter = new SasSubmitter(
              Consumer.AssignedServer
              );
            submitter.SubmitSasProgramComplete += 
                new SubmitCompleteHandler(
                    submitter_SubmitSasProgramComplete);
            submitter.SubmitSasProgram(
                sasProgram,
                "Running custom program");
           }
          
           /// 
           /// This event might be raised on a non-UI, non-STA thread.
           /// 
           void submitter_SubmitSasProgramComplete(object sender, 
             SubmitCompleteEventArgs args)
           {
               if (args.Success)
               {
                   // marshal back to the UI thread
                   this.BeginInvoke(new MethodInvoker(
                     delegate() { YourMethodToUpdateUI(); }
                     ));
               }
               else
               {
                   // marshal back to the UI thread
                   this.BeginInvoke(new MethodInvoker(
                    delegate() { ShowLog(args.Log); }
                    ));
               }
           }
          
          private void ShowLog(string log)
          {
              SAS.Tasks.Toolkit.Controls.SASLogViewDialog dlg =
                  new SASLogViewDialog("Errors", "", log);
              dlg.ShowDialog(this);
          }
          
          

          • Venkata R Potluri on

            Hi Chris,
            Thank you for all the help. Can you please tell me if there is way to assign the value of a macro variable to vb variable straight away with out much coding and work arounds.I mean some thing like this
            dim VBVar as string = .....some statement(&SASMacroVar) ........
            With regards
            Ramana

          • Venkata R Potluri on

            Hi Chris,
            How can I run task in SAS EG repeatedly?

            With regards

            Ramana

  15. Christian Kjeldsen on

    Hi Chris

    Thanks a lot for all your work in educating the rest of us. I have been going through some of the examples on the official SAS support site, however, I find it quite difficult to obtain an overview of what the SAS.Tasks.Toolkit contains and how to use it. The examples shows some ways, but I am sure it may do a lot more than what these examples show. Unfortunately I haven't been able to find a description of the SAS.Tasks.Toolkit, so it is quite a lot of trial-and-error (and especially error) when starting developing my own custom tasks. So do you know a good reference for SAS.Tasks.Toolkit? Maybe that will be a part of your book, however, until that is out on the market, I hope you know where I can get more information.

    Just one of the problem I have, is that I would like to develop an add-in, which will appear in its own category in Tools->Add-In (Like you have "Programmer Utilities"). However, when I set this.TaskCategory in the InitializeComponent method to something I would like, then it still won't appear in EG. I have tried to set [SASTaskCategory("...")] annotation as well, but I still can't make it create the level. Maybe you can help on this particular detail.

    Again thanks for all your work. It is highly appreciated!

    Christian Kjeldsen

    • Chris Hemedinger
      Chris Hemedinger on

      Christian,

      Here is a high-level overview of what the task toolkit does for you:
      - Makes it easy to implement the custom task interfaces. The SAS.Task.Toolkit.SasTask class implements most of what you need from ISASTask, ISASTaskDescription, and ISASTaskAddIn. Hundreds of lines of code can be reduced to just a handful.
      - Provides easy access to SAS-related objects. The SAS.Task.Toolkit.SasServer class provides a useful model of your SAS workspace, and several classes in the SAS.Task.Toolkit.Data namespace allow you to access SAS data, libraries, columns, and even SAS catalogs.
      - Provides access to SAS services, such as submitting programs. Classes and methods within the toolkit make it easy to submit SAS programs, synchronously or asynchronously, and collect the SAS log and the results from those programs.
      - Provides a library of useful user interface controls. The toolkit includes common controls that tasks can use to navigate data sources, display SAS programs, and more. (These controls are implemented using Windows Forms in SAS Enterprise Guide 4.2, 4.3., and 5.1).

      Yes, there is more information in my forthcoming book, which is now in the tech review stage. For your particular issue, what you want to do is set the TaskCategory property in the Designer view of the task class (the SasTask-derived class that implements your main task). Note that the menu grouping *does not* appear unless at least two tasks share the same category.

      • Christian Kjeldsen on

        Hi Chris

        Thanks for the answer. I guess it is mainly an overview of how and when to use the methods of the SAS.Tasks.Toolkit I need. However, I know it is dificult to do that, without a complete book. But I am sure, that when your book hits the market, it will come in handy.

        It was the feature of two tasks having to share the same category before the menu grouping appears that casued my confusion. Thanks for making that clear.

        Christian Kjeldsen

  16. Ramana Potluri on

    Hi Chris,
    Thank you for all the help. Can you please tell me if there is way to assign the value of a macro variable to vb variable straight away with out much coding and work arounds.I mean some thing like this
    dim VBVar as string = .....some statement(&SASMacroVar) ........
    With regards
    Ramana

    • Chris Hemedinger
      Chris Hemedinger on

      Ramana,

      Yes, you can do this with very little code in Visual Basic by using the SAS.Tasks.Toolkit.SasServer class:

      Dim value As String
      Dim server As SasServer
      server = New SasServer("SASApp")
      value = server.GetSasMacroValue("MYMACROVARIABLE")
      

      Note that you supply the macro variable name, but don't reference it with the ampersand.

      • Venkata R Potluri on

        Hi Chris,
        Thank you very much.
        I guess this is possible only for global variables?
        I'm just waiting for your book to come out.Can you please
        when it is comming out?
        With regards
        Ramana

        Ramana

        • Chris Hemedinger
          Chris Hemedinger on

          Ramana,
          Yes, this approach works only for GLOBAL or AUTOMATIC variables. LOCAL macro variables are scoped only within the actual macro processing, and your custom task wouldn't be able to inject any processing/queries while that's happening.

          The book is just finished with tech review (thanks to my team of reviewers), and I'm working on incorporating the feedback and finalizing content. I hope that it will be published by the end of year. In the meantime, I'm willing to help you and others with questions here.

          • Venkata R Potluri on

            Hi Chris,
            Thank you for all your help.
            Every time I open my SAS addon that I have developed is looking for some data avaialable to open. Is it possible to by pass this or is this a default behaviour for SAS addons.

            With regards

            Ramana

          • Chris Hemedinger
            Chris Hemedinger on

            Yes, it's easy to change this.

            At the top of the task class (inherited from SasTask), you should see an attribute that indicates "InputRequired". In Visual Basic it looks like this:

            <InputRequired(InputResourceType.Data)>
            

            Change it to:
            <InputRequired(InputResourceType.None)>
            

  17. Michael Bogdan on

    Hi Chris,
    I'm curious if the SAS Macro Variable Viewer works with Enterprise Guide 5.1. Could you let us know where to copy the DLL file? Thanks!

    • Chris Hemedinger
      Chris Hemedinger on

      Yes, it should work with 5.1 - in my tests it does. Copy the same DLL to %appdata%\SAS\EnterpriseGuide\5.1\Custom.

  18. Pingback: Special automatic macro variables available in SAS Enterprise Guide - The SAS Dummy

  19. Pingback: My favorite SAS tips and tools from 2012 - The SAS Dummy

  20. Pingback: 3 things you should know about custom tasks for SAS Enterprise Guide - The SAS Bookshelf

  21. I have an issue while refreshing the workbook using v5.1, which was not in v4.3
    The issue is when i call sas.Refresh in a macro, refresh process starts (there appears a popup having name of the process SAS currently working on), but macro continues is next code, it does not wait for the refresh process to complete.

    please help me with this issue.

    Regards,

  22. Pingback: Upcoming SAS Talks: Custom tasks for SAS Enterprise Guide - The SAS Dummy

  23. Pingback: Custom tasks for SAS Enterprise Guide: Q&A - The SAS Dummy

  24. Pingback: An FTP-style task in SAS Enterprise Guide: user-driven fixes - The SAS Dummy

  25. Hi Chris,
    It looks great to see all variables at one place. Is there any variable for user's password as well? We want to pass user'id and password in libname statement as &sysuserid and &sysuserpass. Due to security reason, we don't want to pass clear or encoded password in the code.
    Thanks!
    Piyush

  26. Pingback: New SAS programming features in SAS Enterprise Guide 7.1 - The SAS Dummy

  27. Pingback: 11 super-useful custom tasks for SAS Enterprise Guide - The SAS Dummy

  28. Mekides Bekele on

    Thank you very much. I would like to use SAS EG to write Macro codes and if you have more things please send me. appreciate it

Back to Top