Showing posts from 2007

SAS and LINQ - Part 1

So, I am just getting my feet wet with LINQ, the new integrated query language within .NET. There are loads of articles on LINQ elsewhere. What I want to do is to illustrate LINQ with SAS and this is my starting point.

Look at the following code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication2
public partial class Form1 : Form
public Form1()

private void btnGetData_Click(object sender, EventArgs e)
XElement table =XElement.Parse(
&ltName&gt Alfred &lt/Name&gt
&ltSex&gt M &lt/Sex&gt
&ltAge&gt 14 &lt/Age&gt


Good systems practice is to have demarcations between systems layers. This involves separation of the following layers (at a minimum):

Business logic
Data access

SAS programmers though tend to muddle all together:

libname indata ...; <-- Data Access
data mydata...; <--- Business Logic
ods html; proc report...; <--- Application Layer / UI

A better way to handle is to treat all layers as standalone and get them out of each other's space. The easiest way for a SAS coder to accomplish this is to use macro libraries to get it all started:

%GetFinanceData() ;
%DetermineProfit() ;
%OutputResults() ;

However, even this is constrained since everything is called together and a single program controls what happens top-to-bottom. Rather than doing the final piece as a part of the batch job, consider doing it on demand and perhaps through other means:

%GetFinanceData() ;
%DetermineProfit() ;

...wait until use requests information....

Get information on demand and make the presenta…

C# and DBF files

I have a client that asked me to read DBF files generated by their SAS application. Well, this posting is to explain to someone what i have learned in reading DBF files using C#. The main thing I learned was no spaces in the file path.

Here is the code that worked for me:

string connectionString = "Driver={Microsoft dBase Driver (*.dbf)};SourceType=DBF;SourceDB=C:\projects\Client\Data\WeeklyAvailableComparison;Exclusive=No; Collate=Machine;NULL=NO;DELETED=NO;BACKGROUNDFETCH=NO;";
string selectCommand = @"SELECT * FROM C:\projects\Client\Data\WeeklyAvailableComparison\ac_141.dbf";
DataTable dt = new DataTable();

OdbcConnection oConn = new OdbcConnection();
oConn.ConnectionString = connectionString;
OdbcCommand oCmd = oConn.CreateCommand();
oCmd.CommandText = selectCommand;


I tried doing a 8.3 conversion and it wouldn't wor…

Using SAS\Share and C#

Ok, I went a little crazy getting SAS\Share working with OleDb from C#. Since I got it figured out, someone else may have the same issue.

Here is how I did it. First of all, make sure you client machine and the SAS\Share server can talk to each other. I tested from a development machine that has SAS on it. Otherwise, a test app will have to be built.

In the web.config, I have these settings:

<add key=\"ShareConnectionString\" value=\"Provider=sas.ShareProvider.1;Data Source=share1;Location=;User ID=Administrator;Password=<span color=\">*****</span>;Mode=ReadShare Deny None\"/>
<add key=\"SasLibrary\" value=\"demo\">
<add key=\"SasDataSet\" value=\"user_info\">

Here is the C# code:

private static DataTable LoadSasDataSet()
string library = ConfigurationManager.AppSettings["SasLibrary"] ;
string dataset = ConfigurationManager.AppSettings["SasDataSet"] ;
string conn …

SAS, ASP.NET AJAX, Web Services

In preparation for SAS Global Forum 2007, I have posted 2 videos showing 1) How to set up a web service to read a SAS dataset, 2) How to consume that service in an ASP.NET AJAX page. Simple demos but they should help get people started:

There are several videos demonstrating the concepts involved. They can be found here:

Look under the video tab.

Code generation, macros, et al

As a SAS programmer evolves, they start to think:

"Hey, I can create SAS code using data step or macros!"

So they start to go down the happy path of code generation:

data _null_;
file "myplace";
put "data test ;
/ " set a; "
/ " x = wereHavingFunFunc(y)" ;
... etc.

...and pretty soon they have elaborate SAS code in macros, etc. that does nothing but generate code. If you don't use my utility SasEncase to help you do this, you are doing a LOT of extra work but that is another story.

Well, I think the next level of thought (at least for me) was:

"Hey! Why can't I just use ANY programming language to generate SAS code"

Now, think about that for a sec. ANY programming language can be used to generate SAS code.

The reason why SAS is an entry into this area is because that is what all of us know and love. But, don't confine yourself to just using SAS for code generation. Instead, pick other languages as …