Reputation: 187
I'm trying to change all letters into capital letters in all cells holding data in column B2 and down. Got this VBA.
Sub CapitalLettersColumnB()
'Capital Letters to names in column B (from B2 and down)
'Column B holds headers!
With Range("B2", Cells(Rows.Count, "B").End(xlUp))
.Value = Evaluate("INDEX(UPPER(" & .Address(External:=True) & "),)")
End With
End Sub
When my sheet holds 2 rows of data (and more), not counting headers, the vba works just fine. But when my sheet only holds 1 row of data, not counting headers, name in column B (cell B2) is replaced with #VALUE!. Anyone that can help spot what's wrong, and how to correct my vba?
Upvotes: 1
Views: 142
Reputation: 75860
The problem is INDEX
. The funtion returns a position in a Range
or Array
, not a single value. If you would evaluate the formula it would come down to this:
=INDEX("VALUE",)
Instead of a correct:
=INDEX({"VALUE1","VALUE2"},)
Not feeding the INDEX
a range or array will then return the error
To correct your code you need to make sure there is always a range object larger than one cell, so for example:
Sub CapitalLettersColumnB()
With Range("B1", Cells(Rows.Count, "B").End(xlUp))
.Value = Evaluate("IF(ROW(" & .Address & ")>1,INDEX(UPPER(" & .Address & "),)," & .Address & ")")
End With
End Sub
This will now work from B1
onwards, but will leave that cell intact through the ROW
test in our IF
statement.
Another small note, I would definately use an explicit cell reference (including at least a worksheet)
Upvotes: 3
Reputation: 23958
Honestly not sure what is wrong. (I think it's the same reason as range("B2:B2"). You can't set a range spanning the same cell)
Your Cells(Rows.Count, "B").End(xlUp)
returns the value of the last cell which I'm not sure how that works.
But you could change the code to do a with the range to lastrow.
But if the lastrow is 2 the code will fail, so the if goes to else and it only changes the Ucase of cell B2.
If Cells(Rows.Count, "B").End(xlUp).Row > 2 Then
' more than one row after B2
With Range("B2:B" & Cells(Rows.Count, "B").End(xlUp).Row)
.Value = Evaluate("INDEX(UPPER(" & .Address(external:=True) & "),)")
End With
Else
' no rows past B2
Range("B2").Value = UCase(Range("B2").Value)
End If
Upvotes: 1