public CatalogExplorerControl(ISASTaskConsumer3 consumer) { InitializeComponent(); Title = "SAS Catalog Explorer"; consumer3 = consumer; // get the list of SAS servers for use in the context menu foreach (SasServer s in SasServer.GetSasServers()) { MenuItem mi = new MenuItem(); mi.Header = s.Name; mi.Tag = s; mi.Click += new RoutedEventHandler(serverSelected); serverContext.Items.Add(mi); } serverButton.Click += new RoutedEventHandler(serverButton_Click); viewButton.Click += new RoutedEventHandler(viewButton_Click); deleteButton.Click += new RoutedEventHandler(deleteButton_Click); // get notified when the tree view selection changes treeView.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(treeView_SelectedItemChanged); SasServer server = new SasServer(consumer3.AssignedServer); InitializeWithServer(server); deleteButton.IsEnabled = false; viewButton.IsChecked = true; }
/// <summary> /// A special version of GetDataStepDefinition that returns just the DATA step /// header. It's used for purposes of previewing the data set structure. /// </summary> /// <param name="output">The name of the output data set.</param> /// <returns>The DATA step definition.</returns> public string GetJustDataStepDefinition(string output) { // open the connection to data SasServer sasServer = new SasServer(_server); // the "using" statement will ensure that the // connection is closed and disposed of when the // scope of the "using" block ends. using (_connection = sasServer.GetOleDbConnection()) { try { _connection.Open(); char[] types; string code = GetDataStepDefinition(output, out types); // add the "values omitted" message to the end of this preview code code = code + Environment.NewLine + Messages.ValuesOmitted; // add the 4 semicolons to terminate the DATALINES4; statement code = code + Environment.NewLine + ";;;;"; _connection.Close(); return(code); } catch (Exception ex) { return(string.Format("/*Error trying to read input data: {0} */ \n", ex.Message)); } } }
/// <summary> /// Query to retrieve the macro values from the active server /// </summary> private void RetrieveMacroValues() { SasServer s = cmbServers.SelectedItem as SasServer; using (System.Data.OleDb.OleDbConnection dbConnection = s.GetOleDbConnection()) { //----- make provider connection dbConnection.Open(); //----- Read values from query command string sql = @"select * from sashelp.vmacro order by name"; OleDbCommand cmdDB = new OleDbCommand(sql, dbConnection); OleDbDataReader dataReader = cmdDB.ExecuteReader(CommandBehavior.CloseConnection); try { MacroVars = new List <MacroVar>(); while (dataReader.Read()) { MacroVar var = new MacroVar() { Name = dataReader["name"].ToString(), CurrentValue = dataReader["value"].ToString(), Scope = dataReader["scope"].ToString() }; MacroVars.Add(var); } } finally { dataReader.Close(); dbConnection.Close(); } } }
public override ShowResult Show(IWin32Window Owner) { try { if (flag) { EGTitle = System.Diagnostics.Process.GetCurrentProcess().MainWindowTitle; flag = false; } IntPtr hwnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle; SasServer server = new SasServer(Consumer.AssignedServer); if (null != hwnd && WorkspaceID != server.GetWorkspaceIdentifier()) { string sas_pid = server.GetSasMacroValue("SYSJOBID"); string title = string.Format("{0} (EG_PID={1}; SAS_PID={2})", EGTitle, System.Diagnostics.Process.GetCurrentProcess().Id, sas_pid); SetWindowText(hwnd, title); WorkspaceID = server.GetWorkspaceIdentifier(); } } catch { }; return(ShowResult.Canceled); }
public CatalogExplorerControl(ISASTaskConsumer3 consumer) { InitializeComponent(); Title = "SAS Catalog Explorer"; consumer3 = consumer; // get the list of SAS servers for use in the context menu foreach (SasServer s in SasServer.GetSasServers()) { MenuItem mi = new MenuItem(); mi.Header = s.Name; mi.Tag = s; mi.Click += new RoutedEventHandler(serverSelected); serverContext.Items.Add(mi); } serverButton.Click += new RoutedEventHandler(serverButton_Click); viewButton.Click += new RoutedEventHandler(viewButton_Click); deleteButton.Click += new RoutedEventHandler(deleteButton_Click); // get notified when the tree view selection changes treeView.SelectedItemChanged += new RoutedPropertyChangedEventHandler <object>(treeView_SelectedItemChanged); SasServer server = new SasServer(consumer3.AssignedServer); InitializeWithServer(server); deleteButton.IsEnabled = false; viewButton.IsChecked = true; }
private void PopulateUserFormats(TreeNode tn) { SasServer s = new SasServer(currentServer); using (System.Data.OleDb.OleDbConnection dbConnection = s.GetOleDbConnection()) { //----- make provider connection dbConnection.Open(); //----- Read values from query command string sql = @"select distinct libname, memname from sashelp.vformat where libname NOT is missing"; OleDbCommand cmdDB = new OleDbCommand(sql, dbConnection); OleDbDataReader dataReader = cmdDB.ExecuteReader(CommandBehavior.CloseConnection); try { while (dataReader.Read()) { TreeNode n = new TreeNode(string.Format("{0}.{1}", dataReader["libname"].ToString(), dataReader["memname"].ToString())); n.ImageIndex = (int)CatImages.Catalog; n.SelectedImageIndex = (int)CatImages.Catalog; n.Tag = "LIBCAT"; tn.Nodes.Add(n); } } finally { dataReader.Close(); dbConnection.Close(); } } }
/// <summary> /// Get the details about the SAS option /// and its value /// </summary> /// <param name="optionName">Name of the option</param> /// <param name="whereset">return value: where the value was set</param> /// <param name="startup">return value: value at startup</param> /// <param name="fullval">return value: full value of the option</param> private void getOptionInfo(string optionName, ref string whereset, ref string startup, ref string fullval) { whereset = "<cannot determine>"; startup = "<cannot determine>"; try { SAS.Tasks.Toolkit.SasSubmitter submitter = new SasSubmitter(cmbServers.Text); if (!submitter.IsServerBusy()) { string outLog; string program = string.Format( optionDetails + (dServerVer > 9.2 ? optionStartup : ""), optionName); bool success = submitter.SubmitSasProgramAndWait(program, out outLog); if (success) { SasServer s = new SasServer(cmbServers.Text); whereset = s.GetSasMacroValue("_EGOPTHOWSET"); fullval = s.GetSasMacroValue("_EGOPTFULLVAL"); if (dServerVer > 9.2) { startup = s.GetSasMacroValue("_EGOPTSTARTUP"); } } } } catch { } }
/// <summary> /// Get the SAS program that this task should generate /// based on the options specified. /// </summary> /// <returns>a valid SAS program to run</returns> public override string GetSasCode() { SasServer s = new SasServer(Consumer.AssignedServer); string enc = s.GetSasSystemOptionValue("ENCODING"); SPList.ServerCodePage = SASEncodingToWindowsCodepage(enc); return(settings.GetSasProgram()); }
/// <summary> /// Generate a SAS DATA step program from the active data set. /// </summary> /// <remarks> /// <b>NOTE:</b>The DATALINES content is built up entirely in memory. /// If you need this to work with very large data sets, this would need /// to be refactored to emit the contents to a file-based stream as you /// build it out. /// <para> /// Using StringBuilder along the way prevents large strings from being copied around /// and duplicated, but eventually there is going to /// be a large block of text represented in the process memory. /// </para> /// </remarks> /// <param name="output">The output location of the SAS data set that the program will create.</param> /// <returns>The complete SAS DATA step program, complete with DATALINES values.</returns> public string GetCompleteSasProgram(string output) { System.Text.StringBuilder sb = new StringBuilder(); SasServer sasServer = new SasServer(_server); using (_connection = sasServer.GetOleDbConnection()) { try { _connection.Open(); char[] types; sb.Append(GetDataStepDefinition(output, out types)); string valuesdata = string.Format("{0}.{1}", _libref, _member); OleDbCommand command = new OleDbCommand(string.Format("select * from {0}", valuesdata), _connection); using (OleDbDataReader dataReader = command.ExecuteReader()) { int fields = dataReader.FieldCount; ColumnCount = fields; RowCount = 0; while (dataReader.Read()) { StringBuilder line = new StringBuilder(); for (int i = 0; i < fields; i++) { string val = dataReader[i].ToString(); if (types[i] == 'C') { // quote and escape strange chars for character values val = string.Format("\"{0}\"", FixUpDatalinesString(val)); } line.AppendFormat("{0}{1}", val, i < fields - 1 ? "," : ""); } // increment the row count RowCount++; // add to our main program sb.AppendFormat("{0}\n", line.ToString()); } } _connection.Close(); } catch (Exception ex) { sb.AppendFormat("/*Error trying to read input data: {0} */ \n", ex.Message); } finally { // close out the datalines and add RUN sb.Append(";;;;\nRUN;\n"); } } return(sb.ToString()); }
// Clear the form of all info, and populate the tree with // libraries and catalogs for the current server private void NavigateToServer() { Cursor c = Cursor.Current; Cursor.Current = Cursors.WaitCursor; tvLibsCats.Nodes.Clear(); lvMembers.Items.Clear(); TreeNode sn = tvLibsCats.Nodes.Add(currentServer); sn.ImageIndex = (int)CatImages.Server; sn.SelectedImageIndex = (int)CatImages.Server; sn.Tag = "SERVER"; try { SasServer s = new SasServer(currentServer); foreach (SasLibrary lib in s.GetSasLibraries()) { if (lib.IsAssigned) { TreeNode tn = new TreeNode(lib.Libref); tn.ImageIndex = (int)CatImages.Library; tn.SelectedImageIndex = (int)CatImages.Library; tn.Tag = "LIBRARY"; sn.Nodes.Add(tn); // add catalogs for this library PopulateCatalogs(tn); } } TreeNode tnf = new TreeNode(Translate.LabelUserDefinedFormats); tnf.ImageIndex = (int)CatImages.Folder; tnf.SelectedImageIndex = (int)CatImages.Folder; tnf.Tag = "FMTSEARCH"; sn.Nodes.Add(tnf); FmtSearch = s.GetSasSystemOptionValue("FMTSEARCH"); PopulateUserFormats(tnf); // open to the Library list sn.Expand(); } catch { } Cursor.Current = c; UpdateToolbar(); }
/// <summary> /// Initialize the combobox with servers /// </summary> private void LoadServers() { cmbServers.BeginUpdate(); cmbServers.Items.Clear(); cmbServers.DisplayMember = "Name"; foreach (SasServer s in SasServer.GetSasServers()) { cmbServers.Items.Add(s); } cmbServers.Text = Consumer.AssignedServer; cmbServers.EndUpdate(); }
private void PopulateLibraries() { // 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()); // clear Members list, out of sync with previous selection lbMembers.Items.Clear(); }
private void AddCardinalities() { SasServer s = new SasServer(Consumer.AssignedServer); using (OleDbConnection conn = s.GetOleDbConnection()) { try { //----- make provider connection conn.Open(); //----- Read values from query command string sql = @"select * from work._ds_cardinalities"; OleDbCommand cmdDB = new OleDbCommand(sql, conn); OleDbDataReader dataReader = cmdDB.ExecuteReader(CommandBehavior.CloseConnection); while (dataReader.Read()) { cardinalities.Add( dataReader["name"].ToString(), new Cardinality() { levels = Convert.ToInt32(dataReader["nlevels"]), pct_unique = Convert.ToDouble(dataReader["pct_unique"]) } ); } lvColumns.BeginUpdate(); foreach (ListViewItem li in lvColumns.Items) { Cardinality c = cardinalities[li.Text]; if (c != null) { li.SubItems[(int)eColIndex.Cardinality].Text = c.levels.ToString(); li.SubItems[(int)eColIndex.PctUnique].Text = c.pct_unique.ToString("#0.00%"); ((ColTag)li.Tag).Cardinality = c; } } lvColumns.EndUpdate(); } catch { } finally { conn.Close(); } } }
private void InitializeWithServer(SasServer server) { Cursor c = Cursor; try { Cursor = Cursors.Wait; serverLabel.Text = server.Name; SasLibrary[] libraries = server.GetSasLibraries().ToArray(); ServerViewModel model = new ServerViewModel(libraries); treeView.DataContext = model; } finally { Cursor = c; } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); // Set up controls for data binding use lbItems.DisplayMember = "Name"; lbLibraries.DisplayMember = "Name"; lbMembers.DisplayMember = "Member"; cmbServer.DisplayMember = "Name"; // populate comb box with SasServer objects foreach (SasServer s in SasServer.GetSasServers()) { cmbServer.Items.Add(s); } cmbServer.Text = Consumer.AssignedServer; Text = "Explore SAS Data Properties"; PopulateLibraries(); cmbServer.SelectedIndexChanged += new EventHandler(OnServerChanged); }
private string ConnectToSAS() { string statusMsg = ""; activeSession = new SasServer(); try { activeSession.Connect(); if (activeSession.UseLocal) { statusMsg = "Connected to local SAS session"; } } catch (Exception ex) { statusMsg = string.Format("Connection failure {0}", ex.Message); } return(statusMsg); }
/// <summary> /// A special version of GetDataStepDefinition that returns just the DATA step /// header. It's used for purposes of previewing the data set structure. /// </summary> /// <param name="output">The name of the output data set.</param> /// <returns>The DATA step definition.</returns> public string GetJustDataStepDefinition(string output) { // open the connection to data SasServer sasServer = new SasServer(_server); // the "using" statement will ensure that the // connection is closed and disposed of when the // scope of the "using" block ends. using (_connection = sasServer.GetOleDbConnection()) { try { _connection.Open(); char[] types; string code = GetDataStepDefinition(output, out types); // add the "values omitted" message to the end of this preview code code = code + Environment.NewLine + Messages.ValuesOmitted; // add the 4 semicolons to terminate the DATALINES4; statement code = code + Environment.NewLine + ";;;;"; _connection.Close(); return code; } catch (Exception ex) { return string.Format("/*Error trying to read input data: {0} */ \n", ex.Message); } } }
private void RetrieveOptionValues() { SasServer s = cmbServers.SelectedItem as SasServer; dServerVer = 9.2; string ver = s.GetSasMacroValue("SYSVER"); try { dServerVer = Convert.ToDouble(ver); } catch { } using (System.Data.OleDb.OleDbConnection dbConnection = s.GetOleDbConnection()) { //----- make provider connection dbConnection.Open(); //----- Read values from query command string sql = @"select * from sashelp.vallopt order by optname"; OleDbCommand cmdDB = new OleDbCommand(sql, dbConnection); OleDbDataReader dataReader = cmdDB.ExecuteReader(CommandBehavior.CloseConnection); try { Options = new List <Option>(); while (dataReader.Read()) { Option opt = new Option() { Name = dataReader["optname"].ToString(), Setting = dataReader["setting"].ToString(), Type = dataReader["opttype"].ToString(), Description = dataReader["optdesc"].ToString(), Level = dataReader["level"].ToString(), Start = dServerVer > 9.2 ? dataReader["optstart"].ToString() : "", Group = dataReader["group"].ToString() }; if (opt.Level.ToUpper() == "GRAPH") { opt.Group = "GRAPH"; opt.Level = "Portable"; opt.Start = "OPTIONS or GOPTIONS statement"; } switch (opt.Start.ToLower()) { case "anytime": opt.Start = "OPTIONS statement or startup"; break; case "startup": opt.Start = "Startup only"; break; case "": opt.Start = opt.Start = "(requires SAS 9.3 or later to determine)"; break; default: break; } ; Options.Add(opt); } } finally { dataReader.Close(); dbConnection.Close(); } } }
public string GetSasCode() { bool ise = (fln == String.Empty); string fle = dlremfile(url,ise); string servername = this.consumer.AssignedServer; //MessageBox.Show(fle); string savepath = ""; string tfln = ""; SasServer server = new SasServer(servername); if (!iszip) { enc(fle); savepath = server.CopyLocalFileToServer(fle); tfln = Path.GetFileName(fle); } else { string trg = unzip(fle)[0]; enc(trg); savepath = server.CopyLocalFileToServer(trg); tfln = Path.GetFileName(trg); //MessageBox.Show(savepath,trg); } string post_savpath = "\"" + savepath + "\""; return string.Format("proc sql; select xpath into :fl from dictionary.extfiles where fileref={0};quit; x mv &fl ~/{1}; %let filelocation= ~/{1}; ", post_savpath, tfln); //return savepath; }
/// <summary> /// Get the details about the SAS option /// and its value /// </summary> /// <param name="optionName">Name of the option</param> /// <param name="whereset">return value: where the value was set</param> /// <param name="startup">return value: value at startup</param> /// <param name="fullval">return value: full value of the option</param> private void getOptionInfo(string optionName, ref string whereset, ref string startup, ref string fullval) { whereset = "<cannot determine>"; startup = "<cannot determine>"; try { SAS.Tasks.Toolkit.SasSubmitter submitter = new SasSubmitter(cmbServers.Text); if (!submitter.IsServerBusy()) { string outLog; string program = string.Format( optionDetails + (dServerVer > 9.2 ? optionStartup : ""), optionName); bool success = submitter.SubmitSasProgramAndWait(program, out outLog); if (success) { SasServer s = new SasServer(cmbServers.Text); whereset = s.GetSasMacroValue("_EGOPTHOWSET"); fullval = s.GetSasMacroValue("_EGOPTFULLVAL"); if (dServerVer > 9.2) startup = s.GetSasMacroValue("_EGOPTSTARTUP"); } } } catch { } }
/// <summary> /// Submit a bit of code to assign a macro var to with the /// expression, and then retrieve the resulting value. /// If ERROR, show the error in the field instead /// </summary> /// <param name="expression"> /// Expression to evaluate as macro expression /// </param> /// <param name="sasServer"> /// Name of the SAS server /// </param> private void SolveExpression(string expression, string sasServer) { // set UI elements to default state txtEval.ForeColor = SystemColors.WindowText; Cursor c = Cursor.Current; Cursor.Current = Cursors.WaitCursor; // prepare to measure the time it takes to run DateTime start = DateTime.Now; try { if (!string.IsNullOrEmpty(expression)) { // disable solve button while running btnSolve.Enabled = false; string resolveProgram = string.Format("%let _egMacroQuickEval = {0};", expression); string outLog; SAS.Tasks.Toolkit.SasSubmitter submitter = new SasSubmitter(sasServer); // show busy message if needed if (submitter.IsServerBusy()) { MessageBox.Show( string.Format("Unable evaluate expression using {0}: Server is running another program.", sasServer), "Server busy"); } else { // submit expression and wait bool success = submitter.SubmitSasProgramAndWait(resolveProgram, out outLog); if (success) { SasServer s = new SasServer(sasServer); txtEval.Text = s.GetSasMacroValue("_EGMACROQUICKEVAL"); // scan output log for warning messages string[] lines = outLog.Split('\n'); string msg = ""; foreach (string l in lines) { // WARNING lines prefixed with 'w' if (l.StartsWith("w")) { // color WARNINGs blue msg = msg + l.Substring(2) + Environment.NewLine; txtEval.ForeColor = Color.Blue; } } txtEval.Text += Environment.NewLine + msg; } else { // scan output log for error lines string[] lines = outLog.Split('\n'); string msg = ""; foreach (string l in lines) { // ERROR lines prefixed with 'e', WARNING with 'w' if (l.StartsWith("w") || l.StartsWith("e")) { msg = msg + l.Substring(2) + Environment.NewLine; } } // color ERRORs red txtEval.Text = msg; txtEval.ForeColor = Color.Red; } } } } // catch any errant exceptions catch (Exception ex) { MessageBox.Show( string.Format("Unable evaluate expression using {0}: {1}", sasServer, ex.Message), "Error"); } // finally block to clean/reset UI controls finally { btnSolve.Enabled = true; Cursor.Current = c; // add summary with timing TimeSpan s = new TimeSpan(DateTime.Now.Ticks - start.Ticks); stsMsgLabel.Text = string.Format("Evaluated expression in {0} seconds", Convert.ToInt32(s.TotalSeconds)); } }
// When code query is complete, read the process details from // a SAS data set on the server session. // Use this to populate the list view of processes. private void AddProcesses() { listProcesses.BeginUpdate(); listProcesses.Items.Clear(); SasServer s = new SasServer(Consumer.AssignedServer); string thisProcess = s.GetSasMacroValue("SYSJOBID"); using (OleDbConnection conn = s.GetOleDbConnection()) { try { //----- make provider connection conn.Open(); //----- Read values from query command string sql = @"select * from work._allpids_"; OleDbCommand cmdDB = new OleDbCommand(sql, conn); OleDbDataReader dataReader = cmdDB.ExecuteReader(CommandBehavior.CloseConnection); while (dataReader.Read()) { // create an in-memory object of the process // so we can use this in a PropertyGrid control later SasProcess proc = new SasProcess(); proc.PID = dataReader["ProcessIdentifier"].ToString().Trim(); proc.Host = dataReader["HostKnownBy"].ToString().Trim(); proc.Type = dataReader["ServerComponentName"].ToString().Trim(); proc.ServerPort = dataReader["ServerPort"].ToString().Trim(); proc.UUID = dataReader["UniqueIdentifier"].ToString().Trim(); proc.CPUs = dataReader["CPUCount"].ToString().Trim(); proc.Command = dataReader["Command"].ToString().Trim(); proc.Owner = dataReader["ProcessOwner"].ToString().Trim(); proc.SASVersion = dataReader["VersionLong"].ToString().Trim(); proc.StartTime = dataReader["UpTime"].ToString().Trim(); ListViewItem li = new ListViewItem(proc.PID); li.Tag = proc; li.SubItems.Add(proc.Type); li.SubItems.Add(proc.Host); li.SubItems.Add(proc.Owner); li.SubItems.Add(proc.StartTime); li.SubItems.Add(proc.UUID); if (proc.PID.Trim() == thisProcess.Trim()) li.BackColor = Color.LightGoldenrodYellow; listProcesses.Items.Add(li); } } catch { MessageBox.Show("An error occurred while trying to retrieve the list of spawned processes.", "Cannot retrieve processes"); } finally { conn.Close(); } } listProcesses.EndUpdate(); }
private void btnKill_Click(object sender, EventArgs e) { if (listProcesses.SelectedItems.Count == 1) { SasServer serv = new SasServer(Consumer.AssignedServer); string thisProcess = serv.GetSasMacroValue("SYSJOBID"); SasProcess proc = (listProcesses.SelectedItems[0].Tag as SasProcess); if (proc.PID.Trim() == thisProcess.Trim()) { // confirm before killing the current active SAS session if (DialogResult.No == MessageBox.Show("The selected process is your active SAS session. Do you still want to stop it?", "Warning", MessageBoxButtons.YesNo)) return; } string log = ""; string UUID = (listProcesses.SelectedItems[0].Tag as SasProcess).UUID; string program = string.Format(killProgram, UUID ); SasSubmitter s = new SasSubmitter(Consumer.AssignedServer); if (s.IsServerBusy()) { MessageBox.Show(string.Format("The server {0} is busy; cannot end selected process.", Consumer.AssignedServer)); // bail out, return control to UI return; } // server is available, so submit code synchronously bool success = s.SubmitSasProgramAndWait(program, out log); if (success) RefreshProcesses(); else { // ERROR - provide option to show the SAS log if (DialogResult.Yes == MessageBox.Show("An error occurred while trying to end the selected process. Would you like to view the error log?", "Error", MessageBoxButtons.YesNo)) { SAS.Tasks.Toolkit.Controls.SASLogViewDialog logView = new SASLogViewDialog("Error log", "PROC IOMOPERATE log:", log); logView.ShowDialog(this); }; } } }
/// <summary> /// Get the SAS program that this task should generate /// based on the options specified. /// </summary> /// <returns>a valid SAS program to run</returns> public override string GetSasCode() { SasServer s = new SasServer(Consumer.AssignedServer); string enc = s.GetSasSystemOptionValue("ENCODING"); SPList.ServerCodePage = SASEncodingToWindowsCodepage(enc); return settings.GetSasProgram(); }
/// <summary> /// Submit a bit of code to assign a macro var to with the /// expression, and then retrieve the resulting value. /// If ERROR, show the error in the field instead /// </summary> /// <param name="expression"> /// Expression to evaluate as macro expression /// </param> /// <param name="sasServer"> /// Name of the SAS server /// </param> private void SolveExpression(string expression, string sasServer) { // set UI elements to default state txtEval.ForeColor = SystemColors.WindowText; Cursor c = Cursor.Current; Cursor.Current = Cursors.WaitCursor; // prepare to measure the time it takes to run DateTime start = DateTime.Now; try { if (!string.IsNullOrEmpty(expression)) { // disable solve button while running btnSolve.Enabled = false; string resolveProgram = string.Format("%let _egMacroQuickEval = {0};", expression); string outLog; SAS.Tasks.Toolkit.SasSubmitter submitter = new SasSubmitter(sasServer); // show busy message if needed if (submitter.IsServerBusy()) { MessageBox.Show( string.Format("Unable evaluate expression using {0}: Server is running another program.", sasServer), "Server busy"); } else { // submit expression and wait bool success = submitter.SubmitSasProgramAndWait(resolveProgram, out outLog); if (success) { SasServer s = new SasServer(sasServer); txtEval.Text = s.GetSasMacroValue("_EGMACROQUICKEVAL"); // scan output log for warning messages string[] lines = outLog.Split('\n'); string msg = ""; foreach (string l in lines) { // WARNING lines prefixed with 'w' if (l.StartsWith("w")) { // color WARNINGs blue msg = msg + l.Substring(2) + Environment.NewLine; txtEval.ForeColor = Color.Blue; } } txtEval.Text += Environment.NewLine + msg; } else { // scan output log for error lines string[] lines = outLog.Split('\n'); string msg = ""; foreach (string l in lines) { // ERROR lines prefixed with 'e', WARNING with 'w' if (l.StartsWith("w") || l.StartsWith("e")) msg = msg + l.Substring(2) + Environment.NewLine; } // color ERRORs red txtEval.Text = msg; txtEval.ForeColor = Color.Red; } } } } // catch any errant exceptions catch (Exception ex) { MessageBox.Show( string.Format("Unable evaluate expression using {0}: {1}", sasServer, ex.Message), "Error"); } // finally block to clean/reset UI controls finally { btnSolve.Enabled = true; Cursor.Current = c; // add summary with timing TimeSpan s = new TimeSpan(DateTime.Now.Ticks - start.Ticks); stsMsgLabel.Text = string.Format("Evaluated expression in {0} seconds", Convert.ToInt32(s.TotalSeconds)); } }
/// <summary> /// Generate a SAS DATA step program from the active data set. /// </summary> /// <remarks> /// <b>NOTE:</b>The DATALINES content is built up entirely in memory. /// If you need this to work with very large data sets, this would need /// to be refactored to emit the contents to a file-based stream as you /// build it out. /// <para> /// Using StringBuilder along the way prevents large strings from being copied around /// and duplicated, but eventually there is going to /// be a large block of text represented in the process memory. /// </para> /// </remarks> /// <param name="output">The output location of the SAS data set that the program will create.</param> /// <returns>The complete SAS DATA step program, complete with DATALINES values.</returns> public string GetCompleteSasProgram(string output) { System.Text.StringBuilder sb = new StringBuilder(); SasServer sasServer = new SasServer(_server); using (_connection = sasServer.GetOleDbConnection()) { try { _connection.Open(); char[] types; sb.Append(GetDataStepDefinition(output, out types)); string valuesdata = string.Format("{0}.{1}", _libref, _member); OleDbCommand command = new OleDbCommand(string.Format("select * from {0}", valuesdata), _connection); using (OleDbDataReader dataReader = command.ExecuteReader()) { int fields = dataReader.FieldCount; ColumnCount = fields; RowCount = 0; while (dataReader.Read()) { StringBuilder line = new StringBuilder(); for (int i = 0; i < fields; i++) { string val = dataReader[i].ToString(); if (types[i] == 'C') { // quote and escape strange chars for character values val = string.Format("\"{0}\"", FixUpDatalinesString(val)); } line.AppendFormat("{0}{1}", val, i < fields - 1 ? "," : ""); } // increment the row count RowCount++; // add to our main program sb.AppendFormat("{0}\n", line.ToString()); } } _connection.Close(); } catch (Exception ex) { sb.AppendFormat("/*Error trying to read input data: {0} */ \n", ex.Message); } finally { // close out the datalines and add RUN sb.Append(";;;;\nRUN;\n"); } } return sb.ToString(); }