IsNa Sub or Function Not Defined - vba

I Know this is silly but I still can't find the answer after an hour of searching.
I'm trying to determine if a value(Customername) is an NA; I've tried the following 2 methods
Customername = Worksheets("Request").Range("E5")
If IsNA(Customername.value) = True Then CustomerN = 1
CustomerN = Ifna(Customername,1)
Both lines return errors stating "Sub of Function not defined". Whats frustrating is it recognizes the functions because it changes the capitalization, but it still breaks. I've tried dimming CustomerName as different types but doesn't seem to matter.
If you could explain the error in my thought process I'd appreciate it.

It is a worksheet function, so you have to explain this to vba by adding Application.worksheetfunction - like this:
Application.WorksheetFunction.IsNA(Customername.value)

Unless your need is to check specifically for the #N/A error, you can use the natively-available ISERROR function. The caveat is that ISERROR will check for any error, not just #N/A.
(If you need to check specifically for #N/A, Pavel_V's answer is spot on.)
From the link:
Syntax
ISERROR(value)
Function Returns TRUE if
ISERROR Value refers to any error value (#N/A, #VALUE!, #REF!, #DIV/0!, #NUM!, #NAME?, or #NULL!).
You can use it like this:
If IsError(Customer.Value) Then
Additional information at TechOnNet.

Related

Check if a property of an object has value or not

I couldn't find a solution for this on SO or other source. I apologize in advance if this is a tired question:
I have a macro that iterates through placeholders in shapes. Some of these placeholders have text, some don't. I'm trying to figure out if
.Shapes.Placeholder.TextFrame.TextRange has any value or not (In the 'watches' section of the VBA editor, this property has <The specified value is out of range.>). If it does, do something. Otherwise, continue the For Each statement. However, everything I tried has thrown out of bounds errors or something of that type.
I have tried:
If Not (placeholder.TextFrame.TextRange.Length = 0) Then: Immediately throws out of bounds error
Try/catch, which doesn't seem to exist in VBA (Gives me Sub or Function not registered)
If Not CStr(placeholder.TextFrame.TextRange) = "0" then
I'm quite out of my depth as I don't have experience with any Visual Basic iteration. I just need to, if that property is empty or null, skip over the placeholder.
EDIT: Following suggestions, I tried this:
For Each placeholder In sld.NotesPage.Shapes.Placeholders
If Not (placeholder.TextFrame Is Nothing) Then
If Not (placeholder.TextFrame.TextRange Is Nothing) Then
If Not (placeholder.TextFrame.TextRange.LanguageID Is Nothing) Then
placeholder.TextFrame.TextRange.LanguageID = lng
End If
End If
End If
Next
I still get an out of bounds error on placeholder.TextFrame.TextRange Is Nothing. Did I make a syntax error?
FINAL EDIT: Turns out there was an answer in SO after all. For this specific problem, it was enough to add On Error Resume Next right after theFor Each.

Find a Specific Cell entry in a Column in VBA

I'm working on creating a userform for reviewing an excel sheet. I need to search a specific column to see if the user has already reviewed the row. If they have, the cell will be filled with "Reviewed", if it hasn't been reviewed yet it will have "Not Reviewed" in it.
Each department has their own Column logging whether the Row has been reviewed or not. I.e. Dept1 may have reviewed the row, while Dept2 has not yet.
I've tried something like
With Sheets("ECR")
UnReviewedRow = .Range(DepartmentReviewColumn:DepartmentReviewColumn).Find(what:="Not Reviewed", after:=.Cells(DepartmentReviewColumn, 3)).Row
End With
But I'm getting an error, not quite sure where it's coming from though. The hardcoded "3" is because I know that all entries begin at row three, everything above is headers.
I've found a few different similar questions, but they all assume that the column being searched will be the same every time. My issue is that I don't want to code this for each department, I'd like to be a bit more elegant than that.
Something like this:
With Sheets("ECR")
UnReviewedRow = .Range(DepartmentReviewColumn & ":" & DepartmentReviewColumn).Find(What:="Not Reviewed", After:=.Cells(3, DepartmentReviewColumn)).Row
End With
Modifications made:
Range() now takes a properly built string argument;
Cells() now has a row number as its first argument, and a column expressed as a string as its second argument.
Note that this code will fail with Object variable or With block variable not set if the search string is not found. You can handle this situation by initializing UnReviewedRow to e.g. 0 (zero) and putting On Error Resume Next above the Find call, and On Error Resume <either 0 or your original error handler's label> below the Find call. Then, check if UnReviewedRow = 0 and act appropriately.
Always put Option Explicit at the top of modules and classes, and compile your code (Debug / Compile VBAProject). When posting, include the text of all errors encountered.

Presence of parentheses suddenly causes code to break

I had a line of VBA code that basically looked like this:
MyControls.Add(Factory.CreateMyControl(param1, param2))
Where Factory.CreateMyControl is just a sneaky way to allow the new instance of my class module being returned to have a constructor.
It was working without any issues for several weeks. Suddenly, it begins throwing the error object doesn't support this property or method which is baffling me because everything looks like it always has.
After stepping into and through the code, I finally narrowed it down to the line above, and found the issue. The issue was the pair of parentheses surrounding the parameter(s) for the Add function. When I changed the code to the following:
MyControls.Add Factory.CreateMyControl(param1, param2)
It worked just as it always had before the unexpected break.
I now understand that this is the basic syntax in VBA for calling Sub's with parameters: to simply include all parameters in a comma-separated fashion without any parentheses (unless you're setting a Function's return value to another variable or using it's value for some other purpose).
My real question is, why did this suddenly just stop working?
Is it a common occurrence using VBA in Office 2007 for code that once worked to break without warning?
Or could this have been caused by some kind of patch that happened without my knowledge?
With parentheses around, the Sub's parameters per default were passed ByVal instead of ByRef. Without parentheses around, the default is ByRef
Example:
Dim r As Range
Sub test(v As Variant)
MsgBox TypeName(v)
End Sub
Sub main()
Set r = Range("A1")
test r 'ByRef; TypeName is Range
test (r) 'ByVal; TypeName is not Range but the type of the content of A1
End Sub

Expected end of Statement Error on Simple Formula Insert

###.value = "=LOOKUP(LEFT(W2),{"C","A","B"},{"Pick Up","Collect","Prepaid"})"
I want VBA to do this simple formula but getting "Expected: end of Statement" error.
It seems that I need to define something as VBA doesn't recognize character "{}" the brackets.
Assuming that ### actually symbolizes a cell object (otherwise you would get a compile error):
###.Value = "=LOOKUP(LEFT(W2),{""C"",""A"",""B""},{""Pick Up"",""Collect"",""Prepaid""})"
Also, I thought that you would have to change .Value to .Formula, but I tested and both ways work.
It might be requiring you to end the script like this
###.value = "=LOOKUP(LEFT(W2),{"C","A","B"},{"Pick Up","Collect","Prepaid"});"
OR
###.value = "=LOOKUP(LEFT(W2),{"C","A","B"},{"Pick Up","Collect","Prepaid"})";
NOTICE: the Semi-colon at the end ';'.
I'm not a VBA user for a long time. but just try. Delete this answer if its not good enough.

what mistake Am I doing?

sheet1.activate
activesheet.range(cells(2,"Q"),cells(40,"K")).select 'here the error occurs
selection.copy
The above code works for somtimes and for sometimes throws an Error that with object variable not set what does that mean ? why the above code is not working and if i reopen the file it works again and sometimes dont. But i dont know the reason why it happens. Am i making any mistake in the syntax, If so please let me know the right way to do it. And is there any more efficient way to do to select a set of range ? other than the above ? Thank you in advance
The cause of this error is usually the omission of a Set keyword, e.g.
Dim w as Worksheet
w = Sheet1 ' throws error 91
' Correct syntax:
' Set w = Sheet1
If you tell us on what line the error occurs, then a more specific answer will be forthcoming. The syntax of your code sample looks fine, but the error may be due to another line in your code, perhaps not shown in your question.
Is there any more "efficient" way to do to select a range? Personally, I don't like the method you show, with strings as the arguments for Cells. Strings are messy, and often lead to mistakes and therefore a loss of work efficiency. Why not:
Sheet1.Range(Cells(2,18),Cells(40,11)).Select
' or
Sheet1.Cells(2,11).Resize(39,8).Select
' or
Sheet1.Range("K2").Resize(39,8).Select
Or, define K2:Q40 as a named range in your sheet, calling it e.g. "myRange", and do this:
Sheet1.Range("myRange").Select ' My personal favourite
But why are you using Select? This is usually not necessary. Just write:
Sheet1.Range("myRange").Copy
But then I could ask, why are you using Copy, which is a messy method in its own right?...