How do I create multiple instances of an out of process RTD server? - com

I have an RTD server that I created, and I want a different instance for each workbook as each workbook will use a different API key to access some data. In other words, if I open Workbook1, and it uses Key#1, when I open Workbook2, I don't want it to use the same instance.
I know this probably has something to do with COM, and I have tried changing flags to "multiple instance", and I have tried modifying the singleton pattern, but the root problem seems to be that the instance that is created of the exe is the same.

Related

Alternatives to using the clipboard feature in Automation Anywhere

What are some alternatives to using the clipboard feature in Automation Anywhere? I'm told using the clipboard feature is not ideal for consistency.
You can create a variable instead of using clipboard.
Steps to create variable:
Select the variable manager from the extreme right side of workbench window
click on Add at the bottom of variable manager section
In Add Variable window, provide the details of the variable which needs to be created
You can refer How to create variables in Automation Anywhere Client
That is True. Even if user is not using the system while AA bot is running, some background services might kick in and use clipboard(only id programmer have used it)
Note: Sometimes, depending on situation. Like a secure excel files where if we need to copy data between workbooks/sheets, we are stuck with Ctrl+C and Ctrl+V
Alternatives go as below:
1. For values, use variables instead of clipboard
2. Excel files, use Get Cell and Set Cell also consider connecting to Excel as database
3. File Copy, use the Copy File option
I cannot think of anymore scenarios as of now, but let me know what exactly were you trying to do.
You should use 'Prompt-Assignment' variable for holding temporary values. Use of 'Clipboard' should only be done where a Ctrl+C action needs to be performed however the value should immediately be transferred in 'Prompt-Assignment' or any other variable for holding the values.
You can use other system variables according to the application you are using
For ex:
Excel : Excel Column
CSV/TXT : FileData Column
These system variable will hold the values inside the loop only. you can assign in to some other custom variable and you can use it anywhere.

Best way for Excel workbooks to share VBA functions

I seek advice on how to manage userdefined VBA-functions that are used in several workbooks:
Background:
Over time i have created several Excel workbooks (wbs), each with a slightly different purpose, that are ultimately based on a library of my userdefined functions and class modules (From now on: library). The "master"-versions of the wbs are revision-controlled. The wbs are used by several people.
However, I do not use an addin for the library, and hence the modules and class modules are actually locally present in each wb's specific VBA project. This makes it a nightmare when doing either expansions or corrections, as I have to revisit and implement said alterations in each wb.
Furthermore, in each wb there are unique functions, understood such that those are not intended to be shared. Those functions, however, might utilize the library-functions.
Main-Question: How should one manage vba functions across several workbooks shared by several users?
My considerations/Sub questions:
Should I convert the library to a true addin and discard the local copies in each wb?
How do I tell the users that the add-in is required upon getting a copy of the maser-version?
How does one cope with legacy/local versions/branches that are spread among the users? Both current legacy copys and future legacy copies that might be used for reccuring tasks?
Where should such an addin-in be stored (in a shared folder or something)?
Would it be considered "bad practice" to force load the add-in using the workbook_opensub?
Any advice or guidance in best practice is appreciated.
Edit: I have tried to highlight the main question, please consider the sub questions as my own thoughts on the subject.
Until recently, I had several add-ins that lived on a shared drive. I had the users install the add-in using File - Options - Addins and wrote up the instructions to do it. The copy on the shared drive was read-only. For changes, I would code and test on the dev copy on my machine, then deploy it to the shared drive. The next time the user started Excel, the changes would be there.
Then we wanted more people to have the addins and not all of them had access to this shared drive. Also, people complained when they were off the network that it still tried to connect to the addins. So we went a different route.
We used a program called PDQ Deploy to put the addins in everyone's addins directory, so they had a local copy. We also deployed a script that copied the files from a company-wide shared drive to their addins directory. If they weren't connected to the nextwork, the script would fail silently. Finally, we used group policy to 1) create the registry entries to install the addins and 2) create a scheduled task that kicked off the script every night. Updating every day is overkill, but the files are only a few kbs, so we went with it.
Now I can deploy new versions to the company-wide shared drive and everyone will have the changes the next day (or the day after they're back on the network).
I put my vba stuff on the "personal" workbook (Windows menu : Unhide...) and whatever workbook I am using I can use them from there.
You do have to make sure about knowing which one is acrtive though...

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.

Custom Building Block Template wont load reliably

My small collection of document-specific macros and quickpart building blocks is growing! I'm starting to share these with employees, and am looking to be able to set up each remote computer once only. From there on, update collections on a network path. And because each computer looks to the shared location, everyone should always be working with up to date macros and quickparts etc.
So. What I already know:
- Required macros are saved in a separate module, ready to be shared/exported.
- Macros themselves occasionally reference local paths on my computer.
- I will need to reference paths with generic code or use Environ variables.
- Building blocks and quickparts are saved in a separate template file (currently located in Appdata, along with default building block file).
What I dont know:
a) How to point Word to a network path to retrieve macros from custom macro files. (Would I just have to import a fresh macro file at every important update, on each PC?)
b) What's the best way to load a building block item from a CUSTOM path?
My custom BuildingBlock template file is not loaded properly on occasion:
Dim objTemplate As Template
Dim objBB As BuildingBlock
'set template to store the building block
Set objTemplate = Templates("C:\Users\[USER]\AppData\Roaming\Microsoft_
\Document Building Blocks\1033\CustomBBlocks.dotx")
Set objBB = objTemplate.BuildingBlockEntries.Item("[EntryName]")
I know this because the code spits out a 'CollectionDoesntExist' error unless I click the Quickparts gallery prior to running the code for the first time. So it's like Word cant be bothered to open the template file and look inside unless I do it from the UI first.
Of course, if I first open the Quickparts gallery from the UI, prior to running my code, Word seems to figure it out, and inserts the correct Building Block entry without any issue.
In the past I've worked on a product that allows building blocks for Word too. Some sites have hundreds of templates and maybe 1.000 elements (see Composition). The approach we've taken was successful and was different.
You are trying to deploy software elements (macros) across a large number of workstations. You can try to get it working using the possibilities of Microsoft Word and Windows, but it will be sensitive to problems when things change. For instance, switching to Office 2013, splitting a domain into two, work at home without VPN, etc.
Option 1 - DIY deployment: Better put the macros and other stuff behind a webpage, webservice or alike. Deploy on each workstation a generic program that pulls in everything and deploys it locally. You might want to hand over some parameters to the webpage being called to restrict the amount of data. You might want to cache things locally.
Option 2 - Use ClickOnce: write a clickonce deployment script, include the necessary references and put it on a shared network drive or http address. ClickOnce automagically upgrades your software when it finds a new version. It even works across the internet. And it does nothing when there is no new version.
Option 3 - Database: put the elements centrally in a database, allowing end users to change building blocks through forms. Have Microsoft Word in combination with a ClickOnce program pull them in.
For Composition we've used option 2 and 3.

How to retrieve a list of tableadapters?

BACKGROUND:
Most of my programs use table adapters, and the connection strings are stored in app settings. This works fine, but was a real PITA when switching from development to production environment. I had to change manually the connection strings before and after starting my work on any app.
After a bit of research I found how to switch connection strings for table adapters dynamically. By simply adding a custom property for connectionString, I was able to acheive this. But I still have to add code in the new event for each application so the connection strings get switched when it loads. (My connection strings are kept as an app property setting in a common DLL. I just keep one copy of the DLL with my connection strings locally, and one copy o the DLL with the production connection strings on the production server.)
NEW PROBLEM
I'd like to take this one step further and have either have the datasets change the connection strings for all table adapters they each contain when they load using the new event, or do the same from a VB module. I may have up to 3 datasets at any one time.
I do depend a lot on intellisense to help me determine which methods and properties are available, but I can not find a way to retrieve a list of the table adapters in my datasets. It does not appear that they are a part of any collection of objects as far as I can tell. I've searched a quite bit for a solution, but no luck.
Marshall
You might want to reconfigure the location of the connection strings. Make your presentation layer (i.e. the application) contain the connection string in it's app.config. Now here's the cool part ... any .DLL that is being used by the application can access the application's app.config using the ConfigurationManager.ConnectionStrings("MyConnectionString").ToString function. Your .DLL would call the connection string by name, and the call propagates up to the application's app.config. If you don't want to hard code "MyConnectionString", then you should simply pass the connection string to the .DLL via a property of an object.
If you DON'T want to rearrange the connection string "ownership", simply expose the .DLL's connection string from it's own config file via a static object in the .DLL which the application can read. Assign that to the TableAdapters.
As a side note, if you are already familiar and comfortable with what appears to be your custom DLL's, move all of the data access logic into its own DLL as a Data Access Layer (DAL) - get the data access logic out of the presentation layer!