I am wondering if there is a simpler way to "loop" a sub to do a number of times.
I would like to do the following:
Sub defined()
'code here to be looped
End sub
Sub use()
... 'previous codes
Call defined 'do defined once
... 'interlude codes
Call defined(3) 'do defined action thrice
... 'interlude codes
Call defined(2) 'do defined twice
End Sub
Is there something like that exist? Or I must use Loop, something I still am a little confused on how to code when applying this method with a call sub.
Thank you for your time.
edited for tags
You could do something like this:
Sub Defined(numCalls as Integer)
Dim i as Integer
If not numCalls > 0 Then Exit Sub
For i = 1 to numCalls
'The rest of your code
Next
End Sub
This will allow you to do:
Call defined(3)
Etc.
for i = 1 to 3
Defined '("Call" is optional)
next i
Related
I'm new in VBA
I wrote a code like this:
sub a1
some codes
end sub
sub a2
some codes
end sub
when I run my code the only code that be executed is sub a1!
how can I run other subs?
If you have 2 procedures
Sub FirstProcedure()
'Some code
End Sub
Sub SecondProcedure()
'Some code
End Sub
and you want to run both of them sequencially, you just need to call them
Sub RunBoth()
FirstProcedure
SecondProcedure
'Some more code
End Sub
If you now run RunBoth it will call the FirstProcedure and after that has finished it will call SecondProcedure
If you just want to call one of the procedures from the VBA editor, place your cursor in one of the procedures and press Run at the toolbar or F5 on the keyboard.
Alternative to #PEH 's approach via Application.Run
This approach demonstrate possible usage via Application.Run. Similar to OP, I confined myself to procedure calls without passing arguments here.
A) Numbered procedure calls
If you'd dispose of numbered procedures with identical name prefix (e.g. "Proc1", "Proc2"),
you may code as follows:
Sub ExampleCall()
runNumberedProcedures "Proc", 2
End Sub
Sub runNumberedProcedures(ByVal ProcName As String, ByVal ProcNumber As Long)
Dim i As Long
For i = 1 To ProcNumber
Application.Run "Proc" & i
Next i
End Sub
Undocumented Caveat
Note that Run needs an additional module prefix for procedure names ranging from A to XFD (e.g. in the case of Module.a1 or Module1.a2),
as apparently VBA tries to avoid internal conflicts with Excel column names. Therefore a numbered procedure starting with "XFE" or "Proc" needn't be prefixed expressly.
Side note: Personally I'd prefer more meaningful naming conventions than a1,a2 or Proc1,... apart from testings.
B) Procedure calls via list of procedure names
If you want to run any procedure names in a given order, you might call a sub and pass a procedure list as argument (here: "Proc1,Proc2,Module1.a1"):
Sub ExampleCall2()
'[1]run listed procedures
runListedProcedures "Proc1,Proc2,Module1.a1"
'do other stuff
'...
'[2]run procedure a2 later
Run "Module1.a2" ' note module prefix for proc names from A to XFD !
End Sub
Sub runListedProcedures(ByVal ProcList As String)
Const Delim As String = ","
Dim procedures As Variant
procedures = Split(ProcList, Delim)
Dim i As Long
For i = LBound(procedures) To UBound(procedures)
Application.Run procedures(i)
Next i
End Sub
Is there a way that vba can determine if a method is present/available?I have two different methods that will essentially be doing the same thing, but in different ways: one being an SQL server and the other being an excel file. I want to be able to first call the SQL method, and if whatever reason that SQL method is unavailable, it will then call the excel method. But what would be the line of code in the if statement?
I know that you "Call" to methods, but what essentially is the line of code that would be:
If SQLMethod() ... Then
Call SQLMethod()
Else
Call ExcelMethod()
End If
What would the code be at "..." to check this?
Any help would be appreciated!
You cannot have a reference to a routine that doesn't exist; the code won't compile, and you'll receive a "Complie error: Sub or Function not defined".
But, you can do this:
Sub Main()
On Error Resume Next
Application.Run "Test1"
If Err <> 0 Then Application.Run "Test2"
End Sub
Sub Test1()
Debug.Print "Test1()"
End Sub
Sub Test2()
Debug.Print "Test2()"
End Sub
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
My procedure has become too large and won't run anymore. I've redesigned my code in my mind, but I need to get my current code up and running before I start editing. I've looked online and they say you need to split your procedure into subs and call them, but none really explain or show how you do this.
Thanks!
Sub Sub1()
' Code...
End Sub
Sub Sub2()
' Code...
End Sub
Sub Main()
Sub1
Sub2
End Sub
The first step is to take parts of code that are duplicated, and created one subroutine or function that you put that part into. Then you call the subroutine or function instead of duplicating the code everytime you need it.
Sub MacroName
Call ProcedureName1
Call ProcedureName2
etc...
End Sub
Sub ProcedureName1
'insert your vba code here
End Sub
The Call statement pulled each of the subs as long as I called the correct named sub.