Object-oriented access to SAS data in a custom task

Most custom tasks need to access SAS data in some way. Since custom tasks are built using Microsoft .NET, and the .NET Framework is object-oriented, it would be convenient if we had an object-oriented method for navigating SAS data sources.

That was the thinking behind the "SasData"-namespace classes within the SAS Tasks Toolkit. The SAS Tasks Toolkit is a library of .NET classes (included in SAS.Tasks.Toolit.dll) that simplify the implementation of custom tasks by handling most of the "plumbing" for you, so that you can concentrate on the purpose and content of your task. (The SAS Tasks Toolkit is discussed in greater detail in my forthcoming book, Creating Custom Tasks for SAS Enterprise Guide using Microsoft .NET.)

These classes in the toolkit can help with navigating and inspecting the properties of data-related objects in SAS:

SAS.Tasks.Toolkit.SasServer (object for SAS workspace)

SAS.Tasks.Toolkit.SasData.SasLibrary (object for SAS data library)

SAS.Tasks.Toolkit.SasData.SasData (object for SAS data set or view)

SAS.Tasks.Toolkit.SasData.SasColumn (object for a variable in a data set)

SAS.Tasks.Toolkit.Helpers.TaskDataHelpers (methods for retrieving data values)

I built a simple example so that you can see this in action. Here's a preview of the user interface:

You can get the source code for this example on my SasDataExample github repository. There is a ready-to-use DLL that you can "install" into your SAS Enterprise Guide 4.3 or 5.1 to see it in action. And if you want to dabble with the C# source, you can use Microsoft Visual C# Express or Visual Studio (2010 or 2012 editions).

(Note: you don't have to be a github user to try the example. You can download the ZIP archive with a single click.)

What's remarkable about this example is that it contains very little code. Aside from the "designer" code in the Windows form, there are really only about 100 lines of code in the "form" class (excepting comments and spaces).

As I described in a previous post, I'm using data binding to populate the UI controls with the content of the SAS data object.

For example, once you select a SAS server (using the drop-down list in the upper left corner), these few lines of code will populate the list of SAS libraries:

// use the SasServer.GetSasLibraries method
// to get a collection of defined SAS libraries
// on the active server
SasServer s = cmbServer.SelectedItem as SasServer;
IList<SasLibrary> libs = s.GetSasLibraries();
lbLibraries.Items.Clear();
lbLibraries.Items.AddRange(new List<SasLibrary>(libs).ToArray());

This example illustrates a cool function within the SAS.Tasks.Toolkit.Helpers.TaskDataHelpers namespace: GetDistinctValues. You supply it a data reference and the name of a column, and it returns a list of the distinct values within the data for that column. So it's like a SELECT DISTINCT operation, but it's got one additional cool feature: you can optionally supply a SAS format to apply.

So if you have a SAS date column with daily measures (for example) and you want a list of just the distinct year values in the data, you can simply apply the YEAR4. format in the GetDistinctValues function. The following screen image from the example task shows what kind of difference that can make:

If you have questions or thoughts about the example, its code, or the idea of placing such examples on github, please post back in the comments.