VBA Force variable affectation by reference - vba

So I encouter some very weird problem in VBA which I believe is a "feature" of the language.
Right now the following code generates an error of type incompatibility:
Sub MyFoo()
Dim txtTest As TextBox
Set txtTest = frmFoo.txtExistingTextBox
End Sub
So I've come to the conclusion that somehow VBA tries to put the string value of frmFoo.txtExistingTextBox.Value in txtTest while I strictly want to get the TextBox control object.
I know that in some languages there is a way to define if you want or not do an affectation by reference instead of value, which would solve the problem here, but I have no idea how.
I know I could simply declare txtTest as Variant but I find this very unclean :-/
Thanks!

Your conclusion is wrong I'm afraid. The mismatch occurs because Excel's object library has a Textbox object, which is not the same as the MSForms textbox used on a userform. You should be using:
Sub MyFoo()
Dim txtTest As MSForms.TextBox
Set txtTest = frmFoo.txtExistingTextBox
End Sub

Set is always by reference. Try to declare the full type:
Private Sub UserForm_Click()
Dim control As MSForms.TextBox
Set control = Me.TextBox1
End Sub
It could also be a compilation issue. In that case, try to modify the module or rename it and run the code again.

Related

VBA How To Set Form In Function

I add Form1.vb in my project but ı couldn't show it. Form1.show or Form1.ShowDialog didn't worked beacuse it type is class.
Here is the error message;
bc30109 'form1' is a class type and cannot be used as an expression
Solution must be some think like that.
Private Sub Form1Func()
Dim f1 As Object
f1 = Form1
f1.ShowDialog
End Sub
Private Sub OnButtonClick(cmd As Commands_e)
Select Case cmd
Case Commands_e.Export_As_SheetMetal
Form1Func()
Case Commands_e.AboutUs
Application.ShowMessageBox("AboutUS")
End Select
End Sub
Without knowing more about other actions in your program, I cannot pinpoint why you're being asked to provide an argument for show (possibly a named function, etc.), but this is a way to ensure a form is called as an object:
Dim obj As Object: Set obj = VBA.UserForms.Add("userform1")
obj.Show vbModeless
Specific to your error, the above code directly generates the userform object through vba.
Private Sub Form1Func()
Dim f1 As New Form1
f1.Show()
End Sub

userform.show problems

I am making a word document to fill out a form upon clicking a button. I have made a basic form so far named 'NewSite' I have then made a button to click to open the form with the code:
Private Sub NewSite_Click()
NewSiteUserForm.Show
End Sub
This then pops up the error 'Object Required'
Any help will be appreciated!
edit**
I have figured it out...
I set the name of the form back to its original name of 'UserForm1' for ease of use. The code:
Private Sub NewSite_Click()
Dim Form As Object
Set Form = UserForm1
Form.Show
End Sub
semed to work.
If you named it NewSite, you will have to declare your variable as an object of that type and the initialize it. Do it like this:
Private Sub NewSite_Click()
Dim NewSiteUserForm As NewSite
Set NewSiteUserForm = New NewSite
NewSiteUserForm.Show
End Sub

Set userform width from a module by looping through userforms

Been having a very frustrating problem that I can't seem to find a solution for anywhere - help would be greatly appreciated!
I know how to change the width of a userform from within the userform itself (Me.Width).
The problem is that I am writing a module that will format userforms dynamically. The module is passed a form and it does some manipulations on that form. So far everything works as long as I'm referring to objects on the form.
But I'm now trying to refer to the form itself, and when I try to change the width (of the form, not of a control on the form) I get the error: "Object doesn't support this property or method".
I've tried declaring it as both a UserForm and an Object and all of the other code works in both cases, but resizing the width doesn't. I can see in the immediate window that width isn't available, which is obviously why the code won't execute.
Here's the code that I've tried without succses:
Sub frmLoadLayoutTest()
frmLoadLayout frmTest
frmTest.Show
End Sub
Private Sub frmLoadLayout(frmActive As Object) 'Also tried (frmActive as UserForm)
'Setting the width of a control works
frmActive.Controls("labelTest").Width = 100
'Setting the width of the form itself doesn't work
frmActive.Width = 100
End Sub
If anyone can provide an elegant solution, that would be fantastic. Alternatively, is there a way I can refer to the userform by name? (Something like Userform(frm1.name).Width = 100)
Thanks in advance!
Try this:
Sub frmLoadLayoutTest()
Dim frm As frmTest
Set frm = New frmTest '<<< create an instance of the form
frmLoadLayout frm '<<< pass in the instance
frm.Show '<<< show the instance
End Sub
Private Sub frmLoadLayout(frm As Object)
With frm
.Controls("labelTest").Width = 100
.Width = 300
End With
End Sub
See also why it's good practice to avoid the "default instance" and create your own explicit instance of a form before using it:
https://rubberduckvba.wordpress.com/2017/10/25/userform1-show/

Create global variables

Bit of a newbie to VBA, sorry
I need to create some variables that are available throughout my workbook, but I can't seem to figure it out. I've read in previous questions where some people have suggested create a separate dim for this?
When the workbook opens I need to set some variables equal to certain cells in a worksheet, these variables need to be called from dims in others worksheets.
So far I have tried to use
Workbook_Open()
In the 'ThisWorkbook' code area but to no avail.
Any tips?
Reagards
EDIT ----
I have tried with the following:
In 'ThisWorkbook'
Public wsDrawings As String
Public Sub Workbook_Open()
wsDrawings = "Hello"
End Sub
And in Sheet1
Private Sub CommandButton1_Click()
MsgBox wsDrawings
End Sub
I do not get an error, but the message box is empty.
Just declare the variables you need wherever they are first used (ThisWorkbook is a fine place to do it) and replace the typical Dim with Public. It will then be accessable in all your code
You can create global variable with code like this
Public testVar As String
you need to place it outside function or sub and then this variable has value till you close workbook. But i think it have scope only in current module.
So you can have something like this
Public testVar As String
Private Sub Workbook_Open()
testVar = "test"
End Sub
Sub testEcho()
MsgBox testVar
End Sub
for shared variable between multiple modules look here
edit:
So now i found, that you can use public variable from ThisWorkbook using this
Sub testSub()
MsgBox ThisWorkbook.wsDrawings
End Sub
you can use module for creating global variable.

Passing text box control to private sub/function

I have a series of text boxes that I want to evaluate on form load to change some other elements of the form. Rather than processing them line by line I want to create a function. How can I pass the name of the text box to a function. For example:
Private Sub Form_Load()
Call SetIntialToggleValue(MyTextboxName)
End Sub
Private Sub SetIntialToggleValue(ByRef ControlName As Control)
MsgBox ControlName.Value
End Sub
This give me "Object required" error on the MsgBox line. Which makes me think I'm not passing the textbox control properly.
I would ask for clarification if I had enough rep to comment, but here are some thoughts:
If you haven't explicitly declared your variable, MyTextboxName, it will be of type variant. You can't pass a variant to an object parameter. This might be enough:
dim MyTextBoxName as Control
But in this case, you wouldn't be working with names at all. If you want to work with names, you have to change your function. Change the signature to take a string and then use the string as the index into the Controls collection (if there is one on Access Forms):
Private Sub SetIntialToggleValue(ByRef ControlName As String)
MsgBox Form.Controls(ControlName).Value
End Sub
How about something like the following:
Option Explicit
Dim ctl as Control
Private Sub Form_Load()
set ctl = Me.MyTextboxName
Call SetIntialToggleValue(ctl)
End Sub
Private Sub SetIntialToggleValue(ByRef ControlName As Control)
MsgBox ControlName.Value
End Sub
I found the answer here. You can declare:
Private Sub SetIntialToggleValue(ByRef ControlName As MSForms.TextBox)
Currently, you're not passing in the name of the textbox. You're passing in the textbox object itself. You did reference it as a Control in your method, but if you're only using textboxes, you could replace Control with Textbox. Indeed, Textbox is its own type.
The answer as I'm sure you have all figured out is given here:
https://www.access-programmers.co.uk/forums/threads/passing-a-control-as-parameter.213322/
Calling a function with brackets causes the compiler to force a conversion to ByVal which replaces your "control" with the "value" of the control and passes it with the wrong type.
Correct answer is simply SetIntialToggleValue MyTextboxName