VB - Automated Excel in Visual Studio 2010 - Selection Changed Question - vb.net

I am currently writing an utility that takes two different sets of data from an excel document and sends it to two different web services. Each set of data has it's own button that sends the data to the web service. When the a button is clicked, the corresponding web service then returns data depending on the input values.
What I am trying to do is so that this utility can be distrobuted and used by a wide variety of people. What they are going to do is they are going to be synchronizing there particular cells of their own excel document to the corresponding cell in my utility. Using simple excel formulas. For example:
c:\temp\[book1.xls]sheet1'!a1
Now what I am trying to do is automatically "click" the button, or update, on my utility when the user links their cell to its corresponding cell on my utility.
I have tried the selection change event on my page. But it doesn't actually process until my utility is active, or clicked on.
Is there a way to make my utility automatically update? It would be especially awesome if somehow it did this while my utility was closed. So when the user opens it it is already filled with their information, and the outputs are correct.

The requirements:
you need to guarantee that when a user is using excel your app can collect the data. Your app may not be running at the time. You need the Worksheet_SelectionChange() event to fire automatically not just when your app is active.
Solution:
Basically in order to guarantee that the Worksheet_SelectionChange() is running all the time, and in order to guarantee that whenever the user opens an instance of excel you are able to collect and process the data/formulas entered into the particular target range address you need to wire up the selectionchange event inside of a VB.NET Excel COM Addin. There are several ways to do this, but since your using VB.NET your best off using the newest approach which is building a VSTO COM Addin.
There are numerous other questons available on how to best build a VSTO addin (some in C# some in VB.NET but all this information is exactly the same for both, just different syntax).
So you will need two projects. Your existing one, plus a Excel VSTO addin (which you can also do in VB.NET).
Now inside the selectionchange event you should make sure that your code handles the target range correctly; ie. make sure you check for non-contigious groups of ranges with a selection... A1:B1;D2:E2 and copy the data to your app. You may consider using a format such as xml to serialise the latest data from excel so that if your app is not open at the time, it can deserialise and read back the data stored for it the next time it is opened. I guess it really depends how your handling the data (i.e. is it for loading into a datagrid?) and whether you are going to do further processing and store it somewhere else later (in which case maybe you can put it straight into a database from the addin in excel).

Related

Update VBAs in multiple workbooks

END GAME: A user saved Workbook opens and mirrors code from a target file.
I am trying to create a simple VBA application that has an Excel front-end and an Access back-end. There will be multiple users who would have the option to save the front-end Excel piece anywhere they desire.
I would like to know the most efficient way to be able to update macros in all user instances when I need to push updates.
Essentially, I would like to mirror code from a "global" file on Workbook_open. In the past I did actually set code to open a separate workbook and run code (dim x as workbook, open, app.runmacro and etc.), But I think that is not really the most efficient way to do it.
Four possible solutions pop to mind for this (other than your option of having an intermediary workbook), there are likely others:
Treat the Workbook as purely an interface, and move the code to the
Access database and have it accept the Workbook as a parameter if
needed. The advantage would be the code could be maintained in one
place (Access), but it would have two main disadvantages. Each user
would need to have Access installed in order for it to instantiate
the application to call methods on, and it would lock in your
"interface" - that is, changes to how it calls Access macros would
still require Workbook updates.
Create a canonical Workbook and have the user Workbook version check
against the canonical Workbook when opened. If the version is
different, open the new one, move all of the data to it, delete the
old one, and save the new copy to the same filename as the old one.
The main disadvantage of this method would be ensuring that old code doesn't run might be difficult, as you would need
to take measures to prevent situations where the user could abort
the update process and still have a working copy of the old code.
Automate the VBE (see this answer for implementation details -
there are numerous resources on how to do this). Depending on how
you wanted to do this, you could either store the current modules as
files and import them, or store the code in the database itself and
query for it. The main disadvantages of this method are that the
VBE can be fickle about changing code that is actually running. I'm
not sure that I'd trust it to change it's own implementation. You
would also need to allow access to the VBE in each user's security
settings, which may pose a security threat.
Store the location of the Workbooks themselves in the database, then
push out updated copies with external code. The Workbook would
report it's filepath when opened, and if it wasn't already recorded
in the database, check to see if it was the most current version,
and then write a record for itself. This has the disadvantage of
only being able to inform the user that they don't have the current
version if they (for example) move the Workbook in Explorer and
don't open it until after your push.
Note that these are all "pull" type as opposed to "push" type solutions with the exception of the last one. Regardless of the method you use for version checking, any push solution is going to share the disadvantage of number 4 - there is no reliable way to make sure that a push catches all the invalidated versions.

mimic bdh function fill down

When a query is entered into the Bloomberg BDH function in Excel it automatically populates the selected cell, and cells below with the requested data.
I am trying to create a function that does something similar (albeit with a different source of data). How does the BDH function circumvent the typical restriction within a user defined function of modifying other cells when it fills down the queried data?
You need to do it in a two-stage process:
Your function calls another process to compute values and return only the 1st element of the array to be returned (could be "#NA #NA" or the date or price, etc.
The called process can be running in a separate RTD server (check out Real Time Data server) or a separate process which links to your spreadsheet via DDE. (Bloomberg uses DDE for some functions, RTD for the others, I think)
That way when you call a function, the first value is returned immediately (i.e. the answer, or "#NA Requesting Data..." and then when the RTD server fetches the required data the answer to this function changes to whatever the top-left array element is, and the rest of the cells are populated via DDE/RTD.
Simple examples of setting up a RTD server are found on Microsoft's knowledge base. Also, lots of examples using DDE (an older, but very popular technology for financial data exchange using Excel, even today) are available upon Googling.
A simple filler application can be built using C# or VB.net Interop (search again for examples).
Hope this helps.
Edit: You can also do this completely using VBA by using some clever combination of the OnTime functionality (see http://www.cpearson.com/excel/OnTime.aspx) and combining it with DDE driven from a separate spreadsheet (look up Tushar Mehta DDE clock, a very old example, but some things never change!)

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.

VB.net text -> Excel conversion (with extensive formatting required after conversion)

I'm creating a program in VB.net that does the following:
At a high level I receive a file in email, put the attachment in a monitored folder, import the text file to excel, format the excel, and then email the excel file to a list of recipients.
Here is my plan:
Completed: Outlook VBA to monitor all incoming email for specific message. Once message is received drop attached .txt file in a specific network folder.
Completed: (VB.net) Monitor folder, when text file is added begin processing
Not Complete: (VB.net) Import text file to Excel
Not Complete: (VB.net) Format Excel Text file. (add in a row of data, format column headers with color/size, add some blank columns, add data validation to some of the blank columns that allow drop down selections)
Completed: (VB.net) Save file.
Completed: (VB.net) Send file to list of recipients.
Obviously the items above that are not complete are the bulk of the work, but I wanted to get some advice on what some of you think would be the best way to approach something like this. The import and formatting of the file are causing me some problems because I just can't decide what would be the most efficient way to do this.
What I've thought of so far:
The way stated above. Import to excel -> format
Having a template excel that contains all of the formatting already done for me and attempting to transition the data to this document (no clue if/how I can do this). Is it even feasible? Have the template already created and then import the text file to a new excel file, then transition that data to the excel template?
Something I thought about, in terms of formatting the document, was to record a macro of me doing all of the formatting that I'm going to need and then attempt to convert that macro into my vb.net code, but I'm not sure if that will work. I will need to verify that the text file comes in the EXACT format every time correct?
I really appreciate any advice/suggestions that anyone is willing to give.
You will want to use http://epplus.codeplex.com/
It allows you to create an Excel file from scratch, without having to start Excel itself. Automating Excel will make the process slow and it lacks robustness (Excel process can hang or not close properly).
In addition, using a .Net library allows you to run it on a server or so where no Excel is installed. (Next step would be to inspect the mailbox via POP, IMAP or the Exchange API, so that part doesn't have to be run on a client machine either)
http://msdn.microsoft.com/en-us/library/kh3965hw(v=vs.100).aspx
You can also just use the Interops from MS to interact with Excel, Outlook, Word, etc. They're not difficult at all to use. I'm not familiar with CodePlex, so that may be a better route or an easier one. I just wanted to provide you with an alternative.
With Microsoft Office 2010 Interops you can not generate Office files from .net applications anymore.
You can manipulate data from existing Excel files so you need templates(your 4th point). Then Excel allows you to query some databases. You may be able to simulate one with your folder, otherwise I suggest to convert your .txt files into some databases. (3rd point)
If you do use an older version, you can crate your Excel files by loading them into an instance of Excel and manipulating them as you wish.
By the way I supposed your attached files would have some sort of format.
If you want to manipulate Excel files, I can recommand you the NPOI library found on CodePlex. It has several advantages over OLE-automation:
NPOI is not dependent on a specific Excel version.
Excel (or any other Office component) need not to be installed.
It is faster.
It works with both .XLS and .XLSX files.
We are using a third party software called excel writer. May not be what you are looking for becauseit needs to be license, but it is very fast and the clients does not have to wait for a chart or a data output. Because we have that tool, have not try anything else.

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.