Excel VBA Make Cell Active in a Specified Range - vba

I'm not sure why the following code gives a "Not found" Message when the value in the initial active cell (-15.0) is also a value within the specified range.
Sub Test()
Dim c As Double
Dim srchRng As Range
With ActiveWorkbook.ActiveSheet
c = ActiveCell.Select
Set srchRng = .Range("V17:V37").Find(what:=c)
If srchRng Is Nothing Then
MsgBox "Not found"
End If
End With
End Sub
Note sometimes a value of 0 exists within the specified range. If so I don't need to do anything but if 0 does not exist, I first need to find the least negative value (I use separately within the worksheet =MAX(IF(V17:V37<=0,V17:V37),MIN(V17:V37)) and this becomes my initial active cell value [eg -15.0] to look for in the specified range), and this least negative value will then be set to zero (by using a goal seek function in this cell)
So this macro will ultimately incorporate an If statement or conditional lookup
Any feedback appreciated.
I made suggested changes but revised code below still returns "Not found".
Cell V38 has the value -15.0 but this number does appear in the range V17:V37.
This simple macro should result in the cell in the range corresponding to the c value being selected. Any further help appreciated.
Dim c As Double
Dim srchRng As Range
With ThisWorkbook.Sheets("Reel_Pack")
c = Range("V38")
Set srchRng = .Range("V17:V37").Find(what:=c)
If srchRng Is Nothing Then
MsgBox "Not found"
End If
End With
End Sub
I found the following code to do the above.
Dim c As Double
c = ThisWorkbook.Sheets("Sheet1").Range("V58").Value
Dim cel As Range
For Each cel In ThisWorkbook.Sheets("Sheet1").Range("V17:V57")
With cel
If .Value = c Then
.Select
End If
End With
Next cel
End Sub
But can someone suggest please how to improve this by actually incorporating the equation I have in cell V58 within this macro? As mentioned that equation is =MAX(IF(V17:V37<=0,V17:V37),MIN(V17:V37)).
So the macro would look into the range V17:V37 and if there is an exact zero then Do Nothing otherwise locate the cell with the least negative number (which is what the equation above does) and select that cell.

I hope this is the correct reason:
c = ActiveCell.Select is returning the value -1 which equates to TRUE in VBA.
So, I think, the line is asking the question c = ActiveCell is Selected? which returns a boolean TRUE/FALSE converted to a double which equals -1.
c = ActiveCell returns the default property of the ActiveCell which is Value.
So that line should read c = ActiveCell or c = ActiveCell.Value rather than c = ActiveCell.Select.
Edit:
Not so sure of my reasoning now - c= Range("A1").Select selects cell A1 and returns -1 still.
I guess that why you should avoid Select like the plague unless you want to actually select a cell rather than just reference it. Have a read of How to avoid using Select in Excel VBA

Related

Change cell color based on another cell value

In a workbook I have, the D column has a formula in it to derive the last six digits of a value in column C. These columns are located in a sheet titled "JE". I have a dynamic SQL connected query that has values in the A column. That query is located in a sheet titled "required_refs". I essentially, want to write: If the value in the D column cell matches/equals any of the values in that query in sheet "required_refs", turn the F column cell red in sheet JE.
Example: If cell D10 has a value that equals any of the values in column A in "required_refs", turn cell F10 red. In addition, if cell D13 has a value that matches/equals a value in column A in sheet "required_refs", turn F13 red. And so on.
Here is the code I tried. I added it in Sheet "JE":
Code:
Sub ChangeCellColor()
Dim ref_code As Range: Set ref_code = Range("D7:D446").Value
Dim refCode_Confirm As Range: Set refCode_Confirm = Worksheets("required_refs").Range("A:A").Value
Dim colorChange As Range: Set colorChange = Worksheets("required_refs").Range("A:A")
For Each cell In ref_code
If cell.Value = refCode_Confirm.Value Then
Range("F7:F446").ActiveCell.Interior.ColorIndex = 3
Next cell
End If
End Sub
Currently, this code just doesn't do anything. It doesn't turn the F column cell red. I've asked a question similar to this but, the workbook I'm using has changed a bunch since then, and this question is a bit more simple than the previous one.
If anyone could help, I'd really appreciate it. Thanks!
Your code has a number of issues.
.Value returns a basic type, like a string or long. You can't assign this to a range variable.
Your End If and Next cell statements are swapped around. Always use correct indentation so these errors become more obvious.
You have an undeclared variable cell. This can potentially cause bugs. In the VBE, turn on the Tools > Options > Editor > Required Variable Declaration option to force the use of Option Explicit in new modules.
Fixing these issues leads us to this:
Sub ChangeCellColor()
Dim cell As Range
Dim ref_code As Range: Set ref_code = Range("D7:D446")
Dim refCode_Confirm As Range: Set refCode_Confirm = Worksheets("required_refs").Range("A:A")
Dim colorChange As Range: Set colorChange = Worksheets("required_refs").Range("A:A")
For Each cell In ref_code
If cell.Value = refCode_Confirm.Value Then
Range("F7:F446").ActiveCell.Interior.ColorIndex = 3
End If
Next cell
End Sub
Unfortunately, it still doesn't work as you can't compare a single value directly against a column of values in VBA.
This following code corrects this remaining issue. Note the choosing of good meaningful names as well as the use of RVBA for the variables. This is a good tip for how to avoid making similar errors. Also note the use of .Value2 instead of .Value. This is highly recommended.
Sub ChangeCellColor()
Dim rngRef As Range
Dim rngRefsToCheck As Range: Set rngRefsToCheck = Range("D7:D446")
Dim rngRequiredRefs As Range: Set rngRequiredRefs = Worksheets("required_refs").Columns("A")
Dim rngColorChangeRequired As Range: Set rngColorChangeRequired = Columns("F")
For Each rngRef In rngRefsToCheck
If Not IsError(Application.Match(rngRef.Value2, rngRequiredRefs, 0)) Then
rngColorChangeRequired.Cells(rngRef.Row).Interior.ColorIndex = 3
End If
Next rngRef
End Sub
The best and fastest way to achieve the color change would be to use Advanced Filters, thus avoiding the need to loop. However, since you're still learning the basics, I've shown the looping version.

VBA - Error when using ActiveCell and CurrentRegion

I'm trying to write a small piece of VBA that will shade a column of excel cells based on RGB variables in adjacent columns. So I have a table of data (no headings) with 3 columns (R G and B) and x rows (amount will vary). What I would like is to colour a 4th column to the right of this table in a colour based on the 3 numbers to the left. Note that I plan to select the top left cell each time I perform this.
Below is the code I have used but I get an error message:
Error 438... Object doesnt support this property or method
pointing to the Set rng line as being the problem.
Any thoughts or help much appreicated
Sub RGBTest()
Dim rng As Range
Dim n As Integer
Set rng = ActiveSheet.ActiveCell.CurrentRegion
ActiveCell.Offset(0, 3).Activate
For n = 1 To rng.Rows.Count
ActiveCell.Interior.Color = RGB(rng.Cells(n, 1), rng.Cells(n, 2), rng.Cells(n, 3))
ActiveCell.Offset(1, 0).Activate
Next n
End Sub
So the line
Set rng = ActiveSheet.ActiveCell.CurrentRegion
causes the error Error 438... Object doesnt support this property or method.
That means either ActiveSheet doesn't support .ActiveCell or ActiveCell doesn't support .CurrentRegion.
ActiveCell is a range and CurrentRegion is a property of Range so that shouldn't be it.
However, ActiveCell is not a property of a worksheet but of Application. That makes sense since there is only one active cell per Excel instance, not per sheet. So instead of
Set rng = ActiveSheet.ActiveCell.CurrentRegion
just use
Set rng = ActiveCell.CurrentRegion

IF THEN VBA MACRO - Update one column if contents of another = 100%

I have a workbook with "Results" being sheet 3, this being the worksheet I want to use.
I have tried a few formulaes to try and add a macro to do the following:
I have column G with percentages. I then have column I where I would like there to be a result saying TRUE/FALSE where the contents of G are equal to 100%. Column G is formatted to percentage with two decimals.
Some considerations: I have my first row being a Hyperlink to another sheet, then my headings, then the first row of "results". I have 457 rows, if there is a measurement of the range, perhaps it could be on A?
I keep getting this error 9 with my range and have got a bit stuck.
Thanks in advance!
Sub PartialHits1()
Dim rng As Range
Dim lastRow As Long
Dim cell As Range
With Sheet3
lastRow = .Range("G" & .Rows.Count).End(xlUp).Row
Set rng = .Range("G1:G" & lastRow)
For Each cell In rng
If cell.Value = 100
Then
cell.Range("I1:I1").Value = 100
End If
Next
End With
End Sub
(I have hacked this a bit, just was trying to get it to set as 100 instead of the TRUE/FALSE Also was playing around near the Sheet 3 part as I got errors.)
RangeVariable.Range can refer only to a cell within RangeVariable, so you can't refer to column I in this way. Try: .Range("I"&cell.row)=100.
Also your criteria is probably wrong, if you have 100% in a cell it's actual value is 1.
And last question: why do you want to do this with VBA, it would be much more simple with worksheet function =IF(G3=1,100,"")

Selection.SpecialCells() method returns unexpected range (Excel VBA)

When I select a range of three cells say B3:B5, the method acts as expected and displays three messages with "3", "4" and "5".
Sub visTest()
Dim c As Range
For Each c In Selection.SpecialCells(xlCellTypeVisible)
MsgBox c.row
Next c
End Sub
The problem is when I select only one cell:
the Selection.SpecialCells(xlCellTypeVisible) returns ALL visible cells on the worksheet and starts from the cell A1.
How do I make it return only one visible cell within the one selected cell?
Why the problem occurs?
Thanks!
This will perform the correct restriction:
Sub visTest()
Dim c As Range
For Each c In Intersect(Selection, Selection.SpecialCells(xlCellTypeVisible))
MsgBox c.Row
Next c
End Sub
The reason it returns all used cells on the worksheet is that SpecialCells method, as many other methods in Excel, assumes you want the used range of the worksheet if your specified range only contains a single cell.
to eliminate the problem with incorrect range when using "specialCells" just put this line to the code
If Selection.Cells.Count > 1 Then Selection.SpecialCells(xlCellTypeVisible).Select
End If
This way excell will use this method only when actually sellected region consists of more than one cell.

Copy/Paste cells next to cells that have certain string

I am trying to look up cells in a certain column that have a string (e.g. Names), copy the corresponding cells in the column to its right (i.e. offset(0,1) ), then paste it to a column in a different sheet. I have the following code to find the range variable that I want. However, I can't select it from a different sheet!
When I use Sheets(1).MyRange.Copy, it doesn't accept it. Am I referring to the range in a wrong way? What am I doing wrong?
Here's code that I use to get MyRange:
Option Explicit
Sub SelectByValue(Rng1 As Range, Value As Double)
Dim MyRange As Range
Dim Cell As Object
'Check every cell in the range for matching criteria.
For Each Cell In Rng1
If Cell.Value = Value Then
If MyRange Is Nothing Then
Set MyRange = Range(Cell.Address)
Else
Set MyRange = Union(MyRange, Range(Cell.Address))
End If
End If
Next
End Sub
Sub CallSelectByValue()
'Call the macro and pass all the required variables to it.
'In the line below, change the Range, Minimum Value, and Maximum Value as needed
Call SelectByValue(Sheets(1).Range("A1:A20"), "Tom")
End Sub
One More Question: Rather than specifying the exact range to look at (e.g. "A1:A20"), I would LOVE to look at all of column A. But I don't want to use ("A:A") so it wouldn't look at all rows of A. Isn't there a method to look only in cells that have entries in column A?
Thank you VERY much.
Al
You only need MyRange.Copy.
To restrict only to cells in column A which might have values, you could use
With Sheet1
Set rngToSearch = Application.Intersect(.Columns(1), .UsedRange)
End With
...or maybe look at .SpecialsCells()