PDA

View Full Version : Solved: Recommended method for distributing global variables among projects



mansky
01-27-2006, 09:23 AM
Hi all,
I have a number of different template projects that I want to distribute some global data to. I have one template project that reads some data in from 4 flat files and puts that data into a custom User-defined data type (using the Type/End Type statements). The custom data type is really simple:


Public Type ERI_hashes
CjourHash(1 To 3, 1 To 2) As Variant
VMHash(1 To 3, 1 To 2) As Variant
WebCopyHash(1 To 3, 1 To 2) As Variant
XrefHash(1 To 3, 1 To 2) As Variant
End Type


I'd like this data type to then be available to other template projects. In reading the help files, and "Programming Microsoft VB 6.0" by Francesco Balena, using User-defined custom data types seems to be the preferred method for storing global data. The data thus stored is easily called from other modules within a given project. However, I'm getting stuck on passing a reference to this type declaration onto other projects. I'm trying to avoid duplicating the code to read in from the flat files in every project that needs that data. I would hope to take advantage of some code reuseability via passing references to global variables to other projects as needed.

I thought that by using the OrganizerCopy method I could get a reference to the above type passed along. Here's a code snippet:


'Copy ERI_hashes type to Xref.dot template so that it is available to Xref documents
TargetTemplate = TargetPath & "Xref.dot"

Application.OrganizerCopy Source:=SourceTemplate, Destination:=TargetTemplate, _
Name:="ERI_hashes", Object:=wdOrganizerObjectProjectItems


where the string variables SourceTemplate and TargetTemplate have already been defined.

However, when I place my User-defined type in the declarations section of the same module as the above OrganizerCopy statement, the templateproject compiles fine, but Word complains when re-started, about "Object required" which I take to mean that the reference to the data type couldn't be found at runtime since it's in the declaration section and not the body of the macro. When I place the type declaration in it's own module, I can't get the templateproject then to even compile.http://vbaexpress.com/forum/images/smilies/sad2.gif

What's the recommended method of passing, or distributing, references to global variable to other projects in Word (or Excel)?

In particular, I am using Word 10.1.6 in Office 10.1.6 on a Mac 10.2.8 platform using VBA 6.0 (I think).

Any advice for either Windows, or Mac, platforms would be greatly appreciated!


Ed

XLGibbs
01-27-2006, 08:26 PM
Hmmm. I think there is a difference between the need to pass global variables through a user defined data type, and passing the user defined data type through all projects...

I am not sure you can pass a user defined data type through as a global variable. However, a static data point that occurs in a public module can be effectively read from anywhere....however, this is different...

Passing the public type is different than passing a global variable. A global variable would remain constant accross all applications within the scope of the project....

You may explore the possibility of using a Class module for code re-useability, in which each New instance of the class would be able to capture data as identified witih the class module.....You could get your variable data using the class to handle certain actions...I apologzie I do not have samples avaialble to show you what I mean...., I believe the Data type is to handle certain other functionality throughout the project, meaning values must be calculated using them in the same way for each project.

In short, the best way to code re-useability is by handling recurring events in the class module...(I am making a leap here that you need to pass the type because each part of your project is running a similar routine which uses the Type...if so Class is the way to go with it...)

Of course, if each of these templaters are housed in different applications, and NOT contained within the scope of a Visual Studio (C++. Visual Basic, foxpro etc) level project, you will not be able to pass the user type accross different applications without supplying the declared type into each template file.

TonyJollans
01-28-2006, 05:14 AM
In order to reference items in another project you must set up a reference to the other project under Tools > References. If you do that then anything within that project is available to you, so ...



Put your Type definition in, say, ProjectA (the Project in TemplateA will need to have a unique name)
Set a reference in ProjectB to ProjectA
In ProjectB you will then be able to use Dim myVar as ProjectA.myType
Note that whenever TemplateA is opened, Word will also open TemplateB automatically (if it can) to satisfy the reference

mansky
01-29-2006, 09:12 AM
Hi Tony and Gibbs,
It always helps to read the manual! In re-reading the help entry, I realized I wasn't creating an instance of my Type in the macro correctly. Once I did create the instance correctly, I was able to compile the TemplateProject fine.

Now I'm stuck on getting the reference to the first TemplateProject into the second TemplateProject.

Here's the code snippet from TemplateProjectA that compiles correctly now:


Public Type ERI_hashes
CjourHash(1 To 3, 1 To 2) As Variant
VMHash(1 To 3, 1 To 2) As Variant
WebCopyHash(1 To 3, 1 To 2) As Variant
XrefHash(1 To 3, 1 To 2) As Variant
End Type
Sub AutoExec()
'...other Dim statements omitted for clarity
Dim MyHashes As ERI_hashes

'body of subroutine that defines MyHashes
End Sub


Now, when I have the VBE open to the Document_New() macro of TemplateProjectB where I want to reference the MyHashes type, I go to "Tools/References" and check the checkbox for TemplateProjectA, I get the error message:
Name conflicts with existing module, project or object library


What is this about ? http://vbaexpress.com/forum/images/smilies/think.gif How might I get more info on these error message from the VBE? Note the hashes in the type are defined in the AutoExec macro of TemplateProjectA. I want to reference these hashes in the Document_New macro of TemplateProjectB. Where is the name conflict since the elements of my Type should be unique, as should my Type's name itself?

Since I couldn't get the VBE to add a reference to TemplateProjectA in TemplateProjectB, I can't get the Dim statement in TemplateProjectB to compile.

Any ideas would be greatly appreciated!


Ed

XLGibbs
01-29-2006, 09:26 AM
I think you need to subsequently declare variables:


Dim Newhash(1 to 3, 1 to 2) as ERI_Hashes


Since the user defined type becomes added to the library of types (as opposed to Variant, string etc)

I have not used UDT's before, but it seems that the ERI_Hashes should also be

Public Type ERI_Hashes
HashName( 1 to 3, 1 to 2) as variant
End Type


Since all the types have the same type and array dimensions.

EDIT:
From the VBA Help upon further examination


Type StateData
CityCode (1 To 100) As Integer ' Declare a static array.
County As String * 30
End Type

Dim Washington(1 To 100) As StateData
In the preceding example, StateData includes the CityCode static array, and the record Washington has the same structure as StateData.

When you declare a fixed-size array within a user-defined type, its dimensions must be declared with numeric literals or constants (javascript:hhobj_31.Click()) rather than variables.




Of course your public type does not appear to be needed, since you would still have to populate the resulting Type with data by declaring it much in the same way.


If the data behind those Hashes, needs to be passed as global variables, this is different than simply declaring a public data type (as it is a Type) and not storing any actual data within its composition.


I may be way off, but I am only on my 3rd cup of coffee.

TonyJollans
01-29-2006, 10:35 AM
The conflict is in project names. You need to have a unique project name to be able to set a reference.

Right click on TemplateProjectA in the Project Explorer and select Properties. Then give the project a unique name. You should then be able to set a reference to it from other projects - you might have to save it first, I can't remember.

XLGibbs
01-29-2006, 10:43 AM
Oh, I misunderstood then, it sounded to me as if the projects did have different names, but i think the issue will remain as to how to use the public data type, which was more the point of my post...

Also, if both projects have similar declarations or like named variables, wouldn't that also caused the name conflict error?

Thanks Tony!

TonyJollans
01-29-2006, 01:10 PM
I could be wrong - I wasn't sure from mansky's post what whether he had named his template projects, but non-unique project names would give that message so I assumed he was just using names in the post to differentiate what were actually identically named projects in his environment.

Names within projects can always be qualified with the project name (which is one reason why project names must be unique) so ProjectA.UDT1 and ProjectB.UDT1 can both be used without conflict.

When all's said and done I would prefer, as you said, to use a Class for this - but it can be done with UDTs.

XLGibbs
01-29-2006, 01:13 PM
I may be way off too, one of those weekends, but I appreciate the clarification on the naming issue....

mansky
01-29-2006, 03:13 PM
Hi Tony and Gibb,
Absolutely correct! I referred to my two TemplateProjects as A and B for the clarity of the post, but under "Tools/TemplateProject Properties..." I had left the default name "TemplateProject" the same for both -even though the actual template .dot filenames for each were different. I didn't realize that I could change that name.

I've now changed all my TemplateProject names to unique ones and now both TemplateProjects compile fine now. Terrific! Thanks guys!! http://vbaexpress.com/forum/images/smilies/clap.gif


And I agree about using a Class versus UDTs. I am still somewhat new to OO-style programming and already have one Class in my project. I thought I'd see if I could transfer data between TemplateProjects via a UDT. Indeed it seems I can do that.

I want to get the code working and stable first. Then later I figure I'll upgrade to using a Class for the global data.


Many thanks!


Ed