VBA to loop through column if the header is not empty - vba

I want to start looping through each column if the column header is not blank. I don't know how to locate the header of each column as it is letter, not number.
I googled many codes but they are not doing exactly I want.
Below is the code. Any help would be appreciated.
Sub ColorGradient()
'Find the last roll number
Dim Lastrow As Integer
Lastrow = Range("A:A").Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Dim cs As ColorScale
Dim rng As Range
'Loop through each column
For Each rng In Range("B4:AA" & Lastrow).Columns
'Set color gradient
Set cs = rng.FormatConditions.AddColorScale(ColorScaleType:=3)
' Set the color of the lowest value
With cs.ColorScaleCriteria(1)
.Type = xlConditionValueLowestValue
With .FormatColor
.Color = RGB(248, 105, 107)
.TintAndShade = 0
End With
End With
' In the middle
With cs.ColorScaleCriteria(2)
.Type = xlConditionValuePercentile
.Value = 50
With .FormatColor
.Color = RGB(255, 244, 189)
.TintAndShade = 0
End With
End With
' At the highest value
With cs.ColorScaleCriteria(3)
.Type = xlConditionValueHighestValue
With .FormatColor
.Color = RGB(0, 204, 255)
.TintAndShade = 0
End With
End With
Next rng
End Sub

I'm not sure I understand completely, but test that the "header" row value is not blank first, then set your column range and do stuff to it.
Option Explicit
Sub test()
Dim rHdrs As Range
Dim r As Range
Dim rCol As Range
Dim Lastrow As Integer
With ThisWorkbook.Sheets(1)
Lastrow = .Columns(1).Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Set rHdrs = .Range("B3:AA3")
For Each r In rHdrs
If r.Value <> "" Then
Set rCol = .Range(.Cells(4, r.Column), .Cells(Lastrow, r.Column))
'loop through cells in rCol
'do stuff with the non-empty header column ranges here
End If
Next r
End With
End Sub
I assumed you were doing this on Thisworkbook.sheets(1).

Related

VBA to colour cells if cell value matches

I am relatively new to VBA and have this script which searches for the Array "VC" and changes the matching cells within the range by colouring them red.
My problem is I need to change the criteria from -MyArr = Array("VC") to instead search column A and find any corresponding matches in the same row within the range "B2:D20" then colour the matches red as the below script does.
As per the below script I don't want a case sensitive search and am using XLpart to include partial matches. Please help, thanks
Sub Mark_cells_in_column()
Dim FirstAddress As String
Dim MyArr As Variant
Dim Rng As Range
Dim I As Long
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
MyArr = Array("VC")
With Sheets("Sheet1").Range("A2:d20")
For I = LBound(MyArr) To UBound(MyArr)
Set Rng = .Find(What:=MyArr(I), _
After:=.Cells(.Cells.Count), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
FirstAddress = Rng.Address
Do
Rng.Interior.ColorIndex = 3
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
Next I
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Sample data:
You may try this
Public Sub Main()
Dim cell As Range, cell2 As Range
For Each cell In ThisWorkbook.Worksheets("Sheet1").Range("A2:A20")
For Each cell2 In cell.Offset(, 1).Resize(, 3)
If Instr(cell.Value, cell2.Value) > 0 Then cell2.Interior.ColorIndex = 3
Next
Next
End Sub
Or
Public Sub Main()
Dim cell As Range
With ThisWorkbook.Worksheets("Sheet1")
For Each cell In .Range("B:D").SpecialCells(xlCellTypeConstants)
If Instr(.Cells(cell.Row,1).Value, cell.Value) > 0 Then cell.Interior.ColorIndex = 3
Next
End With
End Sub
This will go through all cells in column A, split each cell value (comma-delimited) into separate items, and search for each item in the same row (case insensitive), through columns B to D
Option Explicit
Public Sub MarkCellsInColumns()
Dim arr As Variant, r As Long, c As Long, i As Long, f As Range, vals As Variant
arr = Sheet1.UsedRange
With Sheet1.UsedRange
For r = 1 To UBound(arr)
If Not IsError(arr(r, 1)) Then
If Len(arr(r, 1)) > 0 Then
vals = Split(arr(r, 1), ",") 'check each value in one cell
For i = 0 To UBound(vals)
For c = 2 To UBound(arr, 2) 'check all columns on same row
If LCase(Trim$(vals(i))) = LCase(Trim$(arr(r, c))) Then
If f Is Nothing Then
Set f = .Cells(r, c)
Else
Set f = Union(f, .Cells(r, c)) 'union of found cells
End If
f.Select
End If
Next c
Next i
End If
End If
Next r
If Not f Is Nothing Then f.Interior.Color = vbRed 'color all in one operation
End With
End Sub
Result

Excel: Hiding cells that are not colored

I have a script that changes the cell color and a script to hide the cells that are not colored. The hide script works, but it hides ALL the cells, even the colored ones. I noticed that when I use the script that changes the cell color, it does not detect the changes in the excel interface(in the 'Fill Color' settings in 'Home' tab, under the 'font size' selection). I also noticed that when try to change the color of the cells (using the excel interface) that are colored from using the script, it does not change (the color seems to be fixed to whatever is set from the script).
Therefore, it seems like the interface does not detect the changes that are being made using the coloring script.
Also, I noticed the script below takes a while to check/hide all the cells. If there is a way to speed up the process, that would be great!
Any help will be greatly appreciated!
Thank you!
The script to hide uncolored cells:
Public Sub HideUncoloredRows()
Dim startColumn As Integer
Dim startRow As Integer
Dim totalRows As Integer
Dim totalColumns As Integer
Dim currentColumn As Integer
Dim currentRow As Integer
Dim shouldHideRow As Integer
startColumn = 1 'column A
startRow = 1 'row 1
totalRows = Sheet1.Cells(Rows.Count, startColumn).End(xlUp).Row
For currentRow = totalRows To startRow Step -1
shouldHideRow = True
totalColumns = Sheet2.Cells(currentRow, Columns.Count).End(xlToLeft).Column
'for each column in the current row, check the cell color
For currentColumn = startColumn To totalColumns
'if any colored cell is found, don't hide the row and move on to next row
If Not Sheet1.Cells(currentRow, currentColumn).Interior.ColorIndex = -4142 Then
shouldHideRow = False
Exit For
End If
Next
If shouldHideRow Then
'drop into here if all cells in a row were white
Sheet2.Cells(currentRow, currentColumn).EntireRow.Hidden = True
End If
Next
End Sub
The script that changes the color certain cells:
Range("A8").Select
Application.CutCopyMode = False
Range("A8").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.FormatConditions.Add Type:=xlExpression, Formula1:= _
"=COUNTIF(Name_Preps,A8)=1"
Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
With Selection.FormatConditions(1).Font
.Bold = True
.Italic = False
.TintAndShade = 0
End With
With Selection.FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent3 'Changes the cell to green
.TintAndShade = 0.4
End With
Selection.FormatConditions(1).StopIfTrue = False
End Sub
Try to change your condition to follow
For currentColumn = startColumn To totalColumns
'if any colored cell is found, don't hide the row and move on to next row
If Sheet1.Cells(currentRow, currentColumn).Interior.ThemeColor = xlThemeColorAccent3 Then
shouldHideRow = False
Exit For
End If
Next
conditional formatting is not detected by Interior.ColorIndex and the likes
if you want to go on that way you can see here or here for relevant code
but I'd abandon conditional formatting as well as Select/Selection/Activate/ActiveXXX pattern and go simply this way:
Option Explicit
Sub HandleRowsColorAndVisibility()
Dim iRow As Long
With Range("A8", Cells(Rows.count, 1).End(xlUp)) '<--| reference cells from A8 down to column A last not empty cell
ResetRange .Cells '<--| first, bring range formatting and visibility back to a "default" state
For iRow = .Rows.count To 1 Step -1 '<--| then start looping through range
If WorksheetFunction.CountIf(Range("Name_Preps"), .Cells(iRow, 1)) = 1 Then '<-- if current cell matches your criteria ...
FormatRange .Cells(iRow, 1), True, False, 0, xlColorIndexAutomatic, xlThemeColorAccent3, 0.4 '<--| then format it
Else '<--| otherwise...
.Rows(iRow).Hidden = True '<--| hide it!
End If
Next
End With
End Sub
Sub ResetRange(rng As Range)
rng.EntireRow.Hidden = False
FormatRange rng, False, False, 0, xlColorIndexAutomatic, -4142, 0
End Sub
Sub FormatRange(rng As Range, okBold As Boolean, okItalic As Boolean, myFontTintAndShade As Single, myPatternColorIndex As XlColorIndex, myInteriorThemeColor As Variant, myInteriorTintAndShade As Single)
With rng
With .Font
.Bold = okBold
.Italic = okItalic
.TintAndShade = myFontTintAndShade
End With
With .Interior
.PatternColorIndex = myPatternColorIndex
.ThemeColor = myInteriorThemeColor
.TintAndShade = myInteriorTintAndShade
End With
End With
End Sub

Coloring a line where macro finds a certain word

I'd like to know if there's a way to do the following thing using VBA:
If the macro finds the word "Total" in the column B, then interior.color of the line where total is would be colored in Blue, and do it for all the "Total" words in the column B.
Note: I have different Totals... it's not only the word "Total"
LIKE THIS (i.e coloring from col A to F)
I tried with this but it's not working properly and the code is bad...
Sub forme_couleur()
Dim myRow As Integer
myRow = 1
While Not IsEmpty(Cells(myRow, 2))
If Cells(myRow, 2).Find(What:="Total") Is Nothing Then
myRow = myRow + 1
Else
Cells(myRow, 2).Find(What:="Total").Interior.Color = RGB(174, 240, 194)
End If
myRow = myRow + 1
Wend
End Sub
Consider:
Sub ColorMeBlue()
Dim i As Long, N As Long, s As String
N = Cells(Rows.Count, "B").End(xlUp).Row
s = "Total"
For i = 1 To N
If InStr(1, Cells(i, 2).Value, s) > 0 Then
Range("A" & i & ":F" & i).Interior.Color = RGB(174, 240, 194)
End If
Next i
End Sub
EDIT#1:
To refer to a range using columns by number, use:
Sub ColorMeBlue2()
Dim i As Long, N As Long, s As String
N = Cells(Rows.Count, "B").End(xlUp).Row
s = "Total"
Firstcol = 1
LastCol = 6
For i = 1 To N
If InStr(1, Cells(i, 2).Value, s) > 0 Then
Range(Cells(i, Firstcol), Cells(i, LastCol)).Interior.Color = RGB(174, 240, 194)
End If
Next i
End Sub
You can achieve this with conditional formatting, but if you must do it with VBA use something like the following:
Sub test()
For i = 1 To Cells(ActiveSheet.Rows.Count, "B").End(xlUp).Row
If InStr(1, Cells(i, 2), "Total") Then
With Cells(i, 2).EntireRow.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorLight2
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End With
End If
Next i
End Sub
Another Concept: You can go with the AutoFilter method. Using this method doesn't require any For loops, or any Ifs, just use all the cells that passes the AutoFilter criteria of ="*Total*" inside your Range.
Sub ColorMeBlue_Filter()
Dim i As Long, N As Long, s As String
Dim FirstCol As Long, LastCol As Long
Dim FiltRng As Range
N = Cells(Rows.Count, "B").End(xlUp).Row
s = "Total"
' (just for my testing)
'FirstCol = 1
'LastCol = 6
Range("A1").AutoFilter
Range(Cells(1, FirstCol), Cells(N, LastCol)).AutoFilter Field:=2, Criteria1:="=*Total*", _
Operator:=xlAnd
' set FiltRng to only visible cells (that passed the "Total" filter)
Set FiltRng = Range(Cells(2, FirstCol), Cells(N, LastCol)).SpecialCells(xlCellTypeVisible)
' modify interior color of all cells at once (one code line)
FiltRng.Interior.Color = RGB(174, 240, 194)
End Sub
You can do with a formula based conditional formatting, using the COUNTIF(a1:f1,"Total") function being >0
Using Range.Find avoids: looping through each row and the need to get the last row.
Instead of applying Range.Find to each row, just apply it to the entire column, no need to check if the cell is empty (see Range.Find Method (Excel) for additional details)
Voici votre code révisé:
Assuming your data is located at `A:F'
Sub forme_couleur()
Const kCriteria As String = "Total"
Dim rTrg As Range, s1stFound As String
With ThisWorkbook.Sheets("DATA").Columns(2) 'change as required
Set rTrg = .Cells.Find(What:=kCriteria, After:=.Cells(1), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext)
If Not (rTrg Is Nothing) Then
s1stFound = rTrg.Address
Do
rTrg.EntireRow.Cells(1).Resize(1, 6).Interior.Color = RGB(224, 240, 248) 'RGB(174, 240, 194) give me a green color - changed as required
Set rTrg = .Cells.FindNext(After:=rTrg)
Loop Until rTrg.Address = s1stFound
End If: End With
End Sub

Compare 2 excel file using macro

I was just wondering if is there any way of comparing two excels spreadsheets using macro. I have a piece of macro that basically does the work but it checks column by column. So say in case I have a value defined in A(1,1) in sheet1 and if the same value is not present in A(1,1) in sheet2 but the value present in any row of the column then it won't raise a complaint.
'compare Sheet
Sub CompareTable()
Dim tem, tem1 As String
Dim text1, text2 As String
Dim i As Integer, hang1 As Long, hang2 As Long, lie As Long, maxhang As Long, maxlie As Long
Sheets("Sheet1").Select
Columns("A:A").Select
With Selection.Interior
.Pattern = xlNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Range("A1").Select
Sheets("Sheet2").Select
Dim lastRow As Long
With ActiveSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Rows("1:" & lastRow).Select
With Selection.Interior
.Pattern = xlNone
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Range("A1").Select
maxhang = lastRow ' number of the last row containg data
MaxRow = lastRow
Dim LastCol As Integer
With ActiveSheet
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
MaxColumn = LastCol
For col = 1 To MaxColumn
For hang1 = 2 To maxhang
Dim a As Integer
a = 0
tem = Sheets(1).Cells(hang1, col)
For hang2 = 1 To maxhang
tem1 = Sheets(2).Cells(hang2, col)
If tem1 = tem Then
a = 1
Sheets(2).Cells(hang2, col).Interior.ColorIndex = 6
For lie = 1 To maxlie
text1 = Sheets(1).Cells(hang1, lie)
text2 = Sheets(2).Cells(hang2, lie)
If text1 <> text2 Then
Sheets(2).Cells(hang2, lie).Interior.ColorIndex = 8
End If
Next
End If
Next
If a = 0 Then
Sheets(1).Cells(hang1, 1).Interior.ColorIndex = 5
End If
Next
Next
End Sub
Note : I'm looking for any solution that could give me a row match, so if any value of the given row is not matched with the sheet2 then it should highlight it.
I'm open to have any other alternative as well. Any help or suggestion would be much appreciated.
Thanks for your time !
Im not sure if this is what you are expecting. Please see my below code
Sub CompareTable()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim table1 As Range
Dim table2 As Range
Dim table1Rows As Integer
Dim table1Cols As Integer
Set ws1 = Worksheets("sheet1")
Set ws2 = Worksheets("sheet2")
Set table1 = ws1.Cells
Set table2 = ws2.Cells
table1Rows = ws1.UsedRange.Rows.Count
table1Cols = ws1.UsedRange.Columns.Count
For i = 1 To table1Rows
For j = 1 To table1Cols
If table1(i, j).Value = table2(i, j).Value Then
Else
ws1.Cells(i, j).Interior.Color = vbYellow
End If
Next
Next
End Sub
Sheet1 table
Sheet2 table
After Running the code tgisis my result

Highlight all rows equal to value in cell foobar

I am trying to code this procedure to highlight all rows of which have a value of "N" in their respective row within Column N
I am not too familiar with coding VBA formatting and I cannot get this procedure to function
Sub highlight_new_pos()
Dim rng As Range, lCount As Long, LastRow As Long
Dim cell As Object
With ActiveSheet 'set this worksheet properly!
LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
For Each cell In .Range("N2:N" & LastRow)
If cell = "N" Then
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Next cell
End With
End Sub
Option Explicit
Sub highlight_new_pos()
Dim cel As Object
With ActiveSheet
For Each cel In .Range("N2:N" & .Cells(.Rows.Count, 14).End(xlUp).Row)
If UCase(cel.Value2) = "N" Then cel.Interior.Color = 65535
Next
End With
End Sub
This will be faster if you have a lot of rows:
Sub highlight_new_pos1()
Application.ScreenUpdating = False
With ActiveSheet
With .Range("N1:N" & .Cells(.Rows.Count, 14).End(xlUp).Row)
.AutoFilter Field:=1, Criteria1:="N"
.Offset(1, 0).Resize(.Rows.Count - 14, .Columns.Count).Interior.Color = 65535
.AutoFilter
End With
End With
Application.ScreenUpdating = True
End Sub
In your code, you are looping through the cells, but you're still changing the color of the initial selection (not of the cell in the loop). Adjust as follows:
Sub highlight_new_pos()
Dim rng As Range, lCount As Long, LastRow As Long
Dim cell As Object
With ActiveSheet 'set this worksheet properly!
LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
For Each cell In .Range("N2:N" & LastRow)
If cell = "N" Then
With cell.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End if
Next cell
End With
End Sub
If you want the entire row, change cell.Interior to cell.entirerow.Interior