Custom Building Block Template wont load reliably - vba

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.

Related

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...

TIBCO Global variables, reverse engineering

I'm currently working on a project were am at the stage of figuring out what the current implementation is doing. Have been putting in a lot of time (A LOT) searching connections between queues declared as global variables.
Is there a way to get a listing of were a specific global variable is being used, or do I actually need to go through all processes, as I´m doing atm?
Thank you :)
in Tibco Designer 5.8 you can find where global variable is used using "Tools->Find Global Variable usages" menu item.
Please note that all tibco processes source code are text files. So, you also can search inside project folder using file text search from any utility that allowing you to search inside text files. For windows I prefer Far Manager
In the "Far manager" you can navigate to project folder then ALt+F7 and search for
%%GLOBAL_VARIABLE_NAME%%
Please also note that even if you don't have tibco project source code you can get it from tibco BW server. example path
tibco\tra\domain\tibco\datafiles\YOUR_PROJECT_NAME

Changing the location of an existing VBA Reference from C:\Windows\system32\ to a shared drive

I've been trying for a while now to get a reference file to be loaded externally to no avail.
To be specific I am trying to load a "Microsoft Date and Time Picker Control 6.0(SP4)" which usually resides in C:\Windows\System32\MSCOMCT2.OCX
However some people that run a macro containing this element don't have that "MSCOMCT2.OCX" file on their PCs so I thought I will move the MSCOMCT2.OCX to a shared location and reference the code to use the shared one instead (so everyone will have access to it)
I tried doing that but when I was trying to load a reference with "Browse" from a different location it didn't load it - because I already had that in C:..
So I thought OK... I will remove the file from C:\ so I can only reference the shared file. - so I deleted it.
So I open the workbook again and look at references - I cant find "Microsotft Windows Common Controls-2.6.0(SP4)" - great!
And I proceed to add it manually with Browse from the shared drive.
When I do that however 2 references of "Microsotft Windows Common Controls-2.6.0(SP4)" are being added - 1 from C:\(which is not there) and 1 from the shared drive.
The one from C:\ is always automatically selected.
If I try to disable the one from C:\ and enable the one from the shared drive it automatically changes back to what it was when i press OK.
If I try to enable both - it says duplicate References and keeps only the one from C:\
So.. does anybody know how can I get rid of that C:\ reference from the list so it doesn't get loaded? Apparently deleting the files themselves did not work.
Ultimately my goal is to enable people without C:\Windows\System32\MSCOMCT2.OCX file to be able to use my Date Picker Tool.
Thanks a lot!
ActiveX control rereferences are always GUID-based. The VB IDE shows you the current location of the file as listed in the registry on your computer, as a courtesy, but it really doesn't matter what it says. The control will be loaded from wherever it was registered on the user's computer.
That's the key: the control must be registered on the user's computer.
I must strongly discourage you from doing what you're trying to do. You might be able to concoct a method by which you load the DLL from a network location, but it presents no advantage over doing the Right Thing(TM), and plenty of problems. The Right Thing is simply that if you need that control, you must distribute and register it with your application, just like everybody else does. And you really should install it in the recommended location for it (System32); not on the network.
Here's a quick example of what can go wrong: you provide your user with you app, and it works with the control on the network like you want it. Then the user installs another application that happens to need the same control. The app's installer sees that the control is already registered on the user's computer, so it doesn't try to add it again. Except that this particular app is intended to be used when the user is not connected to a network. Now you just broke someone else's program.
The VB/VBA architecture was never intended to support XCOPY deployment. I'm know it's a pain and that these extra steps are extremely inconvenient when you're just trying to deploy a "macro". Sadly, it's the nature of the beast. I'm sorry

VbaProject.OTM deployment

I came by this page and was thinking about the best method to distribute my VbaProject.OTM file (located into %appdata%\Microsoft\Outlook\) to a bunch of ~30 users at my office. Is it better to simply copy/paste the OTM file onto the network and then copy/paste it back to all users' computers (manually or with a .bat) OR would it be better to use the method described in the link above to generate a OPS file and import it back with Proflwiz.exe? What's the difference?
We are all on Microsoft Office Outlook 2003 actually, we might upgrade to 2007 one day but still years from now.
Finally came up with some elements to deploy a Outlook VBA Project. There are a lot of ways to do this, but the easiest way to do so without installing anything and keeping the same methodology would be to run a OTM file directly from a server. I found out that the process outlook.exe has a parameter altvba that allows to specify another path to run the OTM file from. Here is en example:
outlook.exe /altvba "\\myServer\myFolder\myFile.otm"
This allows me to update only one file to get all computers updated. Obviously, if the file is big and the server's ping is on the high side, it may delay the launch of Outlook. The other problem with this method is that everybody will have to shut down Office if you want to update the OTM file on the server (and if you do work in an office where everyone uses Outlook, you do know that it is impossible to get everyone to shut it down at the same time, except if you code a macro to do so eventually). To prevent both those problems, I could setup a batch file to copy the server OTM file clientside everytime there is a new version (just have to check the NTFS last-modify attribute). This way, Outlook will boot with a local file, the batch file take 2-3 seconds to copy the file if needed (or will launch Outlook instantaneously) and there will be no problem updating the OTM file on the server. Users will have to start Outlook with the batch file (or with the slightly different outlook.exe path with the altvba parameter, so either way they need a different shortcut/file to start off the first time). One other advantage of the altvba is that it's still easy for the user to run Outlook without it (to see if the VBA is problematic or not in case Outlook is sluggish) and the file will remain unchanged after a Outlook reinitialization.
Others solutions include a COM complement that can be developed in a lot on languages including VB6 (no conversion needed from VBA). There is also a bunch of tools included into Microsoft Office XP Developer that could help getting the job done (not free however, especially if you need the most up-to-date version).

SP2010 Client Object Model: Uploading File to Drop Off Library Doesn't Apply Content Organizer Rules

I am currently developing a service using the SharePoint 2010 Client Object Model to programmatically upload Excel worksheets to a Drop Off Library and then set the properties on the file. This process is working well. However, the Drop Off Library is governed by Content Organizer Rules that aren't being applied to the uploaded file. I have examined every property I thought I could have missed:
ContentTypeId is being properly set
_ModerationStatus is being set to 0
The two properties required to invoke the rule are being set to valid values
Update is being called on the ListItem
The file is checked in after the ListItem is updated
The list doesn't have minor versioning enabled so I don't make any calls to publish.
What's most frustrating is that if I edit the document properties using the Web UI and check it back in without making any changes, the file is moved to its final location. What might I have overlooked that is preventing Content Organizer Rules from being applied to newly uploaded files when using SP2010 COM?
The ultimate answer to this question turned out to be that everything was indeed being set correctly. However, one cannot force the evaluation of content management rules programmatically. The information I required was provided by a post from Steve Curran on this MSDN thread.
In SharePoint 2010 Central Administration under the "Monitoring" section there is a control panel for "Timer Jobs" that includes an item to "Review job definitions." On this panel, there should be a job named "Content Organizer Processing." This is a nightly task that will run and clean up content according to the rules you have established in your site. After uploading a file to the drop off library programmatically, you will likely find that hitting the "Run Now" button for this job will cause the file to be moved to its final destination if the properties are set correctly.
The solution was to change the frequency of this job under the Recurring Schedule section from a nightly process to one that is executed every 15 minutes (or whatever interval you determine will work best).
A word of caution: Be certain to note that if you send automated e-mail to the site administrator or a mailing list when files are left in the drop off library that do not have their properties set correctly, these will start arriving with the same frequency as the job's execution.
This article may help.
Basically, it does not appear to be supported in the 2010 COM so you have to work around it, unfortunately.