VBA How to Check if Cell Value is valid and exists? - vba

I have this cell.Offset(0, -2) cell that I need to check if it exists inside my VBA loop.
My idea is that if the cell has an .Offset(0, -2) that does not exist (e.g. say cell = Column B and cell.Offset(0, -2) = Column A-1, cell.Offset(0, -2) is supposed to be invalid), I want to be able to check that it doesn't exist in the if else statement.
Right now when it doesn't exist, I'm getting a “Runtime Error 1004: Application defined or object defined error”.
I've tried IsErr(cell.Offset(0, -2)), cell.Offset(0, -2).Value, If cell.Offset(0, -2) Is Nothing Then, cell.Offset(0, -2) = "", but none of them seem to work... can anyone point me in the right direction? I'm pretty new to VBA and it seems like different variable types have different ways of checking if the value exists.

If you can use your offset amount as a variable, or some method to evaluate against the cell's column, you don't need to defend against errors. Consider below...
Sub IsvalidARea()
Dim OffsetAmount As Integer: OffsetAmount = -2
Dim Cell As Range
If Cell.Column + OffsetAmount < 1 Then
MsgBox "Oh FALSE!"
Else
'EVERYTHING IS OKAY!
End If
End Sub

A solution for this is by using the constantly misused On Error Resume Next, coupled with a If IsError. Here's an example:
On Error Resume Next
If IsError(ActiveCell.Offset(, -2).Select) = True Then
'This is indicative of an error. Meaning you are on Column B, and you ran out of space.
Else
'This means an error did not occur. Meaning you were at least on Column C or above.
End If
There may be a better solution, in fact I am sure there is. But what this will do is allow you to move past the actual 1004 Application error, and you can actually identify, and use the error that was really returned, instead of just forcing your macro/script to end.
To avoid using the error check, you can always check the current column index (B is 2) and make sure whatever you are offsetting by, once subtracted by your index is greater than 0. For example, column B is 2. Your offset is 2. 2 - 2 = 0, so it should not attempt it. Column C is 3, 3 - 2 = 1, which is greater than 0 so it would be valid. Both are explorable methods.

Related

Excel VBA - How to validate input to be in certain column

I have a script that asks for a starting cell
Set myCell = Application.InputBox( _
prompt:="Choose a starting field", Type:=8)
If myCell = Null Or myCell = "" Or Len(myCell.Value) < 3 Or Len(myCell.Value) > 12 Then
MsgBox "Incorrect cell value"
Exit Sub
Else
So, I have these checks for the value of the given cell so the script will not run if the validation does not go through. What I need is also for the validation to check whether the cell in certain column (D in my case).
So I need the validation to say "IS the selected cell in column D?" If Yes, continue, if no stop.
I've relentlessly googled to try to find this kind of comparison but I just fail to give it a good query.
Any help is appreciated. Thanks
With the help of Rich Holton I found the solution.
In order to check whether the input cell is in the column you want it to the following syntax can be used:
If myCell.Column <> 4 Then
...
End If
Where 4 is equal to Column D in this case. (Column A = 1, Column B = 2 and so on...)

Type mismatch when passing an array

I keep on getting an error when I try and pass this value to an array, essentially I am working with exchange rates, I have the currency in the second dimension of the array ary() and I am looking to retrieve a data point in a table that is 2 cells away from the element stored in the array.
Now I believe the problem has something to do with the value being a number and the array being a variant, however I cannot solve the problem.
Option Explicit
Dim fxary(), y
ws.Select
Set Rng = Sheets("BEXR").Range("C2:C" & Sheets("BEXR").Range("A1").End(xlDown).Row)
For i = 1 To UBound(ary, 2)
If ary(2, i) <> ary(2, UBound(ary, 2)) Then
For Each y In Rng
If Sheets("BEXR").Range(y.Address).Value = ary(2, UBound(ary, 2)) And Sheets("BEXR").Range(y.Address).Offset(0, 1).Value = ary(2, i) Then
fxary() = Sheets("BEXR").Range(y.Address).Offset(0, 2).Value ' error occurring here
fxary = ary(1, i)
End If
Next y
End If
Next
Your comments say that I have omitted all the lines not related to this specific problem, therefore I will post an answer based on the assumption that all the lines that are related to the problem have been included in the code in the question.
The following comments should be made about your code:
You have used Option Explicit but nowhere do you declare the size or type of the variables i and ary.
Nowhere do you specify values for the variable ary.
Your line saying fxary() = Sheets("BEXR").Range(y.Address).Offset(0, 2).Value is trying to assign a scalar to a vector, and will generate a Type Mismatch error.
Your line saying fxary() = Sheets("BEXR").Range(y.Address).Offset(0, 2).Value is immediately followed by a line (fxary = ary(1, i)) replacing the value of fxary with something else, so the first line is redundant.
All your references to Sheets("BEXR").Range(y.Address) can be replaced with y.
You are executing through two loops (from 1 to whatever the second dimension of the undefined variable ary is and, within that loop, through every cell in column C of your sheet), but you are effectively only setting fxary once, i.e. to the value in the undefined variable ary where the first dimension's value is 1 and the second dimension's value is i. (But I haven't been able to wrap my mind around the code enough to be able to work out which value of i that will end up being - I think it's worked out by looking at each row of your sheet that has a different value in column C than in column D, and the value in column C is equal to ary(2, highest value), and then determining the highest value of i such that ary(2, i) will equal the value in column D.)
I believe you need to look at each of the above items before your code will do anything meaningful, but to resolve the specific problem you say you are having:
1) Change your declaration of fxary to
Dim fxary, y
2) Simply remove the line saying
fxary() = Sheets("BEXR").Range(y.Address).Offset(0, 2).Value
as that line is redundant (as I said in one of my earlier points).

Check if value exists in range without looping

I'm used to python syntax where to check if 7 is in list1 you simply type 7 in list1 and it returns a boolean. How can I perform something like this in vba?
I'm currently looping through a large range. I want to occasionally check if a value i'm looping over is in a different range. This could get much slower if I had to nest more loops into my loops. What's the fastest way to approach this problem?
For i = 400 To 1 Step -1:
'doing other things
'here's some psuedo-code of what I want to do
If Sheets("Sheet2").Cells(i, 2).Value In Sheets("Sheet1").Range("NamedRange")
Sheets("Sheet2").Cells(i, 2).EntireRow.Delete
End If
Next i
Use a countif, if it's greater than zero then you know it exists in the list:
If Application.WorksheetFunction.CountIf(Sheets("Sheet1").Range("NamedRange"), Sheets("Sheet2").Cells(i, 2).Value) > 0 Then
Sheets("Sheet2").Cells(i, 2).EntireRow.Delete
End If
Here is how you can achieve it in just one line
If Not IsError(Application.Match(ValueToSearchFor, RangeToSearchIn, 0)) Then
// Value found
End If
Example:
Search for Blah-Blah in column A of Sheet5
If Not IsError(Application.Match("Blah-Blah", Sheets("Sheet5").Range("A:A"), 0)) Then
'The value present in that range
End If

How do i add + 1 to activecell in vba

I am kept on getting run time 13 error. all i am trying to do add 1 to activecell.
dim rang as range
rang = activecell + 1
msgbox rang
You're not setting the rang reference.
Set rang = ActiveCell
One problem down.
You're relying on implicit conversions and default properties, which makes it much harder than it needs to be, to understand what's going on.
rang.Value = CLng(ActiveCell.Value) + 1
MsgBox rang.Value
If that blows up with a runtime error 13, then ActiveCell.Value isn't an integer value. You can't legally add +1 to a String... Or do anything (including mere comparison) with an error value. Use IsError to determine if the cell contains a value you can work with, before you work with it:
If Not IsError(rang.Value) Then
MsgBox rang.Value
End If
You want to reference the active cell's value, like this
rang = ActiveCell.Value + 1
Edit - Runtime error 13 is a type mismatch, basically you are trying to combine incompatible data types (assuming the active cell contains a number, not a number formatted as text). Try this.
Dim rang as Integer
rang = ActiveCell.Value + 1
msgbox rang
You can convert numbers formatted as text to numeric values by copying a cell with a one in it, then paste special, and select multiply (assuming the content is valid as a number)
Sub addOne()
ActiveCell = ActiveCell.Value + 1
End Sub
Try This. This will simply add 1 in current value. Make sure its not a string value in active cell. Hope This help.

Comparing cells using match in vba

I am trying to compare two columns of cells in vba using the match function. I am comparing the second column against values in the first and copying and pasting the values that aren't found to another column. I am doing the same with the second against the first as well. For some reason when I try to run this it says that it cannot get the match property of the worksheet function class and I am really confused as to why I am receiving this error. I have pasted the code below. Any help with this issue would be greatly appreciated.
Set PrevMonth = Sheet13.Range(Range("A2"), Range("A2").End(xlDown))
Set currMonth = Sheet13.Range(Range("B2"), Range("B2").End(xlDown))
Count = 2
For i = 2 To PrevMonth.Rows.Count
match = Application.WorksheetFunction.match(Cells(i, 1), currMonth, 0)
If WorksheetFunction.IsNA(match) = True Then
Sheet13.Cells(i, 1).Cut
Sheet13.Cells(Count, 3).Paste
Count = Count + 1
End If
Next i
For i = 2 To currMonth.Rows.Count
match = WorksheetFunction.match(Cells(i, 1), PrevMonth, 0)
If WorksheetFunction.IsNA(match) = True Then
Sheet13.Cells(i, 1).Cut
Sheet13.Cells(Count, 4).Paste
Count = Count + 1
End If
Next i
Can you try using
Application.Match(Cells(i, 1), currMonth, 0)
I know this should have been a comment...but I'm unable to comment as I'm below 50 Rep...
In my experience the "cannot get 'X' property of the worksheet function class" error is indicative that a poor argument has been passed to the worksheet function itself. In your case the arguments are: Cells(i, 1), currMonth. This likely means one of those ranges are inaccessible. If I had to guess, you want to be passing sheet13.cells(i,1). I'd recommend a 'with sheet13' statement for this whole segment of code. WorksheetFunction.Match in particular will throw that error if a match can't be found (VB doesn't work with the #N/A return value). Using a WorksheetFunction.CountIf > 0 can ensure there is a viable match within the range.
Also, Range("A2").End(xlDown) will result in the last cell of the column if there is no data after A2. This is generally unfavorable behavior.