I have a very basic question about VBA sub routines. What I'm trying to do is
Set activeCell to Range variable
Pass that variable to Sub routine
Do something with the activeCell
What I tried to do is
Sub myMacro()
Dim myCell As Range
Set myCell = ActiveCell
mySub(myCell)
End Sub
Sub mySub(cell As Range)
' Do something
End Sub
I keep getting an "Object required" error.
What is the problem here?
When you pass arguments to a function, you dont need to use parenthesis. Eg:
mySub myCell
You could also use Lance sugention and use use Call AND parenthesis. (Press F1 over Call in the VBA Editor to get more info about it)
Call mySub(myCell)
Either way is correct, but the first notation might prove more helpful while learning VBA as the great mojority of Answers in forums use the first one.
You need to use the Call statement on the subroutine.
Call mySub(myCell)
Related
Every time I try to put some arguments in a Function Excel would return #VALUE. Below is one of the examples. Also, I cannot debug when I put arguments in. What is the possible cause? Thank you.
Function lastrowC(SelectedCell As Range)
sc = SelcetedCell.Column
lastrowC = ActiveSheet.Cells(Rows.Count, sc).End(xlUp).Row
End Function
Your code does not work due to a typo. If you add Option Explicit to the top of your code, then try to calculate, VBA will
show you the problem (you misspelled Selected)
Either way, please consider the below code which will target the correct worksheet rather the active worksheet. Your code, as is, will likely look to the wrong sheet to determine the last row under certain circumstances. You need to look at the sheet where the range was selected, which is not always going to be the same as the active sheet
Paste the below code in a Module to call function from excel
Function lastrowC(Target As Range) As Long
With Target.Worksheet
lastrowC = .Cells(.Rows.Count, Target.Column).End(xlUp).Row
End With
End Function
The formula:
=IFERROR(IF(OR(E10=0,D9=0),0,NETWORKDAYS(D9,E9))," ")
An example of what I've tried in VBA:
Sub inputWorkdays()
Range("h9").Formula = "=IFERROR(IF(OR(E9=0,D9=0),0,NETWORKDAYS(D9,E9)),""Yes"")"
End Sub
I'm trying to add the formula from above into cell H9.
Select the cell with the formula and write the following:
Sub TestMe
debug.print Selection.Formula
debug.print Selection.FormulaR1C1
End sub
In your case it would give:
=IFERROR(IF(OR(E10=0,D9=0),0,NETWORKDAYS(D9,E9)),"YES")
=IFERROR(IF(OR(R[-4]C[-1]=0,R[-5]C[-2]=0),0,NETWORKDAYS(R[-5]C[-2],R[-5]C[-1])),"YES")
Take the first one and use it like this:
Range("h9").Formula = "=IFERROR(IF(OR(E10=0,D9=0),0,NETWORKDAYS(D9,E9)),""YES"")"
I gather from the comments that there is no error, just "nothing happens". I see nothing wrong with your code. Except...
Range("h9").Formula = "..."
When Range is unqualified like this, you implicitly refer to the ActiveSheet; if the active sheet isn't the sheet you're expecting to write to, then it's easy to conclude that "nothing happens" and that the code doesn't work.
If you have Rubberduck installed (full disclosure: I'm heavily involved with the development of this open-source VBE add-in), you will see that Range in this case is a member of Excel._Global, and an inspection result will tell you that you're implicitly referring to the ActiveSheet:
Range("H9").Formula = "..."
Implicit references to the active sheet make the code frail and harder to debug. Consider making these references explicit when they're intended, and prefer working off object references.
http://rubberduckvba.com/Inspections/Details/ImplicitActiveSheetReferenceInspection
To fix this, qualify the Range call with a Worksheet object - now the Range call is a member of the Excel.Worksheet class:
Dim sheet As Worksheet
Set sheet = ThisWorkbook.Worksheets("Sheet1")
sheet.Range("H9") = "..."
By qualifying Range calls with a worksheet object, you make sure that you're always writing to the worksheet you mean to write to - not the worksheet that happens to be the active one when the code runs.
I am having trouble concatenating two columns (variable range) to another column in the same document. Is there something really obvious I'm missing?
Function ConcCol(ConVal_1 As String, ConVal_2 As String)
Range("V30:V500").Select
Application.CutCopyMode = False
With ActiveCell
.FormulaR1C1 = "=CONCATENATE(RC[5],"" "",RC[6])"
End With
Selection.AutoFill Destination:=Range(Destination), Type:=xlFillDefault
End Function
When running the above function, I get the following error:
Error: Run-time error '1004': AutoFill method of Range class failed
I assume it's something to do with only one cell being activated perhaps? My VBA knowledge is limited
Sub ConcCol()
Range("V3:V500").Select
For Each Cell In Selection
Cell.Value = "=CONCATENATE(RC[5],"" "",RC[6])"
Next Cell
End Sub
I think it'd be easier (if you're going with the selection idea), to just use each cell. I think your with statement doesn't want to loop at all, hence error. This works, a simple solution.
I think this is what you're looking for:
Sub tgr()
With Intersect(ActiveSheet.UsedRange.EntireRow, Range("V30:V" & Rows.Count))
.Formula = "=AA" & .Row & "&"" ""&AB" & .Row
End With
End Sub
Hey I think you are a bit confused. How do you plan to run this code? You need to provide more details. Here are three ways of running a vba code:
User Interface as a User Defined Function (UDF)
As a Function that is called/used by another VBA code
AS a macro and user need to run it from the macro list
For your purpose, why doesn't the user use CONCATENANTE function in the sheet and fill down?
Maybe use the Excel array functions?
I cannot post images, need 10 reputations :s
I know this sounds simple, but seemingly it is not.
If I write this in Word VBA, it always says "incompatible types" - why?
And how do I make it work?
Sub GetRange()
Dim r As Range
Set r = ActiveDocument.Paragraphs(5).Range
ProcessRange (r)
End Sub
Sub ProcessRange(r As Range)
Debug.Print "This generates an error (incompatible types)- why?"
End Sub
It is not allowed to call a Sub with parenthesis, except if you are using the Call statement.
Hence you have to use either:
Call ProcessRange(r)
Or:
ProcessRange r
The reason for that is that in VBA (and VBS, VB6, too) the parenthesis can have a whole lot of different meanings.
In your case the range object will be evaluated before passing the result to ProcessRange. In this case it leads to a string being passed to the sub, because the default property of Range is Text.
See this article for an overview: http://blogs.msdn.com/ericlippert/archive/2003/09/15/52996.aspx
Process Range is a sub so don't invoke it with parentheses. (The error occurs because (r) causes r to be evaluated which returns its default property value which isn't of type range so mismatches what ProcessRange expects.
Use either;
ProcessRange r
or
call ProcessRange(r)
Using parenthesis visual basic assumes you're calling a function.
ProcessRange r
does the trick
I am a beginning in visual basic. What I am trying to do is whenever a box is clicked, highlight a specific range. Then, if another box is clicked after that, the previous range will unhighlight, and another range will highlight. Here is my code but it doesn't work right now.
Dim FSelect As Boolean
Dim myRange As Range
Sub Rectangle18_Click()
If FSelect Then
UnhighlightBox (myRange) <---error - runtime error "424" object required
End If
Range("C9:D9").Select
HighlightBox
FSelect = True
Set myRange = Range("C9:D9")
End Sub
Sub Rectangle19_Click()
If FSelect Then
UnhighlightBox (myRange)
End If
Range("C11:D11").Select
HighlightBox
FSelect = True
Set myRange = Range("C11:D11")
End Sub
Sub HighlightBox()
Selection.Interior.ColorIndex = 36
End Sub
Sub UnhighlightBox(cellRng As Range)
cellRng.Interior.ColorIndex = 2
End Sub
When I throw this code into excel it complains about Select. I don't think you can use Select as a variable...
EDIT: Select is a reserved keyword in VB/A, It begins the Select Case block.
Putting the parentheses around the argument when calling the UnhighlightBox procedure is incorrect.
Two possible correct forms:
UnhighlightBox myRange
Call UnhighlightBox(myRange)
I find the first form (without the Call keyword) to be preferable
For the Excel 2003 help:
You are not required to use the Call
keyword when calling a procedure.
However, if you use the Call keyword
to call a procedure that requires
arguments, argumentlist must be
enclosed in parentheses. If you omit
the Call keyword, you also must omit
the parentheses around argumentlist.
Please note that this does not apply to a function which returns a value. A function needs to be called as part of an assignment (e.g. a = f(x)) and the arguments must be enclosed in parentheses
Your use of the FSelect boolean (which initialises to false) should be preventing the problem with calling UnhighlightBox before myRange is ever set.
When using the UnhighlightBox routine you either need to put the Call statement before hand or remove the parenthesis.
For example:
Call UnhighlightBox (myRange)
or
UnhighlightBox myRange
For more info on why to use Call, etc see the either of the following:
what-does-the-call-keyword-do-in-vb6
MSDN