<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: [DOTNET] Execute a SAS File and retrieve results in Developers</title>
    <link>https://communities.sas.com/t5/Developers/DOTNET-Execute-a-SAS-File-and-retrieve-results/m-p/782536#M1336</link>
    <description>&lt;P&gt;Look at my libraries on GitHub (&lt;A href="https://github.com/savian-net" target="_blank"&gt;savian-net (ALAN CHURCHILL) (github.com)&lt;/A&gt;). They should help out. If anything needs more clarity, let me know. Also, Chris Hemendinger has written a lot about it so check his stuff out as well.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Download and install the SAS ODBC and OleDB packages. They should already be installed but just in case, check. You also need the Integration Technologies client.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Get a DataSet&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;        public static DataTable GetSasDataSet(string sasLibrary, string dataset)
        {
            OleDbConnection sas = null;
            DataTable dt = new DataTable(dataset);
            try
            {
                sas = new OleDbConnection(@"Provider=SAS.LocalProvider.1; Data Source=" + sasLibrary);
                sas.Open();
                OleDbCommand sasCommand = sas.CreateCommand();
                sasCommand.CommandType = CommandType.TableDirect;
                sasCommand.CommandText = dataset;
                OleDbDataReader sasRead = sasCommand.ExecuteReader();
                dt.Load(sasRead);
                sas.Close();
            }
            catch (Exception ex)
            {
                sas.Close();
                string errMessage = "Unable to get the SAS dataset. Library: " + sasLibrary + ", DataSet: " + dataset + ", " +
                    ex.TargetSite.Name;
                throw ex;
            }
            finally
            {
                sas.Close();
            }
            return dt;
        }&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;STRONG&gt;Execute SAS Code&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;public class SasRunObject
{
    public string SasLog {get;set;}
    public string SasCode {get;set;}
    public string SasList {get;set;}
}
    
internal SasRunObject SubmitSasCode(string reqId, string workarea, string sasCode)
{
    var sro = new SasRunObject();
    try
    {
        StepError = false;
        var timer = new Stopwatch();
        timer.Start();
        var ws = new Workspace();
        SetOptions(ws);
        var ls = ws.LanguageService;
        Log.Info($"Startup time for SAS: {timer.ElapsedMilliseconds} ms");
        timer.Reset();
        //Log.Info($"Submitting SAS code to workspace: {SasLanguageService.}");
        var htmlFile = Path.Combine(workarea, reqId + ".html");

        //Append special code at the top of the SAS to direct output
        sasCode = string.Join(Environment.NewLine, AddRadHeaderCode(reqId, htmlFile), sasCode, AddRadFooterCode());

        ls.Submit(sasCode);
        Log.Info($"Run time of SAS code: {timer.ElapsedMilliseconds} ms");
        timer.Stop();
        ls.StepError += SasLanguageService_StepError;
        ls.LineSeparator = "\r\n";
        sro.ProcessId = ws.GetSasProcessId();
        sro.SasCode = sasCode;
        sro.SasLog = ls.FlushLog(Common.AppConfig.SasConfig.LogCharsToAnalyze);
        sro.SasList = ls.FlushList(Common.AppConfig.SasConfig.ListCharsToAnalyze).Replace("\f", "");
        sro.HtmlOutputFile = htmlFile;
        CloseSasWorkspace(ws);
        return sro;
    }
    catch (Exception ex)
    {
        Log.Error("Error when submitting code", ex);
        return new SasRunObject();
    }
}

private void CloseSasWorkspace(Workspace ws)
{
    //var obWorkspaceManager = new SASWorkspaceManager.WorkspaceManager();
    //obWorkspaceManager.Workspaces.RemoveWorkspaceByUUID(SasWorkSpace.UniqueIdentifier);
    if (ws != null)
    {
        ws.LanguageService.Reset();
        ws.Close();
    }
    ws = null;
}

/// &amp;lt;summary&amp;gt;
/// Sets SAS options for processing
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="ws"&amp;gt;A SAS workspace to appl options to&amp;lt;/param&amp;gt;
private static void SetOptions(SAS.Workspace ws)
{
    Log.Info("Set the SAS system options");
    var opt = ws.Utilities.OptionService;
    var options = new Dictionary&amp;lt;string, string&amp;gt;();

    options.Add("MEMLIB", "4GB");
    options.Add("NOOVP", "");
    options.Add("MEMSIZE", "MAX");
    options.Add("MEMCACHE", "4");
    options.Add("MEMMAXSZ", "12G");

    var sasOpt = options.Select(p =&amp;gt; p.Key).ToArray();
    var sasVals = options.Select(p =&amp;gt; p.Value).ToArray();
    Array errIndices = new long[options.Count];
    Array errCodes = new string[options.Count];
    Array errMsgs = new string[options.Count];
    try
    {
        opt.SetOptions(sasOpt, sasVals, out errIndices, out errCodes, out errMsgs);
        foreach (var o in options)
        {
            Log.Info($"{o.Key,-15}:{o.Value}");
        }
    }
    catch (Exception ex)
    {
        Log.Error("Error when setting SAS options. Most likely, this is caused by doing an " +
                  "Embed Interop Type on the SAS interop references. Check properties and make " +
                  "sure Embed Interop Type is set to false.", ex);
        if (errMsgs != null)
        {
            foreach (var e in errMsgs)
            {
                Log.Error($"SAS error message when setting options: {e.ToString()}");
            }
        }
        else
        {
            Log.Error($"SAS error message array is empty.");
        }
    }
}

private string AddRadFooterCode()
{
    var sb = new StringBuilder();
    sb.AppendLine($"/*" + new string('=', 50) + "*");
    sb.AppendLine($" | CODE ADDED BY SAVIAN WEB SERVICES ");
    sb.AppendLine(" *" + new string('=', 50) + "*/");
    sb.AppendLine($"ods _all_ close;");
    sb.AppendLine($"*{new string('-', 50)} ;");
    return sb.ToString();
}

private string AddRadHeaderCode(string reqId, string htmlFile)
{
    var sb = new StringBuilder();
    sb.AppendLine($"/*" + new string('=', 50) + "*");
    sb.AppendLine($" | CODE ADDED BY SAVIAN WEB SERVICES ");
    sb.AppendLine(" *" + new string('=', 50) + "*/");
    sb.AppendLine($"options fullstimer;");
    sb.AppendLine();
    sb.AppendLine($"%LET SVCSID = {reqId};");
    sb.AppendLine($"%LET SVCSWORK = {Common.AppConfig.Directories["Requests"]};");
    sb.AppendLine();
    sb.AppendLine($"ods _all_ close;");
    sb.AppendLine($"ods html file='{htmlFile}';");
    sb.AppendLine();
    sb.AppendLine($"*{new string('-', 50)} ;");
    sb.AppendLine();
    return sb.ToString();
}

&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 26 Nov 2021 12:40:31 GMT</pubDate>
    <dc:creator>AlanC</dc:creator>
    <dc:date>2021-11-26T12:40:31Z</dc:date>
    <item>
      <title>[DOTNET] Execute a SAS File and retrieve results</title>
      <link>https://communities.sas.com/t5/Developers/DOTNET-Execute-a-SAS-File-and-retrieve-results/m-p/782485#M1335</link>
      <description>&lt;P&gt;Hello everybody,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Please, I need to make an integration from SAS into a Dotnet WebApplication where I need to exec a .sas file and then get the results into an object (prefereble a DataSet or DataTable) but I'm stuck at SAS IOM component where I can't find any methods to open this file.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Could somebody help me in how I could exec the .sas file and then how I can get the results, please?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you in advance.&lt;/P&gt;</description>
      <pubDate>Thu, 25 Nov 2021 21:58:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Developers/DOTNET-Execute-a-SAS-File-and-retrieve-results/m-p/782485#M1335</guid>
      <dc:creator>edsonbassani</dc:creator>
      <dc:date>2021-11-25T21:58:22Z</dc:date>
    </item>
    <item>
      <title>Re: [DOTNET] Execute a SAS File and retrieve results</title>
      <link>https://communities.sas.com/t5/Developers/DOTNET-Execute-a-SAS-File-and-retrieve-results/m-p/782536#M1336</link>
      <description>&lt;P&gt;Look at my libraries on GitHub (&lt;A href="https://github.com/savian-net" target="_blank"&gt;savian-net (ALAN CHURCHILL) (github.com)&lt;/A&gt;). They should help out. If anything needs more clarity, let me know. Also, Chris Hemendinger has written a lot about it so check his stuff out as well.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Download and install the SAS ODBC and OleDB packages. They should already be installed but just in case, check. You also need the Integration Technologies client.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Get a DataSet&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;        public static DataTable GetSasDataSet(string sasLibrary, string dataset)
        {
            OleDbConnection sas = null;
            DataTable dt = new DataTable(dataset);
            try
            {
                sas = new OleDbConnection(@"Provider=SAS.LocalProvider.1; Data Source=" + sasLibrary);
                sas.Open();
                OleDbCommand sasCommand = sas.CreateCommand();
                sasCommand.CommandType = CommandType.TableDirect;
                sasCommand.CommandText = dataset;
                OleDbDataReader sasRead = sasCommand.ExecuteReader();
                dt.Load(sasRead);
                sas.Close();
            }
            catch (Exception ex)
            {
                sas.Close();
                string errMessage = "Unable to get the SAS dataset. Library: " + sasLibrary + ", DataSet: " + dataset + ", " +
                    ex.TargetSite.Name;
                throw ex;
            }
            finally
            {
                sas.Close();
            }
            return dt;
        }&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;STRONG&gt;Execute SAS Code&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;public class SasRunObject
{
    public string SasLog {get;set;}
    public string SasCode {get;set;}
    public string SasList {get;set;}
}
    
internal SasRunObject SubmitSasCode(string reqId, string workarea, string sasCode)
{
    var sro = new SasRunObject();
    try
    {
        StepError = false;
        var timer = new Stopwatch();
        timer.Start();
        var ws = new Workspace();
        SetOptions(ws);
        var ls = ws.LanguageService;
        Log.Info($"Startup time for SAS: {timer.ElapsedMilliseconds} ms");
        timer.Reset();
        //Log.Info($"Submitting SAS code to workspace: {SasLanguageService.}");
        var htmlFile = Path.Combine(workarea, reqId + ".html");

        //Append special code at the top of the SAS to direct output
        sasCode = string.Join(Environment.NewLine, AddRadHeaderCode(reqId, htmlFile), sasCode, AddRadFooterCode());

        ls.Submit(sasCode);
        Log.Info($"Run time of SAS code: {timer.ElapsedMilliseconds} ms");
        timer.Stop();
        ls.StepError += SasLanguageService_StepError;
        ls.LineSeparator = "\r\n";
        sro.ProcessId = ws.GetSasProcessId();
        sro.SasCode = sasCode;
        sro.SasLog = ls.FlushLog(Common.AppConfig.SasConfig.LogCharsToAnalyze);
        sro.SasList = ls.FlushList(Common.AppConfig.SasConfig.ListCharsToAnalyze).Replace("\f", "");
        sro.HtmlOutputFile = htmlFile;
        CloseSasWorkspace(ws);
        return sro;
    }
    catch (Exception ex)
    {
        Log.Error("Error when submitting code", ex);
        return new SasRunObject();
    }
}

private void CloseSasWorkspace(Workspace ws)
{
    //var obWorkspaceManager = new SASWorkspaceManager.WorkspaceManager();
    //obWorkspaceManager.Workspaces.RemoveWorkspaceByUUID(SasWorkSpace.UniqueIdentifier);
    if (ws != null)
    {
        ws.LanguageService.Reset();
        ws.Close();
    }
    ws = null;
}

/// &amp;lt;summary&amp;gt;
/// Sets SAS options for processing
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name="ws"&amp;gt;A SAS workspace to appl options to&amp;lt;/param&amp;gt;
private static void SetOptions(SAS.Workspace ws)
{
    Log.Info("Set the SAS system options");
    var opt = ws.Utilities.OptionService;
    var options = new Dictionary&amp;lt;string, string&amp;gt;();

    options.Add("MEMLIB", "4GB");
    options.Add("NOOVP", "");
    options.Add("MEMSIZE", "MAX");
    options.Add("MEMCACHE", "4");
    options.Add("MEMMAXSZ", "12G");

    var sasOpt = options.Select(p =&amp;gt; p.Key).ToArray();
    var sasVals = options.Select(p =&amp;gt; p.Value).ToArray();
    Array errIndices = new long[options.Count];
    Array errCodes = new string[options.Count];
    Array errMsgs = new string[options.Count];
    try
    {
        opt.SetOptions(sasOpt, sasVals, out errIndices, out errCodes, out errMsgs);
        foreach (var o in options)
        {
            Log.Info($"{o.Key,-15}:{o.Value}");
        }
    }
    catch (Exception ex)
    {
        Log.Error("Error when setting SAS options. Most likely, this is caused by doing an " +
                  "Embed Interop Type on the SAS interop references. Check properties and make " +
                  "sure Embed Interop Type is set to false.", ex);
        if (errMsgs != null)
        {
            foreach (var e in errMsgs)
            {
                Log.Error($"SAS error message when setting options: {e.ToString()}");
            }
        }
        else
        {
            Log.Error($"SAS error message array is empty.");
        }
    }
}

private string AddRadFooterCode()
{
    var sb = new StringBuilder();
    sb.AppendLine($"/*" + new string('=', 50) + "*");
    sb.AppendLine($" | CODE ADDED BY SAVIAN WEB SERVICES ");
    sb.AppendLine(" *" + new string('=', 50) + "*/");
    sb.AppendLine($"ods _all_ close;");
    sb.AppendLine($"*{new string('-', 50)} ;");
    return sb.ToString();
}

private string AddRadHeaderCode(string reqId, string htmlFile)
{
    var sb = new StringBuilder();
    sb.AppendLine($"/*" + new string('=', 50) + "*");
    sb.AppendLine($" | CODE ADDED BY SAVIAN WEB SERVICES ");
    sb.AppendLine(" *" + new string('=', 50) + "*/");
    sb.AppendLine($"options fullstimer;");
    sb.AppendLine();
    sb.AppendLine($"%LET SVCSID = {reqId};");
    sb.AppendLine($"%LET SVCSWORK = {Common.AppConfig.Directories["Requests"]};");
    sb.AppendLine();
    sb.AppendLine($"ods _all_ close;");
    sb.AppendLine($"ods html file='{htmlFile}';");
    sb.AppendLine();
    sb.AppendLine($"*{new string('-', 50)} ;");
    sb.AppendLine();
    return sb.ToString();
}

&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 26 Nov 2021 12:40:31 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Developers/DOTNET-Execute-a-SAS-File-and-retrieve-results/m-p/782536#M1336</guid>
      <dc:creator>AlanC</dc:creator>
      <dc:date>2021-11-26T12:40:31Z</dc:date>
    </item>
  </channel>
</rss>

