Next without For error in Select Case - vba

I'm trying to write a macro that processes data but skips over data points that meet specific criteria. Here's a simplified version of my code:
Set gData = ThisWorkbook.Sheets("Dashboard").Range("E3:E16")
For Each cell In gData
Select Case cell.Value
Case Is = 20
Next cell 'error thrown here
Case Is > 20
'Do stuff
End Select
Next
The compiler is throwing a "Next without For" error in the location noted above. I haven't been able to find a working solution to this problem. Please help!

Set gData = ThisWorkbook.Sheets("Dashboard").Range("E3:E16")
For Each cell In gData
Select Case cell.Value
Case Is > 20
'Do stuff
End Select
Next

Related

Count Rows Until Finding Specific String

I am trying to use Excel VBA to count the number of rows until I hit a specific string and set a variable equal to it.
Something like:
Dim i as Integer
i = Worksheets("Scope Phase Document").Range("A1", Range("A1").End(xlDown)).Find("FACTS - What are we measuring?").Count
I know this isn't the correct syntax and I'm probably missing other stuff, but just using the different functions I currently know, this is what I would hope would do the trick. I get
Run-time error '91' saying "Object variable or With block variable not
set
I have tried a few different ways of doing it, but can't figure out a way that doesn't result in an error.
So I want to start at A1 and count all the rows down until I reach the specific string "FACTS - What are we measuring?".
Any help would be greatly appreciated!
I prefer MATCH, but if the match is not found it throws an error. So we need to test for that:
Dim i As Long
i = 0
On Error Resume Next
i = Application.WorksheetFunction.Match("FACTS - What are we measuring?", ActiveSheet.Range("A:A"), 0)
On Error GoTo 0
If i > 0 Then
' do you stuff with i
End If
So you basically want MATCH():
=MATCH("FACTS - What are we measuring?",A:A,0)
It returns the row number of matched string.
Your code is fine except you should use the Row property. The Count property as you have used it will return 1 because the Find method returns one cell (the first cell where a match is found).
Dim i as Integer
i = Worksheets("Scope Phase Document").Range("A1", Range("A1").End(xlDown)).Find("FACTS - What are we measuring?").Row
Like Scott mentioned, if your text is not found, Excel will throw an error.
I'd do this:
Sub rowcounter()
Dim i As Integer
Range("A1").Select
i = 0
Do
Selection.Offset(1, 0).Select
i = i + 1
Loop Until Selection.Value = "FACTS - What are we measuring?"
MsgBox "rows count is " & i
End Sub

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

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.

VBA code in Excel with pivot tables

The data source will change often. After I refresh the pivot table, I have the following code to update the grade pivot item field. Sometimes grade 4 is available and sometimes it is not. Essentially, If grade 4 is available I want it to be selected and if it is not available then all fields can be select. For some reason when I run it, it stops on the else line. Any suggestions?
ActiveSheet.PivotTables("PivotTable1").PivotFields("Grade").ClearAllFilters
If IsError(ActiveSheet.PivotTables("PivotTable1").PivotFields("Grade").CurrentPage = "4") Then
ActiveSheet.PivotTables("PivotTable1").PivotFields("Grade").CurrentPage = _
"(All)"
Else
ActiveSheet.PivotTables("PivotTable1").PivotFields("Grade").CurrentPage = "4"
End If
You can't trap the PivotField("Grade").CurrentPage error with IsError.
Try the code below:
ActiveSheet.PivotTables("PivotTable1").PivotFields("Grade").ClearAllFilters
On Error Resume Next
ActiveSheet.PivotTables("PivotTable1").PivotFields("Grade").CurrentPage = "4"
If Err.Number <> 0 Then
ActiveSheet.PivotTables("PivotTable1").PivotFields("Grade").CurrentPage = _
"(All)"
On Error GoTo 0
End If
Note: you could clean up your code if you use With statements. In your code, you could use With ActiveSheet.PivotTables("PivotTable1").PivotFields("Grade")

Excel VBA: Detecting empty cell to end loop

In Excel 2007 I have imported data consisting of a column of rows. I wish to set a VBA script to read through the data from top to bottom, using a loop. The loop should continue to iterate while the cell in the sixth column is not empty.
I have tried:
Do While IsEmpty(Cells(i,6)) = False
...
i = i + 1
Loop
...and also
Do While Cells(i, 6).Value <> ""
...
i = i + 1
Loop
The loop does what it is supposed to but an error ensues because the program goes on reading below the block of data. (I inserted "On Error GoTo Catch" in the loop, then after the loop "Catch: MsgBox Cells(i, 6).Value & "Error" so as to confirm that an error occurs).
There is nothing in the loop that would affect Cells(i,6).
There are many questions in Stack Overflow about empty cells but the answers tend to avoid the issue how to detect an empty cell to make a loop end. Is there a way of doing this?
Provided you're on the right sheet (replace below) the code you posted should work
i = 1
Do While sheets("sheet1").Cells(i, 6).Value <> ""
i = i + 1
Loop
Could you post a screenshot of the column end? Your error handling may be preventing the error message too, try disabling that temporarily. Do the columns all end on a certain row? You could specify "do while not blank AND row < end row".

Runtime error "424: Object Required"

I am having difficulties with this code. I am trying to make it so that based on the value of cell D25 the value of F25 will change. I made the code in VBA (don’t know if this is actually the best way) and it is giving me a 424 runtime error: Object Required. Could someone please point me in the right direction?
Sub Storage_vesel_Controle()
Sheets("NSR Form").Select
If Range("D25") = "1" Then Range("F25").Select.Value = "0"
If Range("D25") = "2" Then Range("F25").Select.Value = ".95"
If Range("D25") = "3" Then Range("F25").Select.Paste = ".98"
End Sub
Also, what do I need to add to make the code "always running"... in loop I think?
Further to my comment above, I wasn't planning on posting an answer but saw few things which I think I will bring to your notice and comments wouldn't accommodate so much of text.
I would recommend not using .Select to select the sheet but work with the sheet directly (See Below code) You might also want to see this link
Sub Storage_vesel_Controle()
With Sheets("NSR Form")
Select Case .Range("D25").Value
Case 1: .Range("F25").Value = 0
Case 2: .Range("F25").Value = 0.95
Case 3: .Range("F25").Value = 0.98
End Select
End With
End Sub
EDIT:
Regarding your edit. You can use the Worksheet_Change Event to ensure that the values of F25 gets automatically updated or if you want a non VBA solution then simply use a Formula in F25
If you are interested in Worksheet_Change then see this. Else a simple formula like this in F25 will suffice your needs :)
=IF(D25=1,0,IF(D25=2,0.95,IF(D25=3, 0.98,"")))
Clean it up a little bit. Using a Select Case statement will be easier to work with than mutliple If/Then statements.
Sub Storage_vesel_Controle()
With Sheets("NSR Form")
.Activate '<this line is not actually necessary unless you want to be on the sheet.
Select Case .Range("D25").Value
Case 1
.Range("F25").Value = 0
Case 2
.Range("F25").Value = 0.95
Case 3
.Range("F25").Paste = 0.98
Case Else
'do nothing, or, modify as needed
End Select
End With
End Sub