PDA

View Full Version : Create controls at runtime



whytedawg
11-13-2007, 05:20 AM
Hi everyone

I'm currently working on a VBA program in word 2003 that requires me to be able to dynamically create multiple edit boxes. I though the solution had came when I read about control arrays...but for some reason they aren't included in VBA :( I guess it is an expression version of VB...

Anyway, heres what I'm aiming the program to do:

Basically i have a table of editboxes, when clicking a button ads a new row and clicking another removes a row. There are 4 columns. When you click on the editbox, the current selection in word becomes the content of the edit box (if u have a checkbox somewhere else in the dialog checked).

It sounds like a stupid program, but it's something that will save me lots of time if I get it working :)

I have a modeless dialog setup (it took me forever to work that out...and all i had to call was myform.show(false) :banghead: and everything else worked out...I just need a way to add controls when I click a button. Can anyone suggest a function or perhaps tutorial ?

Thanks

whytedawg
11-13-2007, 05:47 AM
Woops found an answer

Set Obj = Me.Controls.Add("Forms.TextBox.1")

Adds a new text box for me. There seems to be a addhandler function so I'm gonna experiment with that.

Heh...any easy way to copy over all the properties of one control to another :( ?

whytedawg
11-13-2007, 07:58 AM
Okay incase other people are trying to do the same thing, a useful site was this one:
(WWW dot )dbforums.com/showthread.php?t=803898 (my status is too noobish to post urls)

The last post on that page shows a good method for overwriting the button class so you can control the handles. I found adding a public integer called index to the class allows you to distinguish the controls better, although you still have easy access to the name, co-ordinates, etc.

Sorry I couldn't have worked this stuff out before i posted :(

blue_bogdan
11-13-2007, 08:03 AM
Woops found an answer

Set Obj = Me.Controls.Add("Forms.TextBox.1")

Adds a new text box for me. There seems to be a addhandler function so I'm gonna experiment with that.

Heh...any easy way to copy over all the properties of one control to another :( ?
Well you could use this...

For i = 1 To Per
Set Ctrl_Yr = frm_fin.mp_fin.Pages(2).Controls.Add("Forms.Label.1")
With Ctrl_Yr
.Left = 6
.Width = 48
.Top = 30 * i
.Height = 18
.Caption = "Year " & CStr(i)
.name = "lbl_yr_" & CStr(i)
End With
Next
and it might do the trick...

Have fun.

whytedawg
11-14-2007, 03:17 AM
I'll briefly discribe the solution incase someone else wishes to do something similar.

1. Create a new class module that will wrap up the control (or controls) you wish to use. Heres the code I used:

Public WithEvents TextBoxGroup As TextBox

Private Sub TextBoxGroup_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
TextBoxGroup.Text = Selection.Text
End Sub

explaination:


Public WithEvents TextBoxGroup As TextBox

This is your member in your class which holds the control. In this case, a TextBox. TextBoxGroup is what I called my variable, it can be any name.



Private Sub TextBoxGroup_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)

This is pretty much your normal handle. If you insert a textbox on your forum and add a 'on mouse clicked' handle you will get something identical to the above. The start of the function name must be the name of your variable.

2.
If you wish to create a textbox at runtime, all you need to do is declare the control outside of the functions ( i just had it in the top of the file containing the code of the form)


Dim MyTextBox as New Class1
And then in the function which creates the control (such as a button being clicked) you can use

Set MyTextBox.TextBoxGroup = Me.Controls.Add("Forms.TextBox.1")

And now your control is nicely wrapped in a class module.

If you wish to have a dynamic number of that control, for example, an edit box for every user in a username list, simply declare your Class1 variable as an array:


Dim Usernames() As New Class1

And presuming you maintain the number of those usernames in a variable called Count, you could dim the array of usernames to the right size:

ReDim Preserve Usernames(1 To Count)

And then you could loop through all your user names and call:
Set Usernames(i).TextBoxGroup = Me.Controls.Add("Forms.TextBox.1")

As each of your text boxes has their own class, you can store extra data with the controls that could help you better with maintaining the multiple textboxes (such as the index in the array)

fumei
11-14-2007, 12:56 PM
I am confused. I am not sure if you are talking about textboxes on a userform, or textboxes in a document.

blue_bogdan
11-15-2007, 12:41 AM
I am confused. I am not sure if you are talking about textboxes on a userform, or textboxes in a document.

well my method intoduces textboxes in userform, but i believe it can be adapted as to insert them into documents.

whytedawg
11-15-2007, 03:09 AM
Oh sorry, I didn't realise until just now that you could add buttons and controls onto word.....thats crazy...

In my posts I have been refering to userforms, not forms in the word document itself. Sorry about that :(

fumei
11-15-2007, 07:58 AM
While true it is possible to create controls at run-time, I for some reason dislike doing that, from a design point of view.

I use Multi-Pages, plus the .Visible properties to make things appear, or not.

blue_bogdan
11-15-2007, 08:13 AM
While true it is possible to create controls at run-time, I for some reason dislike doing that, from a design point of view.

I use Multi-Pages, plus the .Visible properties to make things appear, or not.

I tend to agree but if the programer has to design more that 10 controls or let's just say he does not realy know how many controls are required i belive that creating them at run-time might be the best option he has.

I for example have to create a number of controls based on a number that the user inputs in a previous form and the requirements were not to cap that number.

fumei
11-15-2007, 12:51 PM
Oh I am not arguing that there can be NO requirement for run-time created controls. I am simply stating that I have seen very few situations where that is the case.

"I tend to agree but if the programer has to design more that 10 controls or let's just say he does not realy know how many controls are required i belive that creating them at run-time might be the best option he has."

I disagree.

1. I have often made userforms with more than 10 controls. I have made userforms with 40 controls...on MultiPages, on userforms that resize themselves in conjunction with the visibility (or not) of required controls.

2. Again, I have no issue with the idea that it is possible that a designer may not know how many controls are needed. I just have great doubt that this is really true, from a design POV. A designer that is faced with not knowing how many controls are needed, should perhaps reconsider the design.

I saw an example where a developer had a combobox with six items in it. Depending on the selected value, one of six different other controls became visible. Total controls: 7 (two visible)

Redone: combobox with six items, depending on the selected item, ONE control configured in response. Total controls: 2 (two visible)

This was a design issue, not a technical one. Again, I am not arguing that there is never a need for dynamically created controls. I am arguing that I have rarely seen a real need for it, and that dynamically used controls, for the most part, fulfill requirements.

blue_bogdan
11-16-2007, 12:17 AM
You might be right and i have a design issue.
Well the problem is as follows: my user inputs a number in a text box, a number that is not known in the design phase. Based on that number the program must generate two series of text boxes that the user will fill. These later values will go in another function...
Any ideas???

And maybe if the creator of this thread is satisfied with this the responses he could close this thread and the admin might move this part of the discusion to a relevant place... like a design issue thread.

Thank you.

whytedawg
11-16-2007, 03:47 AM
OMG I cant believe you guys are arguing over this. I thought this was a forum about programming, not youtube ;)

The macro I am working on requires an undefined number of textboxes as each textbox represents a property and I have no idea how many there are. There probably wouldn't be more than 40, but coding 'on clicked' for 40 text boxes to perform the same function is a bit excessive, even if u can simply list the names of all the boxes at the declaration of the function.

Anyway, I found a solution by searching around in the forum, and i shared it with u guys coz i hate it when people on the forum say 'how do u do x ? oh wait, i worked it out! k thankx!'

So...how do i close a thread :P ?

fumei
11-16-2007, 08:05 AM
Thank you for posting something when you found an answer. That is indeed the polite thing to do.

You can not "close" the thread. You can make it "Solved" though.

The macro I am working on requires an undefined number of textboxes as each textbox represents a property and I have no idea how many there are. I do not understand that.

"property"? You mean a control property? Property of what?

OMG I cant believe you guys are arguing over this. I thought this was a forum about programming, not youtube We are not really arguing, we are discussing, and it most certainly IS about programming.

I have a question.

Textboxes are for user input, not for displaying text. Labels are for displaying text. So if the result of the user selecting something from a combobox, is to display information, then labels should be used, not textboxes.

Say one of these "properties" is yaddayadda. You are putting, I assume, yaddayadda into one of these run-time created textboxes. Will the user actually change the text (yaddayadda)? If they are not, then a textbox is pointless.

For my own curiosity, and if you can do so, could you post an example?

lucas
11-16-2007, 08:22 AM
http://www.vbaexpress.com/forum/showthread.php?t=11177