I am trying to highlight rows in Excel if they have a numeric values in this column (others are blank), however this code highlights all of them:
For lRow = LastRow To FirstRow Step -1
With .Cells(lRow, "AF")
If IsNumeric(.Value) Then
.EntireRow.Interior.Color = 5296274
End If
End With
Next lRow
Any advice or assistance will be appreciated.
The safest way to check for Numeric values in a cell is also check that the cell is not empty, or contains only spaces, for that you can use Trim(.Value2) <> "".
Code
If IsNumeric(.Value) And Trim(.Value2) <> "" Then
.EntireRow.Interior.Color = 5296274
End If
Edit 1: Faster run-time code.
Using VBA, the tasks which consume the longest are the ones accessing the worksheet, in this case it's .EntireRow.Interior.Color = 5296274.
What we can do, is use a Range object, in my code it's ColorRng, and every time the If criteria is met, we add that cell to this Range, using the Union function. At the end of the code, we just change the color of the EntireRow in ColorRng, which will result coloring the entire rows which are not numeric at one shot.
Modified Code
Option Explicit
Sub ColorEmptyRows()
Dim ColorRng As Range
For lRow = LastRow To FirstRow Step -1
With .Cells(lRow, "AF")
If IsNumeric(.Value) And Trim(.Value2) <> "" Then
If Not ColorRng Is Nothing Then
Set ColorRng = Application.Union(ColorRng, .Cells(lRow, "AF"))
Else
Set ColorRng = .Cells(lRow, "AF")
End If
End If
End With
Next lRow
' if the range has at least 1 cell, color the entire range at the same time
If Not ColorRng Is Nothing Then ColorRng.EntireRow.Interior.Color = 5296274
End Sub
Empty cells are also considered as numeric with that function. You can use If Isnumeric(.Value) and .Value <> "" Then for instance.
Related
I am working on a spreadsheet that utilizes user input to fill out a table. This data is entered into a table with numerous columns required. I have a command button that creates a new row and inserts all the data validation necessary for a new line item (below is an example.)
My problem revolves on a specific a column (blue circle) where other cells rely on based on a "yes" or "no" string. If the column has a "yes", the adjacent cells do something. If the column has a "no", the adjacent cells do something different.
As this table grows in rows, my column range I am focused on will change dynamically. I want the VBA code to run if the worksheet experiences a change event in that dynamic range utilizing the "Worksheet_Change(ByVal Target As Range) sub.
Right now, I am defining that dynamic range in my commandbutton_click sub because everytime i click the button, a new row is added thus I need the spreadsheet to be aware that my range has changed (see my code below).
Sub CommandButton1_Click()
Application.EnableEvents = False
Dim LastRowEntry As Long
Dim DeviceNo As Integer
'Dim RTUTable As Range
'Determine the last entry row & Copy
LastRowEntry = Sheet1.Cells(Rows.Count, 1).End(xlUp).Row
DeviceNo = Sheet1.Cells(Rows.Count, 1).End(xlUp)
Sheet1.Cells(Rows.Count, 1).End(xlUp).EntireRow.Copy
'Once the last row is determined, go to the next row to paste
Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormats
Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValidation
'Incase the above cell has Conditional Formatting, we set the color back to "white"
Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).EntireRow.Interior.ColorIndex = 0
Application.CutCopyMode = False
ActiveCell.Value = DeviceNo + 1
With RTUTable
RTUTable = Sheet1.Range(("G7"), Sheet1.Cells(LastRowEntry + 1, "G"))
End With
Application.EnableEvents = True
End Sub
Then, in a different sub I enter code that will "check" to see if that dynamic range has had a change in value with a "yes" or "no" answer. This is where I enter my defined dynamic range (see my code below).
Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
'This code checks to see if the Device is polled by RTU
If Not Intersect(Target, Range(RTUTable)) Is Nothing Then
If ActiveCell.Value = "NO" Then
"DO SOMETHING"
Else
"DO SOMETHING"
End If
End If
Application.EnableEvents = True
End Sub
Can someone help me out on the error message "Type mismatch" I am receiving? Am I entering the dynamic range correctly into the intersect code?
Thank you
****Update - More information for Clarification*****
I have added some information in the array I am evaluating. Below is a snapshot of my spreadsheet.
When I go into the Debug mode, I am viewing my "Locals table" and see I am successfully capturing my information in an array.
I need to run the intersect command with this array
This has been resolved. Below is the code I used to determine the dynamic range and then the code evaluates that range for a change.
Dim dyString As String
Dim dyRange As Range
Dim LastRowEntry_1 As Integer
Dim i As Integer
LastRowEntry_1 = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(-2, 0).row + 1
dyString = "G8:G" & LastRowEntry_1
Set dyRange = Range(dyString)
If Not Intersect(Target, dyRange) Is Nothing Then
For i = 1 To 6
If ActiveCell.Value = "NO" Then
Target.Offset(0, i).Interior.ColorIndex = 23
Target.Offset(0, i).Font.Color = vbWhite
Target.Offset(0, i).Value = "N/A"
Target.Offset(0, i).Locked = True
ElseIf ActiveCell.Value = "YES" And ActiveCell.Offset(0, i).Value = "N/A" Then
Target.Offset(0, i).Value = ""
Target.Offset(0, i).Interior.ColorIndex = 0
Target.Offset(0, i).Font.Color = vbBlack
Target.Offset(0, i).Locked = False
To summarize:
No matter what, my dynamic range will always begin at cell "G8"
After that, the range will change dynamically. Either grows or shortens depending on
the info. So my "LastRowEntry_1" determines where that last cell entry is. (Note: I
had to offset it because of some footer information on my spreadsheet)
I created a string where I could combine the range of the fixed cell to the dynamic
cell.
Then I set that string as a range.
Then based if the target range was intersected or not, I run a "For" loop to perform
my conditional formatting.
I have a sheet FC, with this sheet, I have column R, S and T filled.
I would prefer to have a code, which checks if R contains "invalid" and if S and t are filled, then it should filter complete row.
I know we can use isblank function to check whether the cell is blank or not,
but I am struck how I can use a filter function with these condition .Any help will be helpful for me. I am struck how I can proceed with a vba code. Apologize me for not having a code.
You will have to somehow specify last row:
Dim lastRow, i As Long
For i = 1 To lastRow 'specify lastRow variable
If InStr(1, LCase(Range("R" & i).Value), "invalid") > 0 And Range("S" & i).Value = "" And Range("T" & i).Value = "" Then
'do work
End If
Next i
In our If condition we check three things that you asked.
Try this
Sub Demo()
Dim lastRow As Long
Dim cel As Range
With Worksheets("Sheet3") 'change Sheet3 to your data sheet
lastRow = .Cells(.Rows.Count, "R").End(xlUp).Row 'get last row in Column R
For Each cel In .Range("R5:R" & lastRow) 'loop through each cell in range R5 to lase cell in Column R
If cel.Value = "invalid" And Not IsEmpty(cel.Offset(0, 1)) And Not IsEmpty(cel.Offset(0, 2)) Then
cel.EntireRow.Hidden = True 'hide row if condition is satisfied
End If
Next cel
End With
End Sub
EDIT :
To unhide rows.
Sub UnhideRows()
Worksheets("Sheet3").Rows.Hidden = False
End Sub
Assuming Row1 is the header row and your data starts from Row2, in a helper column, place the formula given below.
This formula will return either True or False, then you may filter the helper column with either True or False as per your requirement.
=AND(R2="Invalid",S2<>"",T2<>"")
In case your header row is different, tweak the formula accordingly.
sub myfiltering()
'maybe first row always 4
firstrow=4
'last, maybe R column alaways have any entered info, so let us see what is the last
lastrow=cells(65000,18).end(xlup).row
'go ahead
for myrow=firstrow to lastrow
if cells(myrow,18)="Invalid" and cells(myrow,19)="" and cells(myrow,20)="" then
Rows(myrow).EntireRow.Hidden = True
else
Rows(myrow).EntireRow.Hidden = false
end if
next myrow
msgbox "Filter completed"
end sub
hope this will help you :)
Why you need the vba code for this problem?
Its more simple if you add a new column with if & and formula, and autofiltering within the added col.
The formula may be similar like this in the U2 cell.
=if(and(R2="invalid";S2="";T2="");"x";"")
Also set autofilter to x. :)
I'm new to VBA and English isn't my native language so here goes.
I want to conditional format rows/ range (giving them green-colored background) if cell C in that row have duplicate value in column C and also if there's a cell in column O that equals 0, but if the cell in column C has no similar value, don't apply the conditional format to that cell (eventhough cells in column O has the value of 0).
Note: Cells that have same values in column C will always be above and below each other, for example it's possible that C1=C2=C3 but not C1<>C2, C1=C3
I know I'm not explaining it clearly, so please just let me know if you want more information.
Update (more information): I may have 3 or more rows with same C column value above and below each other, and the zero value in column O will always be the bottom row.
Example:
If C1=C2=C3=C4=C5 and O5=0 , Rows 1 2 3 4 5 become green colored.
I prefer using conditional format even if it needs vba code so I dont have to run it everytime there's new 0 in column O.
I've used this code but it doesn't work (obviously), but maybe it's a little different with my question because the real data is more complicated than what I illustrated. My data table starts at 4th row (header on 3rd). This code only formats 1 row (above the row that has zero column O value) and what I need is all rows with same column C value are formatted. Please keep in mind that I'm a newbie in vba :(
With Range("A4:r8000").FormatConditions.Add( _
Type:=xlExpression, _
Formula1:="=AND($C4=$C5,$O5=0,$F4<>0)")
.Interior.Color = 13551615
.Font.Color = -16383844
End With
Try this as the formula for the CFR,
=and(countif(c:c, c1)>1, o1=0, len(o1))
'alternate for part that I am not sure I understand
=and(countif(c$1:c1, c1)>1, o1=0, len(o1))
This will go through and highlight duplicate cells if any of the duplicate cells' rows have '0' in column O. I am still working on a way that will make this auto update whenever a change happens in Column O, but can't quite figure that out. Will update when I do.
Sub ConditionalFormatSE()
Application.ScreenUpdating = False
Dim lastRow As Long
Dim myCell As Range
Dim colCVals As Range
lastRow = Cells(Rows.Count, 3).End(xlUp).Row
Set colCVals = Range("C1", "C" & lastRow)
colCVals.clearformats
For Each myCell In colCVals
If Cells(myCell.Row, 15).Value = "0" Then
If WorksheetFunction.CountIf(colCVals, myCell.Value) > 1 Then
Set c = colCVals.Find(myCell.Value)
If Not c Is Nothing Then
firstAddress = c.Address
Do
c.Interior.color = RGB(198, 239, 206)
c.Font.color = RGB(0, 97, 0)
Set c = colCVals.FindNext(c)
Loop While Not c Is Nothing And c.Address <> firstAddress
End If
End If
End If
Next myCell
Set colCVals = Nothing
Set myCell = Nothing
Set c = Nothing
Application.ScreenUpdating = True
End Sub
As for making it run automatically, put this in: VBAProject([workbookname].xlsm)->Microsoft Excel Objects->Sheet1([sheetname]) and it should run whenever a value in column 'O' is changed
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Set KeyCells = Columns(15)
If Not Application.Intersect(KeyCells, Range(Target.Address)) Is Nothing Then
Call ConditionalFormatSE
End If
Set KeyCells = Nothing
End Sub
If cells with same values are always grouped (one below the other), following code might do what you want.
Sub Test()
Dim lLastRow As Long
Dim i As Integer
lLastRow = Worksheets("Sheet1").Cells(Rows.Count, 3).End(xlUp).Row
For i = 1 To lLastRow
If ((Worksheets("Sheet1").Cells(i + 1, 3).Value = Worksheets("Sheet1").Cells(i, 3).Value) And (Worksheets("Sheet1").Cells(i, 15).Value = "0")) Then
Worksheets("Sheet1").Cells(i, 3).Interior.Color = vbGreen
End If
Next i
End Sub
Needing help with the following.
I want for the first column: To auto fill the remaining blank spaces until another value is found. Example: RMDSADMN would be autofilled until TXAADGLI is found, then this would be autofilled until TXAADM, then this would get filled one time since there is one blank space.
I tried adding input boxes where I had to manually insert the name of each value but I am aiming for something that automatically checks the values, instead of me inserting them.
Try,
with activesheet
with .cells(1,1).currentregion
.specialcells(xlcelltypeblanks).formular1c1 = "=r[-1]c"
.value = value
end with
end with
Try this:
Sub test()
Dim lRow As Integer
Dim i As Integer
lRow = Cells(Rows.Count, 5).End(xlUp).Row
With ThisWorkbook.ActiveSheet
For i = 1 To lRow
If .Cells(i, 1).Value = "" Then
.Cells(i, 1).Value = .Cells(i - 1, 1).Value
End If
Next i
End With
End Sub
Can be achieved easily without VBA:
Enter something in first row after last blank (same column), select from RMDSADMIN down to that something, =, Up, Ctrl + Enter.
The following code can help is there you need to auto-fill the previous values between 1st and last cells depending on value of 1st cell as mentioned in question Excel - VBA fill in cells between 1st and Last value
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Long
For i = 2 To Target.Column
If Cells(Target.Row, i) = "" Then
If Cells(Target.Row, i - 1) <> "" Then
Range(Cells(Target.Row, i), Cells(Target.Row, i)).Value = Range(Cells(Target.Row, i - 1), Cells(Target.Row, i - 1)).Value
End If
End If
Next i
End Sub
This sub is activated by clicking on any cell.
Same cell marks the end of the loop i.e. to stop the loop just click the cell till which you want to fill the blank cells.
Update: this can be similarly done for other way round as well as asked in this question.
I am writing a script to fill down values of the column based on the column header/first value of the column. In this case, I want the script to identify all columns with the header "||" and fill down to the current region of the sheet.
I have the following but instead of filling down on all columns I want just columns with "||" in the header. Can a condition be a added in thewith statements? Or is there a better approach?
Sub FillCellsFromAbove()
Option Explicit
On Error Resume Next
With Columns
.SpecialCells(xlCellTypeBlanks).formula = "=R[-1]C"
.Value = .Value
End With
Err.Clear
End Sub
Screenshot of spreadsheet: Imgur: The most awesome images on the Internet
Also, the || columns varies. Sometimes there could be 3, other times it could be 6+
Sub FillCellsFromAbove()
Dim lColumn As Long, yes As Integer
lColumn = Cells(1, Columns.Count).End(xlToLeft).Column
For i = 1 To lColumn
yes = InStr(Cells(1, i).Value, "||")
If yes <> "0" Then
'Add code to fill in the column
End If
Next i
End Sub
Thanks, adapted your code and it's working so far.
For i = 1 To lColumn
yes = InStr(Cells(1, i).Value, "||")
If yes <> 0 Then
Set Filldown = Range(Cells(1, i), Cells(lrc, i))
Filldown.Select
Selection.Filldown
End If
Next i