Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Wanet Telecoms Ltd on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Userform variables available in other userform

Status
Not open for further replies.

Berlie

Programmer
Dec 7, 2004
10
US
I am very new to VBA and am working on my first Word template that has a few different userforms.

How do you make a variable defined in a userform be able to be referenced in the code of another userform?

Example:

First UserForm allows the user to select Option1 or Option2. If they select Option2 Then Option1 is set as False and Option2 as True when they hit the Finish button on the first UserForm.

They then can open a new UserForm. This new UserForm needs to have If Then statement checking the value of Option1 and Option2 that was defined in the first UserForm.

This is probably very basic stuff but I can't find a reference to it in my new VBA book.

Thanks in advance for any help or a point in the right direction on where to find the answer.
 
Move the definitions to a separate Code Module as global public variables and then they can be referenced from anywhere
[tt]
Option Explicit
Public Option1 as integer
Public Option2 as integer
[/tt]
(By putting the definitions before any Sub or Function declarations, they are interpreted as global by the compiler.)

 
Look up "Scope" in VBA Help. It explains why Zathras states to put them in a Code Module. Variables in a Form Module are not available outside the scope of THAT form, even if they are declared Public.

Gerry
 
Thanks for the help. Reading more about this now.

PS.. Any recommendations for a VBA book that is a step up from a beginners guide? Think I may be moving beyond what is covered in my "Absolute Beginners" book.
 
I think I have figured this out.

I am trying this with a simple form to try to get it to work before I incorporate it into my real one.

Here is what I have so far. Can you let me know if this looks correct or if maybe I am not doing something right or could be doing it another better or easier way?

In my Code Module:
------------------

Option Explicit

Public strAuthor As String
Public strChapter As String
Public optAuthor As Boolean
Public optChapter As Boolean

------------------

On my First UserForm I have two TextBoxes. One for the author's name named "AuthorName" and one for the chapter title named "ChapterTitle". I then have two Option Buttons, one that you select to display author named "optAuthor" and the other to display chapter title named "optChapter". Then I have an command button named "cmdOK".

The code on that userform looks like:

-------------------

Private Sub cmdOK_Click()
Dim AuthorName
Dim ChapterTitle

strAuthor = UserForm1.AuthorName.Value
strChapter = UserForm1.ChapterTitle.Value

If optAuthor = True Then
Selection.TypeText Text:=strAuthor
Else
Selection.TypeText Text:=strChapter
End If

Unload Me

End Sub

-------------------

On my second User Form I have a TextBox to enter in a new chapter title named "NewChapterTitle" and a commandbutton named "cmdOk" This form should check if the user selected the Display Author or Display Chapter option button in the first UserForm. If they selected display author then the author's name is written to the document. If they selected display chapter then the new chapter title they entered on this form is written to the document.

The code on that UserForm looks like:

---

Private Sub cmdOK_Click()

strChapter = UserForm2.NewChapterTitle.Value

If optAuthor = True Then
Selection.TypeText Text:=strAuthor
Else
Selection.TypeText Text:=strChapter
End If


Unload Me

End Sub

--------



 
#1 - why use two UserForms? You certainly do not need to do so. Is there some reason for using two?

#2 - according to what your code DOES, your Public variable are totally unneeded.

#3 - you have code:

Code:
Dim AuthorName 
   strAuthor = UserForm1.AuthorName.Value
   If optAuthor = True Then
      Selection.TypeText Text:=strAuthor

a) the Dim declares AuthorName as a Variant as it is not specified. If a Variant is not needed, always declares your data type

b) you do not need a variable for your instruction.
Code:
If optAuthor = True Then
  Selection.TypeText Text:=UserForm1.AuthorName.Value

is quite valid.

more importantly is
#4 !!!! What are you trying to do??? You have option buttons the result of which seem to type text into the document. At initial reading what is the differene to this, and the user...typing in text into the document? What is your intention. Also, textbox are for user input...does this mean the user is entering in author name and the form simply wries that into the document?

What are you trying to do? Oh and one way to have this all on one for is to use a MultiPage on the form.

Gerry
 
The end result is to provide a easier way to create a book document.

I am creating a word template that when a new document is created based on that template it opens up a userform which asks the user to enter in the Book title, author name, copyright year, page size, fonts to use for different styles etc. One of the things they select is if they want the left header of the book to display the author name or the current chapter title. The first user form only has the text field for the first chapter title and text. When they have all the basic info and first chapter title and text filled out they hit ok. The book is created and formatted depending on the values and options they entered.

That is the first userform.

The second userform will be tied to a menu item that they will use when they want to add a new chapter. The second userform will pop up and ask them to input the chapter title and the chapter text. The user form needs to know what they wanted to display in the left header area of the book (author name or current chapter name) which they selected in the first userform. Depending on what they selected determines what header information the new userform inputs into the new chapter that is created in the document when they submit the second userform.

The code I put in as an example is what I am doing to get the hang of how to make this work. It is not the complete userform for the book template that I am doing.

I am very new to programing and VBA, this is the first VBA I have attempted to write.
 
Well Berle...you are certainly ambitious in what you want to do. No offence intended, but you listed yourself as a Programmmer. If you are "very new to programming" that may not be an apt description.

I have built such a beast, for exactly the same purposes. It can definitely be done. However, it is not exactly trivial, not hard core, but not trivial. You are going to have to learn some things about how Word deals with headers...for sure.

Some other points. "fonts to use for different styles" Huh? Asking users to set a font for style is backwards. YOU, as the template creator MAKE styles. Users USE styles. They should not manually alter them. You create the styles in the template and inform the user of them, and let them choose - if that is what you want.

Do you want to allow the user to CHANGE the way headers are set up for a new chapter? Say Chapter 1 has Author on the left page. Are you going to allow them to put Chapter 2 with the Author on the right? Maybe Chapter 3 back to left?

If not (and I suggest that this be the case), then you do not need to know the variables input into the first userform. In fact you could not anyway. Once a UserForm is unloaded, any variables declared and set in that form are destroyed with the form. They are not persistent - unless you set them into Document variables. So, if the header structure (Author on left, Chapter on right - or the other way...does not matter) are to be the SAME in following chapters, what you need to to pick up that structure from Chapter 1. This can be done by code.

That way, sure you could use a second userform when they want to make a new chapter. But really, it does not need to be a form. An InputBox asking for Chapter title is all you need. The code behind that can extract the header structure, increment a counter so it knows this is Chapter(previous number + 1), and the title is InputBox.

But one last comment.
The second userform will pop up and ask them to input the chapter title and the chapter text

Your form is going to ask for "chapter text"???? Are you serious? Your form is going to ask them to type in the entire text of the chapter? Title? Sure. Of course. Chapter text? You can't be serious.

Gerry
 
Well I wasn't sure what to select besides "programmer".

I actually have the entire thing working already except for that one part. I have the userform with multipages on it where the user makes all of their choices and enters their info. Right now the first form works fine, its the second Add New Chapter form that is giving me trouble, and just with inserting the New chapter title into the heading section IF they selected Chapter Title on left in the first form.

Also I have styles in the template set up for Book Title, Chapter title and Chapter text. Since I dont know what fonts the user will have on their computer I have it so they can select a font for each of the different styles I created then apply them to that style. I have a listbox in first userform that checks for the users installed fonts and then adds them to the list box array. Sure they could do this themselves after the document is created but the average user who the template is geared towards doesn't know how to do that.

They wont be able to change the left header choice after they make their choice in the first userform. If they select author on left then all sections (chapters) will show the author on the left. However if they choose chapters then each section (chapter) will need to show that chapters title in the left heading for that section. When they add a new chapter I need to check to see if they wanted the chapter title in the left header. If so I need to take the new chapter title and go into the header for the new section, unlink it from previous section and add the newchapter title. If they selected author name for left header then when the new section is added for the chapter I wont have to change anything since it will just pick it up from the previous section.

PS.. as far as inserting the chapter.. I have a text box for them to enter in a "placeholder" for the chapter. I suggest they enter in the first paragraph of the chapter then add the rest directly into word.
 
I strongly suggest that you act upon each section independently. Do not do any linking.

Actually, your basic design strategy is fairly sound. You seem to make a distinction between if they choose Author or Chapter for left.
If they select author on left then all sections (chapters) will show the author on the left. However if they choose chapters then each section (chapter) will need to show that chapters title in the left heading for that section.{/quote]
Actually, there is no distinction. The actual TEXT of the chapter will be different, but the structure remains the same.

I think you could do better by the following:

When the document is created from the template, display the document properties dialog. If you really want to, you could still do this with a custom useform. In any case, this is pertinent to you wanting to pick up variable information to reuse. Word has document properties such as Author, Title etc. You can get the user information and store them there. Then whenever you want them, simply use a field that pulls that document property.

You can also create Document variables that ARE persistent. Say, get you user input on chapter title. create a document variable named Chapter2" - remember this is the variable name, not its value. Then set the value to be the text of the chapter.

Gerry
 
Hey it looks like I got everything working now. I struggled with the code for the stupid "LinkToPrevious" property for the headers with the add new chapter userform. If I had to unlink the header from the previous one to have it replace the previous chapter title in the header with the new chapter title it didn't want to do it. I had to be very careful with the order in which the code did everything to get it to do it properly. But after pulling out most of my hair it now works.

The code for the whole project probably could be cleaned up some but I am rather proud to have done this whole thing after only picking up my first VBA book a week ago.

I considered using the document variables but it seems that I would still need to check to see if the new chapter headers should be linked to the previous ones or if I needed to unlink them and insert the new chapter title instead.

Anyways.. think I will go play some CoH now to relax and look at this some more tomorrow.

Thanks for all the help, this is a great forum and I am glad I found it.

Kimberlie
 
Just had a thought. Wonder if there is someway to unlink all the headers in all future sections from their previous headers within the first userform if the Chapter Title is selected for the left header. If I could set the header properties before they are created that would make it easier.
 
For the creation of new section headers, Word defaults to Same As Previous. I do not, as yet, know of a way to remove or change this so FUTURE creation will not defualt. However, you can write a Sub to make new sections that in effect explicitly does this. This is what I do for making new sections. I have code make the section, and automatically make it NOT "Same as previous.". Something like:
Code:
Sub MakeNewChapter()
Dim strCurHeaderPrimary As String
Dim strCurHeaderEven As String
Dim strAuthor As String
Dim var, var2
' this runs BEFORE making the new section break
' pick up Author DocProperty
' pick up CURRENT Odd header text
    strAuthor = ActiveDocument.BuiltInDocumentProperties("Author")
    strCurHeaderPrimary = Selection.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text
' first go to end of current section
' make new section starting with Odd page
' this can be whatever, continue structure
var2 = Selection.EndOf(unit:=wdSection, Extend:=wdExtend)
    Selection.InsertBreak Type:=wdSectionBreakOddPage
    With Selection.PageSetup
        .SectionStart = wdSectionOddPage
        .OddAndEvenPagesHeaderFooter = True
        .DifferentFirstPageHeaderFooter = False
    End With
' check DocProperty Author is in the now previous
' section header text; if it is, then want to repeat it
   var = InStr(1, strCurHeaderPrimary, strAuthor, vbTextCompare)
   If var = 1 Then
        '  current primary (odd) header IS author
        '  even though the same, break link anyway
        '  and insert Author again
        With Selection.Sections(1).Headers(wdHeaderFooterPrimary)
            .LinkToPrevious = False
            .Range.Fields.Add _
                Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
                "DOCPROPERTY  Author ", PreserveFormatting:=True
        End With
    Else
        ' current primary (odd) header is NOT author
        ' create new doc Variable and give value from inputbox
        ' then strip off the last charcter of previous header
        ' as it is the chapter number, and increment
        ActiveDocument.Variables.Add Name:="Chapter2", _
            Value:=InputBox("Chapter 2 Title?")
        strCurHeaderPrimary = "Chapter" & (Right(strCurHeaderPrimary, 1) + 1)
        Selection.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
            strCurHeaderPrimary
    End If
End Sub

Note that the above makes use of explicitly instructions for the header objects of the section.

ALL sections have THREE headers, regardless of how you have configured the section.

Even if you do not have "different odd/even" or "Different first page", Word ALWAYS as three headers.

wdHeaderFooterPrimary
wdHeaderFooterFirstPage
wdHeaderFooterEven

There is NO Odd page Header. There is HeaderFooterPrimary, Ifthere is NO different odd/even, then Primary is the header for all headers in that section. If there IS Different Odd/Even, then Primary becomes the header for odd pages, Even becomes the header for even pages. If Different Odd/Even not set, you can set primary anywhere. Once Different Odd/Even is True, you can only change primary from an odd page. Note you change Different Odd/Even from True to False, the entry for it REMAINS.

In any case, the code above picks up logic from the previous section first, makes a new section and explicitly makes LinkToPrevious = False.

And congratulations on putting in some work that satisfied you.

Gerry
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top