Dealing with SAS Sessions while running a Stored Process - vba

Currently I am trying to run a SAS program using VBA. Using the SAS Add-In For Microsoft Office, I created a stored process that contains a generic code that creates a dummy table. Inside SAS EG, I am able to run the Stored Process normally, and also inside the Excel environment, using the InsertStoredProcess function of the SASExcelAddIn object. Regardless of the environment used to run my Stored Process, the behavior of the SAS Sessions are the same: one session is created when I start to run and another one is created during the process. However, that is where my problem comes. When the process finishes, I continue with the two sessions as active, and every time I try to run again my Stored Process, one new session is created over the ones that already existed. The sessions close only when I manually disconnect from the SAS Server I'm connected or when I close the Excel. Since my organization allows only three concurrent sessions, this is becoming a big problem for me.
I already tried to use the ABORT macro function inside my code, the rc=stpsrv_session('delete') command and delete the Stored Process from the Excel worksheet, and none of them solved my problem.
Any ideas of what I'm missing here? Is there a way to end the SAS Session after the Stored Process ends?

First of all, you shouldn't use VBA to do any of this. If in Office products, use VSTO and C#. I am in the throes of converting thousands of lines of VBA to C#/VSTO. VBA is very obsolete which is why the code is being converted.
Second, EG is built using C# so it is more natural to use. You can even create custom tasks using C# in EG.
You need to close out your sessions after they are started. See this post at SAS for how to close out your sessions in VBA: https://communities.sas.com/t5/SAS-Enterprise-Guide/Calling-SAS-through-VBA/td-p/79673
Again, you should stop using VBA and switch over. It will be much easier. VSTO is free and is made to interact with Office. Use Visual Studio to create your project. The C# code for working with SAS can be found using any of Chris Hemendinger's post (SAS community manager) or you can refer to links on my github repos here: https://github.com/savian-net

Related

Logging When Files Are Saved, Modified or Deleted Using VBA

I work with VBA in MS Access databases. I'd like to be able to log when files are saved, modified or deleted without having to update the existing code to do the logging when the pertinent events take place. I want the time, location and the name of the file.
I found a good example here: when file modified
However, it only allows for monitoring a particular location (path). I want to be able to log regardless of where the save, modify or delete takes place. I'm only allowed to program in the MS Office environment in this situation. It seems as though using the Windows API is going to be how this task will be achieved. However, I don't have much experience working with the API. Is there an easier way to achieve what I want that doesn't involve using the API?
Have you worked with After_Updates or After_Insert macros? Also, is your application split? Meaning there's a front-end and a back-end of the database. You can create a separate table that mirrors that table that you need to track changes for. Every time a table is updates, run a macro that inserts a row to that table.
I'm assuming you're saving files to the database. If that's the case, add a after_update or after_insert macro that can keep track of when then files are being modified or added to the table.

Run Code after any VBA (MS Access) error

I am developing for an error logging application for data centers that use MS Access. In the test environment there are +- 200 MS Access MDBs. I at the point where my application will run on one MDB perfectly fine. I have achieved the MDB specific functionality by inserting code into each and every On_Error function, and by wrapping any function in such an On_Error catch statement.
My problem is that to alter each and every database and each and every function in each of those would be redundant.
Is there anyway to add some code/module to each MDB just in one place that would be run on any error? (Alternatively is there a way to open and alter the VBA behind the forms programmically, even if it involves ridiculous string-manipulation.)
You can link a centralized library mdb/mde as per DaveMac's link, but error handling ("On Error ...") needs to be local in each and every function. That's just how it is in VBA.
Using the VBIDE object library, you can access and modify VBA code in other databases. See
Import lines of code
https://christopherjmcclellan.wordpress.com/2014/11/06/meta-programming-in-vba-the-vbide-and-why-documentation-is-important/
It will be quite a bit of work though, I think. I only ever used this to copy modules from one (Word) file to a couple of other files, and it took some time to get it right.
Note that using http://www.mztools.com/v3/mztools3.aspx you can add a customizable error handler to a function with one click (or shortcut).
Doing it with VBIDE might not be the faster way in the end, but surely more fun. :)

VB columed profile/process list with embedded sqllite database for editable process parameters

I have no idea how to make this in Visual Studio 2010. I'm trying to make a program that has a "grid" with columns. It will have a option to name a new profile/process, which is then added to the grid/list.
I can then edit the profile/process by clicking a button and editing the parameters that the process runs with.
most of the time these processes are the same same program/executable, just multi-instanced.
I can then start the process with the given parameters after I have setup it's profile.
I want to be able to monitor the RAM/CPU usage in one of the colums of the record/profile/process, sort of like the task manager and also "maintain" the process and keep it running/restart automatically it so it doesn't stop or crash unless directed otherwise.
I want these profiles/process parameters to be stored in a sqllite dll embedded database.
I would appreciate your help. thanks.
The very first step is for you to get all process, then place it in a container.
From there you can rename the process via My.Computer.FileSystem.RenameFile(file ,newName)
I prefer using datagridview, as with it you can easily add/remove columns and refer to the data. Assuming you have a datagridview with one column:
For Each ito As Process In Process.GetProcesses
Datagridview1.rows.add(ito.ProcessName.ToString)
Next
this will get you through the first part.

Many user using one program (.exe) that includes datasets

I created a time recording program in vb.net with a sql-server as backend. User can send there time entries into the database (i used typed datasets functionality) and send different queries to get overviews over there working time.
My plan was to put that exe in a folder in our network and let the user make a link on their desktops. Every user writes into the same table but can only see his own entries so there is no possibility that two user manipulate the same dataset.
During my research i found a warning that "write contentions between the different users" can be occur. Is that so in my case?
Has anyone experience with "many user using the same exe" and where that is using datasets and could give me an advice whether it is working or what i should do instead?
SQL Server will handle all of your multi-user DB access concerns.
Multiple users accessing the same exe from a network location can work but it's kind of a hack. Let's say you wanted to update that exe with a few bug fixes. You would have to ensure that all users close the application before you could release the update. To answer you question though, the application will be isolated to each user running it. You won't have any contention issues when it comes to CRUD operations on the database due to the network deployment.
You might consider something other than a copy/paste style publishing of your application. Visual Studio has a few simple tools you can use to publish your application to a central location using ClickOnce deployment.
http://msdn.microsoft.com/en-us/library/31kztyey(v=vs.110).aspx
My solution was to add a simple shutdown-timer in the form, which alerts users to saving their data before the program close att 4 AM.
If i need to upgrade, i just replace the .exe on the network.
Ugly and dirty, yes... but worked like a charm for the past 2 years.
good luck!

How can I protect a process I start from within my vb.net program?

I've created a small application that basically reads and writes to a single Excel.exe process. It's basically a timer that records the time I use on projects and then store it in an Excel sheet. This works great, however, I've noticed that if I open Excel manually, work on some sheets and whatnot, save and exit etcetc, the process my software use gets broken or something. The same thing that happens if I manually close the excel.exe process and my software doesn't "know".
So I was wondering if it's possible to protect the excel.exe process somehow? To make sure it can't be closed or tampered with in the meantime?
Let me suggest an alternative approach that does not require you to have an Excel process running all the time (after all, this also consumes a lot of system resources):
Let your application record your information. Every now and then -- for example, after a work entry has been finished or a specific time has elapsed -- open the Excel sheet, write the data, and close it again (also closing the Excel process that you are automating). This save operation should not take more than a few seconds and it will (mostly) prevent the problem you are experiencing.
In fact, since Office automation is always a bit painful, an even better way would be to output your data without requiring an Excel process. To do this, you could use
one of the third-party Excel libraries available for .net,
a CSV or HTML file, which can be opened by Excel, or
open the Excel file as a database with ADO.NET.
You cannot protect a process, but you can check the process.HasExited property to find out whether the process has terminated and take action based on that.
Add an exception handler. Either call non-throw methods if possible.