VBA pass the name of activesheet to a function - excel

I have created a function to receive three parameters.:
An array of strings
A worksheet name
An index for the array of strings
When I compile I am getting a compile error stating:
Compile Error:
Expected:=
My call is:
Sub C_Button_ImportBOM_Click()
Dim strFilePathName As String
Dim strFileLine As String
Dim v As Variant
Dim RowIndex As Long
Dim mySheet As Worksheet
ActiveSheet.Name = "Import"
mySheet = Worksheets("Import")
strFilePathName = ImportFilePicker
v = QuickRead(strFilePathName)
For RowIndex = 0 To UBound(v)
PopulateNewLine (v(RowIndex), mySheet, RowIndex)
Next
End Sub
The function declaration is:
Function PopulateNewLine(SourceString As String, ImportSheet As Worksheet, CurrentRow As Long)
I have tried many things to no avail. Initially with just the first argument declared and used this worked okay.
Any ideas greatly appreciated.
Excel 2010 VBA

You are calling your function like a subroutine, i.e., you're not returning a value from it and assigning it to a variable, as you'd normally do with a function. That means you need to call it without the parentheses surrounding the arguments:
PopulateNewLine v(RowIndex), mySheet, RowIndex
If you really aren't returning anything from it, you should probably turn it into a Sub for clarity's sake:
Sub PopulateNewLine(SourceString As String, ImportSheet As Worksheet, CurrentRow As Long)
... your code here
End Sub
On another note, you should qualify your mySheet reference, and as I mentioned in the comments, use Set. It should look something like:
Set mySheet = ActiveWorkbook.Worksheets("Import")
Substitute whatever workbook Import is in for ActiveWorkbook above.

Related

How to access data from another workbook?

My function is accepting workbook as an input. But I am not able to iterate the values in the workbook.
I am getting the error as the 'Object variable not set'.
P.S: I cannot use Range since the range is unknown.
Sub Test (wb as workbook)
Dim sheet as worksheet
Dim value as Integer
sheet = wb.worksheet(1)
value = sheet.Cells(1,1).Formula
return value
End sub
There are several issues with your code:
The error you get is because you declared Dim sheet As Worksheet and Worksheet is an object and objects need to be Set like
Set sheet = wb.worksheet(1)
You defined the variable value as Integer and then you try to read the .Formula into it which is a String. An Integer cannot hold a formula. I think you wanted to read the .Cells(1,1).Value instead.
VBA does not have a return you need to set your function Test = value
You used a procedure Sub and not a function therefore it cannot return any values. You need to change it into a Function
I think you should end up with something like that:
Public Function ReadMyValue(ByVal wb As Workbook) As Double 'or Long
Dim ws As Worksheet
Set ws = wb.Worksheet(1) 'use set for objects!
Dim Value As Double 'or Long !!! but the same as your function is declared !!!
Value = ws.Cells(1, 1).Value
ReadMyValue = Value 'return the value to your function
End Function
And you can test it like:
Public Sub TestMyFunction()
Debug.Print ReadMyValue(ThisWorkbook) 'will output the value of A1 of the first worksheet in this workbook.
End Sub

Passing variable to macro [duplicate]

If I have an excel function such as:
=my_function(A1:C4)
and I want to call this from VBA like:
Dim t as variant
t = Application.Run("my_function",X)
What is the simplest way for X to represent A1:C4?
Your range has to come from a worksheet, so if you define that range first and then pass it to the function in your other workbook (I assume that's what you want to do since you wouldn't use Application.Run otherwise). So the following code will do the trick:
Sub RunFunctionInAnotherWorkbook()
Dim rThisRange as Range
Dim vResult as Variant
Set rThisRange = ActiveSheet.Range("A1:C4")
vResult = Application.Run("'MyOtherWorkbook.xls'!TheModuleName.TheSubName", rThisRange)
End Sub
And the function in the workbook "MyOtherWorkbook.xls":
Function TheSubName(inputRange as Range) as Variant
'Work your magic here
End Function
I haven't try it, but wouldn't
t=myfunction(range)
The simplest syntax is
Application.Run("my_function", [A1:c4])

Passing sheets as variables from one sub procedure to another in VBA

This is my first post on stackoverflow. I have two sub procedures in Excel VBA. The first one, called Sub IAR_part_2(), is intended to assign two sheets (by index location) to two variables named sheetname1 and sheetname2. after assigning the variables I am trying to pass them to my second sub procedure, called IAR_macro, to be processed. The two sheets are dependant on one another, so sheets 4 and 8 are ran through the IAR macro, sheets 5 and 9, sheets 6 and 10, etc. My problem is that I cannot figure out how to pass the sheetname variables from IAR_part_2 to IAR_macro. What am I doing wrong?
Sub IAR_part_2()
sheetname1 = Worksheets(4)
sheetname2 = Worksheets(8)
Call IAR_macro
End Sub
Sub IAR_macro(sheetname1 As Worksheet, sheetname2 As Worksheet)
Dim h As Long
Dim i As Long
Dim l As Long
Dim j As Long
Dim k As Long
Dim lr As Long
Worksheets(sheetname1).Activate
' Find the number of the last cell with data in column A and subtract 1 to populate variable i
On Error GoTo Canceled
i = (Range("B1").End(xlDown).Row) - 1
'Switch over to the Code sheet
Worksheets(sheetname2).Activate
'While the number of loops is less than variable i minus 1, copy the contents of cells A2 through A29 over and over down the worksheet
Do While l < (i - 1)
Range("A2:A29").Select
Selection.Copy
lr = Cells(Rows.Count, "A").End(xlUp).Row
Range("A" & lr + 1).Select
ActiveSheet.Paste
l = l + 1
'rest of macro follows from here...
Simple example of how to pass worksheet objects to a different sub:
Sub Macro1()
'Declare variables
Dim ws1 As Worksheet
Dim ws2 As Worksheet
'Assign variables to worksheet objects
Set ws1 = Worksheets(4)
Set ws2 = Worksheets(8)
'Call the second sub and pass the worksheet variables to it
Call Macro2(ws1, ws2)
End Sub
Sub Macro2(ByVal arg_ws1 As Worksheet, ByVal arg_ws2 As Worksheet)
'Reference the accepted arguments (in this case worksheet variables) directly:
MsgBox arg_ws1.Name
MsgBox arg_ws2.Name
'This will result in an error because you're using the passed argument incorrectly:
MsgBox ActiveWorkbook.Sheets(arg_ws1).Name '<-- Results in error
End Sub
You must reference the passed arguments directly. If you want to use the structure shown in your code, then the arguments passed need to be a string (but this method is NOT recommended):
Sub Macro1()
'Declare variables
Dim sSheet1 As String
Dim sSheet2 As String
'Assign variables to worksheet objects
sSheet1 = Worksheets(4).Name
sSheet2 = Worksheets(8).Name
'Call the second sub and pass the worksheet variables to it
Call Macro2(sSheet1, sSheet2)
End Sub
Sub Macro2(ByVal arg_sSheetName1 As String, ByVal arg_sSheetName2 As String)
'Because the arguments are strings, you can reference the worksheets this way
'This method is NOT recommended
MsgBox Worksheets(arg_sSheetName1).Name
MsgBox Worksheets(arg_sSheetName2).Name
End Sub
I noticed in your examples, you have your variables declared inside the function. Normally any variables you wish to use are better implemented by using option explicit. Also when identifying sheets, you will have less problems when addressing a sheet by its sheet number as opposed to the sheet name. That way if you need to use a variable, you can use just a integer instead as well.
Option Explicit
Dim h as Long, i as Long, l as Long, j as Long, k as Long, lr as Long
Dim x as Integer
Sub IAR_macro()
On Error GoTo Canceled
i = (Range("B1").End(xlDown).Row) - 1
Sheets(x).Activate
Do While l < (i - l)
Sheet ids can be located in the development tool. Here is an example:
This is minimal way of passing the worksheets. As far as they are objects, they are passed by reference by default:
Sub TestMe()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = Worksheets(1)
Set ws2 = Worksheets(2)
Passing ws1, ws2
End Sub
Sub Passing(arg_ws1 As Worksheet, arg_ws2 As Worksheet)
Debug.Print arg_ws1.Name
Debug.Print arg_ws2.Name
End Sub
VBA is not as easy and as simple as many people (mainly those who consider it to be a funny-scripting-language, written by wanna-be-developers) think. Sometimes it allows to write ByVal, but it follows its own rules and takes the argument ByRef, just to comfort you and make sure you are not going to make an error.
Saw the answer from #tigeravatar here and I have decided not to write a comment under it, but to explain in a different post why it is wrong and dangerous, as far as explaining it as a comment would have been tough.
If you try to write a Stop line here from the answer:
Sub Macro1()
'Declare variables
Dim ws1 As Worksheet
Dim ws2 As Worksheet
'Assign variables to worksheet objects
Set ws1 = Worksheets(4)
Set ws2 = Worksheets(8)
'Call the second sub and pass the worksheet variables to it
Call Macro2(ws1, ws2)
End Sub
Sub Macro2(ByVal arg_ws1 As Worksheet, ByVal arg_ws2 As Worksheet)
'Reference the accepted arguments (in this case worksheet variables) directly:
MsgBox arg_ws1.Name
Stop
MsgBox arg_ws2.Name
'This will result in an error because you're using the passed argument incorrectly:
MsgBox ActiveWorkbook.Sheets(arg_ws1).Name '<-- Results in error
End Sub
Run the answer and wait for the Stop line:
If the arg_ws1 were taken byVal, then if someone changes the name of the 8th worksheet, while the Stop is lighting, then it should still take the old name. It is ByVal, remember? Well, go ahead and change the name. Then continue with F5. Which name are you getting? Why?
The answer is because of the way the Sub is called with parenthesis in the arguments. These force ByVal and ignore anything explicitly written.
CPearson ByRef vs ByVal
Disclaimer - My Article for how to refer a function ByVal when it is ByRef
You need to pass the two variables you created to your second sub when you call the procedure:
Sub IAR_part_2()
Set sheetname1 = Worksheets(4)
Set sheetname2 = Worksheets(8)
Call IAR_macro (sheetname1,sheetname2)
End Sub

Excel Mac 2011 VBA, ByRef argument type mismatch with Worksheet argument

I'm tearing my hair out trying to get VBA to be happy. I have a function which returns the name that the current sheet should have, depending on its contents. Declared like this:
Function NewSheetName(OnSheet As Worksheet) As String
Dim n As String
n = Left(OnSheet.Name, 4)
<set n based on sheet's contents>
NewSheetName = n
End Function
To test it works, I have the following:
Sub try()
Dim ws As Worksheet
Dim s As String ' try to make VBA happy...doesnt make any difference
Set ws = Application.ActiveSheet
If TypeOf ws Is Worksheet Then
Debug.Print "Yup"
s = NewSheetName(ws)
Else
Debug.Print "Nope"
End If
End Sub
The Immediate window gets "Yup" but then VBA barfs, telling me there is a ByRef argument type mismatch.
Please, what am I doing wrong?

Application.Run and range parameter?

If I have an excel function such as:
=my_function(A1:C4)
and I want to call this from VBA like:
Dim t as variant
t = Application.Run("my_function",X)
What is the simplest way for X to represent A1:C4?
Your range has to come from a worksheet, so if you define that range first and then pass it to the function in your other workbook (I assume that's what you want to do since you wouldn't use Application.Run otherwise). So the following code will do the trick:
Sub RunFunctionInAnotherWorkbook()
Dim rThisRange as Range
Dim vResult as Variant
Set rThisRange = ActiveSheet.Range("A1:C4")
vResult = Application.Run("'MyOtherWorkbook.xls'!TheModuleName.TheSubName", rThisRange)
End Sub
And the function in the workbook "MyOtherWorkbook.xls":
Function TheSubName(inputRange as Range) as Variant
'Work your magic here
End Function
I haven't try it, but wouldn't
t=myfunction(range)
The simplest syntax is
Application.Run("my_function", [A1:c4])

Resources