Can someone explain what am I doing wrong here. Excel doesn't seem to set the variable value if I run the second macro before the first one. I would like to set the values just once and use them in multiple macros. I have 6 macros that will be using the same values. The code included below is a short code I use to test.
Option Explicit
Dim Test As String
Sub sub1()
Test = "Test"
MsgBox Test
End Sub
Sub sub2()
MsgBox Test
End Sub
This is the popup i get if the second macro is executed before the first one.
Just call the second macro from the first. Otherwise Test will not be assigned a value.
You can read about scope here.
Dim Test As String
Sub sub1()
Test = "Test"
MsgBox Test
sub2 'or call sub2
End Sub
Or you can use a Constant, e.g.
Public Const Test As String = "Test"
(see my edit below - the original answer doesn't answer the question you asked properly)
You can set it as a public variable
Option Explicit
Public Test As String
Sub sub1()
Test = "Test"
MsgBox Test
End Sub
Sub sub2()
MsgBox Test
End Sub
Or call sub2 from sub1 with a parameter
Sub sub1()
Test = "Test"
MsgBox Test
'call the second sub with the Test variable here
sub2 Test
End Sub
Sub sub2(test as string)
MsgBox test
End Sub
or have Sub1 be a function and return the value
Function sub1()
Test = "Test"
MsgBox Test
'call the second sub with the Test variable here
sub1 = Test
End Function
Sub sub2()
test = sub1()
MsgBox test
End Sub
EDIT :
Or you could wrap it all in another sub so you are able to define the public variable
Public Test as string
Sub sub1()
MsgBox Test
End Sub
Sub sub2()
MsgBox Test
End Sub
Sub run()
Test = "Test"
sub1()
sub2()
End Sub
If you want a variable to keep its value for the whole excel session (i.e. a static variable) use the Global keyword
Global Test As String
Remember, one of your procedures must assign a value to it. Otherwise it will have a value of ""
Related
I'm trying to write a macro that will have many different buttons. I would like all the buttons to trigger the same function but I need to set a variable in the function to identify which button triggered the macro.
I'm not really sure how I should do this. Is there a way I can say like variableA = ClickedButton()?
Any advice is appreciated
Hi , I think something like this should work
Private Sub CommandButton1_Click()
myfunction "b1"
End Sub
Private Sub CommandButton2_Click()
myfunction "b2"
End Sub
Private Sub CommandButton3_Click()
myfunction "b3"
End Sub
sub myfunction (v as variant)
msgbox v
end sub
Try the following
In the button module:
Sub CommandButton1_Click()
myFunction btn_name:= Me.Name
End Sub
In a normal module:
Public Function myFunction(btn_name As String)
MsgBox "The button pressed was:" & btn_name
'do stuff
End Sub
Doing this, you pass the name of the pressed button (Me.Name) to the function as a variable, so it can be used generally inside that function.
How do I feed parameters into a sub? When I run a Macro, the sub just runs without asking for any input.
Sub do_something(input as integer)
xxxxxx
end sub
I know I can use the sub in another sub/function where I can give it a input. Like the following,
sub caller_function()
call do_something(1)
end sub
Is there another way to use do_something?
Thanks in advance!
Set up your sub something like this:
Sub do_something(param As Integer)
MsgBox "The parameter passed to this Sub is " & param
End Sub
To call it:
do_something 1
If you want more than one parameter..
Sub do_something(param1 As Integer, param2 As String)
MsgBox "The parameters passed to this Sub is " & param1 & " and " & param2
End Sub
To call it:
do_something 4,"Hello"
Or for a bit or reading chaos:
do_something param2:="Hello", param1:=4
The code that you provided does not compile. Maybe you were trying to provide a simple example...?
It does not compile because Input is a reserved word, used to read data from a file object. You cannot use it as a variable name. (I have assumed that "xxxxx" is indicating where code should go, i.e. 'Do something here.)
The following code works, but you cannot run it without passing a value:
Sub do_something(i As Integer)
MsgBox i
End Sub
If you want to make the variable optional, you can add the Optional keyword. Then it will run even if a value is not passed:
Sub do_something(Optional i As Integer)
MsgBox i
End Sub
You could also use a globally scoped variable, which would allow the sub to run without directly supplying a value:
Option Explicit
Public i As Integer
Sub do_something()
MsgBox i
End Sub
Regarding Input: https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/inputstatement
With a single argument, you don't use parenthesis
do_something 1
This is just an example of what I want to do. I have an elaborate macro that I want to do different things depending on whether it was called by another macro or not.
sub Example()
Call MyCode
end sub
sub MyCode()
If Called by Example GoTo SkipNextLine
Do these things
exit sub
SkipNextLine:
Do other things
end sub
You can create hidden name (which, actually, isn't tied to range). Think of it as global variable. The difference between global variable and this name is that name is persisted in workbook when you close it. When you open workbook again - you can start using it without any initialization. As a bonus, this name won't be displayed in Name Manager. The defining of name is required only once.
Sub SetHiddenName()
Names.Add Name:="Caller", RefersTo:="StartValue", Visible:=False
End Sub
Sub FF()
Names("Caller").Value = "FF"
Call SS
End Sub
Sub SS()
Select Case [Caller]
Case "FF": MsgBox "Called by FF" '...
Case "ZZ": MsgBox "Called by ZZ"
End Select
End Sub
A simple approach would be to use arguments and parameters.
Sub Example()
Call MyCode("Example")
End Sub
Sub Example2()
Call MyCode("Example2")
End Sub
Sub MyCode(Origin as String)
Select Case Origin
Case "Example"
'Do stuff here
Case "Example2"
'Do other stuff here
End Select
End Sub
I made my way to this post wanting a macro that changed things on the sheet, but not wanting to kick off event driven macros. In case it's also useful for someone else, it's possible to turn these off in excel using Application.EnableEvents in the parent macro using:
Sub parentMacro()
Application.EnableEvents = False
'Do stuf here
Application.EnableEvents = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
'this now only is called on worksheet changes outside of parent macro,
'as it's disabled while parent runs
'Note: This disables all event macros running, so might not be perfect for all cases
End Sub
I put this code into the module page
Option Explicit
Dim correct As Boolean
Sub setCorrect()
correct = True
End Sub
Sub checkCorrectTrue()
If correct Then
MsgBox "OK"
Else
MsgBox "NO"
End If
End Sub
Then when I call these 2 subs from a sheet my variable correct never switch to True
Private Sub CommandButton4_Click()
Call setCorrect
Call checkCorrectTrue
End Sub
Because you're using Dim correct As Boolean it is only available in that module. To be able to use the variable across modules you need to declare it using Public
Try using
Option Explicit
Public correct As Boolean
Sub setCorrect()
correct = True
End Sub
Sub checkCorrectTrue()
If correct Then
MsgBox "OK"
Else
MsgBox "NO"
End If
End Sub
Usually the Excel VBA editor auto-capitalizes keywords and property names for you, but now it is un-capitalizing them. Like this:
Private Sub CommandButton1_Click()
Range("A1").Value = "test"
End Sub
changes to:
Private Sub CommandButton1_Click()
Range("A1").value = "test"
End Sub
And then the code doesn't run properly. Any ideas what could cause this behavior? Thanks.
Possible reasons
You have named one of the modules as value
You have a variable called value in one of your procedures/functions
You have a procedure/function with that name
Example for point 1
Example for point 2
Sub Sample()
Range("A1").value = "Sid"
End Sub
Sub Blah()
Dim value As Long
value = 1
End Sub
Example for point 3
Sub Sample()
Range("A1").value = "Sid"
End Sub
Sub value()
'
'
'
End Sub