How to tell the AVERAGE function to avoid non numerical values - vba

I've got a worksheet that looks something like this
and what I want to do is average the values on each column using vba.
If I use the =AVERAGE() formula, that works fine and it ignores the N/A in the columns. But I need to do this with vba.
If I try to do something like
Sub test()
Worksheets("Sheet1").Range("C17").Value = WorksheetFunction.Average("C2:C14")
End Sub
Then I get a message saying "Unable to get the Average property of the WorksheetFunction class"
Is there any way I can tell my code to avoid the "N/A" when it calculates the averages so I don't get this issue?

Since Average doesn't take a string input, use
WorksheetFunction.Average(Worksheets("Sheet1").Range("C2:C14"))
rather than just WorksheetFunction.Average("C2:C14")

Related

Expected: End of Statement for Excel Formula

I have an Excel macro that formats a sheet down to its relevant data.
One of the columns I have taken (column C) has full names of individuals - and I am trying to put in a calculation that will pare the full name down to initials.
I have a calculation that works, if used by itself...but when I put it into the VBA macro, I get the "Expected: End of Statement".
The formula itself is:
=LEFT(C2)&IF(ISNUMBER(FIND(" ",C2)),MID(C2,FIND(" ",C2)+1,1),"")&IF(ISNUMBER(FIND(" ",C2,FIND(" ",C2)+1)),MID(C2,FIND(" ",C2,FIND(" ",C2)+1)+1,1),"")
The VBA code I have is:
Enter_Formulas() = "=LEFT(C2)&IF(ISNUMBER(FIND(" ",C2)),MID(C2,FIND(" ",C2)+1,1),"")&IF(ISNUMBER(FIND(" ",C2,FIND(" ",C2)+1)),MID(C2,FIND(" ",C2,FIND(" ",C2)+1)+1,1),"")"
I get the End of Statement error at the first FIND part above, I believe because the ", followed by a space seems to signal the end of the statement - how do I overcome this? Or is there a better way to achieve what I am trying?

VBA creating formulas referencing a range

After several hours of research, I still can't solve what seems to be a pretty simple issue. I'm new to VBA, so I will be as specific as possible in my question.
I'm working with a DDE link to get stock quotes. I have managed to work out most of the table, but I need a VBA to create a finished formula (i.e., without cell referencing) in order to the DDE link to work properly.
My first code is as follows:
Sub Create_Formulas()
Range("J1").Formula = "=Trade|Strike!" & Range("A1").Value
End Sub
Where J2 is the blank cell and A2 contains the stock ticker. It works fine, but when I try to fill out the rows 2 and bellow, it still uses A1 as a static value.
Sub Create_Formulas()
Dim test As Variant
ticker = Range("A1").Value
'Test to make variable change with each row
'Range("J1:J35").Formula = "=Trade|Strike!" & Range("A1:A35").Value
'not working
Range("J1:J35").Formula = "=Trade|Strike!" & ticker
'not working
End Sub
I couldn't find a way to solve that, and now I'm out of search queries to use, so I'm only opening a new topic after running out of ways to sort it by myself. Sorry if it is too simple.
You are referencing absolute cell adresses here. Like you would do when using $A$1 in a normal excel formula.
What you want to do is:
Dim row as Integer
For row = 1 to 35
Cells(row,10).Formula = "=Trade|Strike!" & Cells(row,1).Value
Next row
This will fill the range J1 to J35 with the formula. Since (row,10) indicates the intersection of row and column 10 (J)
Firstly, in your second set of code, you define a variable "test", but never give it a value.
You assign a value to the variable "ticker", and then never reference it.
Secondly, the value you have assigned to ticker is a static value, and will not change when it is entered in a different row.
Thirdly, I think your issue could be solved with a formula in Excel rather than VBA.
The "INDIRECT" function can be quite useful in situations like this.
Try inserting the formula
=INDIRECT("'Trade|Strike'!"&A1)
into cell A1, then copy down.
Note the ' ' marks around "Trade|Strike". This is Excels syntax for referencing other sheets.

VBA Offset Match Not Working

I am trying to run a goal seek setting a certain cell equal to zero by changing another cell in Excel with VBA.
The cell I want to set to zero changes location so I need to use a match offset combination I think.
I get a compile error Invalid qualifier when I run the code though. Any ideas?
Thank you.
Private Sub CommandButton1_Click()
Dim x As Integer
x = Application.WorksheetFunction.match("G3", Range("I6:SF6"), 0).Value
Range("I199").Offset(0, x.Value).GoalSeek Goal:=0, ChangingCell:=Range("GN197")
End Sub
Try replacing:
"G3"
with:
Range("G3")
Try using named range instead of using Range reference. This way even if rows or columns are added you named range is still available.
As per official documentation, the return value of WorksheetFunction.Match is a Double. So you probably do not have Value available. Try removing it.
PS: I do not have a system with Excel to test this.
PS2: You did not indicate the line producing the error.

VBA Code for Vlookup

When I reference a specific cell in vlookup VBA code like below I can get the code to return the correct answer.
Application.VLookup(Sheets("Setup").Cells(2, 1),
Sheets("Download").Range("A:G"), 7, 0)
However, if I replace the code with a variable (VLDate) then I get an error
Application.VLookup(VLDate, Sheets("Download").Range("A:G"), 7, 0)
I've tried to make Dim VLDate As String but this didn't work too.
Any suggestions?
In your example Sheets("Setup").Cells(2,1) is not a string.
Cells returns a Range.
Dim VLDate As Range
Set VLDate = Sheet("Setup").Cells(2,1)
If your first example worked, using the above code to set the value of VLDate should make your second example work too.
Edit
Might have misunderstood your question a little so while the above is true it might not help!
Could you provide an example value for VLDate, and also the cell formatting type and an example value from the range that its looked up in?
I think I know what the problem is. The vlookup's first input has to be of the same data type of what you're looking for. For example if in the cells you are searching you have only numbers, then try dimensioning VLDate as a number, if you try to dim it as string it won't find a match and will give you the type mismatch error.
You can dim VLDate as variant, which is easier, but do not use quotes if you're looking for a number.
try adding, for debugging purposes, the line
MsgBox(CStr(Application.VLookup(Sheets("Setup").Cells(2, 1), Sheets("Download").Range("A:G"), 7, 0))
and if you het a msgbox with Error 2042 it menas it couldn't find a match, therefore you should be using the wrong data type.
The only situation that you use string is if the destination cells contain something like ="21" in their formulas, because then it is a string.
hope it helps

VBA: How to get the last used cell by VBA code when the last error occured in a Workbook/Worksheet?

Eventually, I want to move the cell to the location where the last error occured. Edit: Forgot to say that I'm using Excel 2003.
As requested in comments...
Look up the 'Caller' property of the 'Application' object in the Excel VBA help. When you use it from a VBA routine, it will tell you where the call to the routine came from - what Range, Chart, etc.
An important thing to be aware of when using 'Application.Caller' is that it isn't always a Range object. Look at the help, but the property returns a Variant value that can be a Range, String, or Error. (It is a Range object in the case you're interested in, but you'll need to be aware of this.)
Because of the above, and the vagaries of VBA syntax when it comes to objects vs. values, it can be tricky to use 'Application.Caller'. Putting a line like:
Debug.Print Application.Caller.Address
in your code will fail when the caller isn't a Range. Doing something like:
Dim v
v = Application.Caller
will "compile", but will create circular references when the caller is a Range because you're trying to access the value of the calling Range.
This all means that it's probably best to write a little utility function for yourself:
Public Function currentCaller() As String
If TypeOf Application.Caller Is Range Then
Dim rng As Range
Set rng = Application.Caller
currentCaller = rng.Address(External:=True)
Else
currentCaller = CStr(Application.Caller)
End If
End Function
and then call it from your error handlers where you want to know where the call came from.
One more thing - obviously this can only tell you the caller once a VBA routine has actually been called. If you have errors in your calling formulas, Excel will return error values to your cells without ever calling your VBA routines.
Wrap your VBA function in another function that stores the cell location and value as variants. Keep this 'wrapper' function as basic as possible so it won't cause any additional errors.
If you're trying to debug app-crashing errors, the wrapper function could even store those values in a comma-delimited text file. Once stored, Excel can crash all it wants and you'll still know what the cell location and value were since you stored them outside of Excel beforehand.
Could this be done with an error handler?
An example of what I mean below:
sub code1()
on error goto cell A1
end sub