Bold Top 50% of the summed values in Column E and their rows - excel

After seeking help in stackoverflow, I came back with the skeleton of the vba codes (still not working though), however it is not generating the outcome that I desire.
Sub Highlight_Top50()
Dim CheckRange As range
Set CheckRange = range("E2:E", Cells(Rows.Count, "E").End(xlUp)).Row
Selection.FormatConditions.AddTop10
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1)
.TopBottom = xlTop10Top
.Rank = 50
.Percent = True
End With
With Selection.FormatConditions(1).Font.Bold = True
End With
Selection.FormatConditions(1).StopIfTrue = False
End Sub
Under Conditional Formatting, there's no such rule as "Highlight Top 50% of the summed value". The nearest Excel provides is "Format cells that rank in Top: x%".

You're close. There are a couple of problems to fix.
The first is to ALWAYS make sure you're specifying a worksheet reference. Notice in the code below there is a '.' before ALL of the sheet references. This ensures you're referencing the sheet in the With clause.
With ActiveSheet
Set CheckRange = .Range("E2:E" & .Cells(.Rows.Count, "E").End(xlUp).Row)
End With
Also, when you're counting the rows until the end of the data, the .Row was in the wrong place (outside of the )).
Next, you set up your CheckRange variable but you don't use it. You should avoid using Select. So just make the references for the FormatConditions to your CheckRange.
With CheckRange
...
End With
Here is the corrected method.
Sub Highlight_Top50()
Dim CheckRange As Range
With ActiveSheet
Set CheckRange = .Range("E2:E" & .Cells(.Rows.Count, "E").End(xlUp).Row)
End With
With CheckRange
.FormatConditions.AddTop10
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1)
.TopBottom = xlTop10Top
.Rank = 50
.Percent = True
.Font.Bold = True
.StopIfTrue = False
End With
End With
End Sub

Related

VBA Compare single row values and highlight the entire row if different

My code uses conditional formatting to look at the row values in Column A "Order ID", compares them, and then formats the cell if the row values are different. Instead of formatting the cell, how do I format the entire row based off of consecutive row values in Column A "Order ID" being different?
Said differently - if the value in Column A "Order ID" is different from the previous value in Column A "Order ID", I want to format the entire row that is different. My data is variable everyday so I need to use VBA!
Here is the output of my current code:
This is the desired outcome:
Here is the code
Sub Fulfillment()
'
' Fulfillment Macro
' Format the order number in column A as plum
Range("A2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=MOD(SUM((A$2:A2<>A$1:A1)*1),2)=0"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Font.Color = RGB(0, 0, 0)
End With
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = RGB(221, 160, 221)
.TintAndShade = 0
End With
Selection.FormatConditions(1).StopIfTrue = False
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Thank you! I do not necessarily need a conditional formatting solution, just a VBA solution that works dynamically.
A Different Flavor of Banded Rows
Option Explicit
Sub Fulfillment()
'
' Fulfillment Macro
' Format the order number in column A as plum
Const CriteriaColumn As Long = 1
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1") ' adjust
Dim rg As Range: Set rg = ws.Range("A1").CurrentRegion
Set rg = rg.Resize(rg.Rows.Count - 2).Offset(2) ' exclude first two rows
Application.ScreenUpdating = False
rg.Interior.Color = xlNone
Dim Col As Long: Col = 1
Dim cell As Range
Dim r As Long
For Each cell In rg.Columns(CriteriaColumn).Cells
r = r + 1
If cell.Value <> cell.Offset(-1).Value Then Col = Col Mod 2 + 1
If Col = 2 Then rg.Rows(r).Interior.Color = RGB(221, 160, 221)
Next cell
Application.ScreenUpdating = True
MsgBox "Fulfillment accomplished.", vbInformation
End Sub

VBA Change row color based on cell value

I am trying to automate a massive report and one step of the process involves changing the row color based on the value in column B.
Essentially, if B# = "SCC NUPSFTPDE", then I need the row color to be a light blue. (I'm not overly concerned with the exact color TBH).
I've been trying to manipulate code and have basically made my own Frankenstein code so I'm sure it's wrong somewhere in here. Please help!
Dim LastRow As Long
Dim cell As Range
sSheetName = ActiveSheet.Name
With Worksheets(sSheetName)
LastRow = .Cells(.Rows.Count, TEST_COLUMN).End(xlUp).Row
**For Each cell In Range("B2:B" & LastRow)
If cell.Value = "SCC NUPSFTPDE" Then
ColorRow = 39**
Else
cell.EntireRow.Interior.ColorIndex = xlNone
End If
Next
End With
Just to close this question out: change
ColorRow = 39
to
cell.EntireRow.Interior.ColorIndex = 39
or perhaps better, something like
cell.EntireRow.Interior.Color = RGB(129, 218, 239)
You could also try worksheet event - Worksheet_Change which apply the color in every change automatically.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim cell As Range
Dim LastRow As Long
With Me
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
If Not Intersect(Target, .Range("B2:B" & LastRow)) Is Nothing Then
For Each cell In Target
Application.EnableEvents = False
If cell.Value = "SCC NUPSFTPDE" Then
cell.EntireRow.Interior.ColorIndex = 39
Else
cell.EntireRow.Interior.ColorIndex = xlNone
End If
Application.EnableEvents = True
Next cell
End If
End With
End Sub

Bold Top 50% of summed values & Values => 50,000

Sub Highlight_Top50_AND_50K()
Dim CheckRange As Range
With ActiveSheet
Set CheckRange = .Range("E2:E" & .Cells(.Rows.Count, "E").End(xlUp).Row)
End With
With CheckRange
.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreaterEqual, Formula1:="=0.5*SUM(E:E)", Formula2:="=50,000"
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1)
.Font.Bold = True
.StopIfTrue = False
End With
End With
End Sub
Within Range (E2:E),
CONDITION 1: Bold values that are greater than and equal to 50% of the summed values.
CONDITION 2: Bold values that are greater than and equal to 50,000.
The codes ran without error but nothing is generated. Could someone please enlighten me?
Test below code and see if it works for you. The code you've posted just adds one condition and not both the conditions you have stated!
With CheckRange
.FormatConditions.Delete
.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreaterEqual, Formula1:="50000"
With .FormatConditions(1)
.Font.Bold = True
.StopIfTrue = False
End With
.FormatConditions.Add Type:=xlCellValue, Operator:=xlGreaterEqual, Formula1:="=0.5*SUM(E:E)"
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1)
.Font.Bold = True
.StopIfTrue = False
End With
End With
For some reason i couldn't figure why one of your conditions is not working, but if it helps you this alternative should do the job
Sub Highlight_Top50_AND_50K()
Dim CheckRange As Range
Dim x As Range
Dim formula1 As Long
formula1 = Evaluate("=0.5*SUM(E:E)") 'define your first condition
Set CheckRange = Range("E2:E" & Range("E" & Rows.Count).End(xlUp).Row)
For Each x In CheckRange
x.Font.Bold = False
If x >= formula1 Then 'check if greater or equal than 50% of the summed values
x.Font.Bold = True
End If
If x >= 50000 Then ' check if greater or equal to 50,000
x.Font.Bold = True
End If
Next
End Sub

Insert a cell location in condition formatting

so I have a code like this:
Sub ApplyIconSets()
Dim rng As Range
Dim iset As IconSetCondition
Set rng = Application.InputBox("Select a Range", "Obtained Range Object", Type:=8)
rng.Name = "selected"
LastRow = Range("selected").Rows.Count
LastColumn = Range("selected").Columns.Count
With Range("selected")
For i = 2 To LastColumn
For r = 1 To LastRow
Set iset = .Cells(r, i).FormatConditions.AddIconSetCondition
With iset
.IconSet = ActiveWorkbook.IconSets(xl3Arrows)
.ReverseOrder = False
.ShowIconOnly = False
End With
With iset.IconCriteria(2)
.Type = xlConditionValueFormula
.Operator = xlGreaterEqual
.Value = Range("selected").Cells(r, i).Offset(, -1)
End With
With iset.IconCriteria(3)
.Type = xlConditionValueFormula
.Operator = xlGreaterEqual
.Value = Range("selected").Cells(r, i).Offset(, -1)
End With
Next r
Next i
End With
End Sub
So basically this code applies IconSet condition formatting to a cell based on its preceding cell value. The code works perfectly fine, however there's one point I want to improve it.
When I check the condition applied, the code inputs the preceding cell absolute value instead of the cell's location.
Like This
However, I want the code to input the cell location, so that when I change the data, it still works instead of having me rerun the code.
Like this
I have tried to change
.Value = Range("selected").Cells(r,i).Offset(,-1).Address
But it returns a string, hence the condition won't work.
Anyone knows a solution?
Thanks in advance.
I'm not sure you've got your conditional format logic right. Your code as it stands will never show an amber arrow because IconCriteria(3) will evaluate first. Since IconCriteria(2) has identical property values, it will never be met. If you wanted the green arrow to display for numbers greater than the tested cell value and the amber arrow to display for numbers equal to the value, then you'd need to write the code as given below.
I'm also wondering if a ForEach loop might be simpler, especially as it would pass the cell range itself so you could just derive your workbook and worksheet objects from that. This would avoid a potential problems of your unqualified ranges. You'd simply need to add an If statement to ensure that you didn't try to offset past column 1.
All in all, then, the code below might serve your purposes. BTW I'd recommend adding Option Explicit at the top of your module and handling the case where the user hits Cancel on the input box:
Option Explicit
Sub ApplyIconSets()
Dim sel As Range, cell As Range
' Acquire the target range and handle a cancelled input box.
On Error GoTo Canx
Set sel = Application.InputBox("Select a Range", "Obtained Range Object", Type:=8)
' Iterate cell by cell to add the condition.
On Error GoTo EH
For Each cell In sel.Cells
'Ignore the cell if it is in column 1.
If cell.Column > 1 Then
With cell.FormatConditions
'Delete existing conditions.
.Delete
'Add a new condition.
With .AddIconSetCondition
.IconSet = cell.Worksheet.Parent.IconSets(xl3Arrows)
'Set the amber criterion.
'Note: we have to use '>=' but anything '>' will be caught
'in the green operator, so only '=' will meet this criterion.
With .IconCriteria(2)
.Type = xlConditionValueFormula
.Operator = xlGreaterEqual
.Value = "=" & cell.Worksheet.Name & "!" & cell.Offset(, -1).Address
End With
'Set the green criterion.
'Note: we have to use just '>' because this is evaluated first
'and '>=' would result in amber never capturing a value.
With .IconCriteria(3)
.Type = xlConditionValueFormula
.Operator = xlGreater
.Value = "=" & cell.Worksheet.Name & "!" & cell.Offset(, -1).Address
End With
End With
End With
End If
Next
Exit Sub
Canx:
Debug.Print "User cancelled."
Exit Sub
EH:
Debug.Print Err.Number; Err.Description
End Sub
Please try to define in each segment, the value as a reference to the cell like this:
With iset.IconCriteria(3)
.Type = xlConditionValueFormula
.Operator = xlGreaterEqual
.Value = "=Sheet1!$B$1"
End With
You'd have to replace the string with variables to something like this:
.Value = "=Sheet1!" & Range("selected").Cells(r, i).Offset(, -1).Address
Please mark this answer if this helped you.
This code does what you want.
Sub ApplyIconSets()
Dim LastRow As Long, LastColumn As Long
Dim Rng As Range
Dim iSet As IconSetCondition
Dim i As Integer, R As Integer
Set Rng = Application.InputBox("Select a Range", "Obtained Range Object", Type:=8)
Rng.Name = "selected"
LastRow = Range("selected").Rows.Count
LastColumn = Range("selected").Columns.Count
With Range("selected")
For i = 1 To LastColumn
For R = 1 To LastRow
Set iSet = .Cells(R, i).FormatConditions.AddIconSetCondition
With iSet
.IconSet = ActiveWorkbook.IconSets(xl3Arrows)
.ReverseOrder = False
.ShowIconOnly = False
End With
With iSet.IconCriteria(2)
.Type = xlConditionValueFormula
.Operator = xlGreaterEqual
.Value = "=" & Range("selected").Cells(R, i).Offset(, -1).Address
End With
With iSet.IconCriteria(3)
.Type = xlConditionValueFormula
.Operator = xlGreaterEqual
.Value = "=" & Range("selected").Cells(R, i).Offset(, -1).Address
End With
Next R
Next i
End With
End Sub
I didn't want to spend the time experimenting further: I think that the condition can be set for the entire range in one go, causing Excel to set relative formatting instead of absolute. You may like to try that. There would be a difference in speed. You may also like to add code which deletes existing CF before applying the new. CF gets overloaded easily and will then slow down your sheet.

VBA Loop and copy regions from sheet to sheet

I am trying to loop down the column "Q" on my active sheet, find values that are in between 27 and 40 and then copy that cell along with a region around the cell noted by the (-1, -16) into a new sheet.
Right now I am just making the region bold to make sure that my loop is catching the right values and regions.
I"m new to VBA so if anyone can give me some pointers or advise on how to solve my problem I'd be very appreciative.
Sub Test2()
Application.ScreenUpdating = False
ActiveSheet.Range("Q13").Select
Let x = 0
Do While x < 500
If ActiveCell.Value >= 27 And ActiveCell.Value <= 40 Then
Range(ActiveCell, ActiveCell.Offset(-1, -16)).Select
Selection.Font.Bold = True
ActiveCell.Offset(2, 16).Activate
Else
ActiveCell.Offset(1, 0).Select
End If
x = x + 1
Loop
End Sub
Try below code :
Always set the ScreenUpdating property back to True when your macro
ends.Check this link
Avoid using Select/Activate in your code. Check this link
Always explicitly specify the sheet when working with more than one
sheet.
Avoid using ActiveCell,ActiveSheet and refer to them explicitly.
Sub Test2()
Application.ScreenUpdating = False
Dim lastRow As Long
lastRow = Sheets("sheet1").Range("Q" & Rows.Count).End(xlUp).Row
Dim rng As Range, cell As Range
Set rng = Sheets("sheet1").Range("Q1:Q" & lastRow)
For Each cell In rng
If cell.Value >= 27 And cell.Value <= 40 Then
Sheets("sheet1").Range(cell, cell.Offset(0, -16)).Copy Sheets("sheet2").Cells(Sheets("sheet2").Range("Q" & Rows.Count).End(xlUp).Row + 1, 1)
End If
Next
Application.ScreenUpdating = True
End Sub

Resources