I'm working on a excel vba code to import and manipulate some data from CSV-file. Suddenly a part of my code didn't work any more though it had worked without problems before.
It is about range.select and afterward with selection.Interior.Pattern = xlSolid
I have tried to copy the same small part of the code to a different workbook and here it work just perfect.
Dim iPhase As Integer
iPhase = Application.WorksheetFunction.CountIf(Range("A:A"), "Phase")
Dim h As Integer
h = 1
Range("A6").Select
Do Until h > iPhase
Cells.Find(What:="Phase", after:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
ActiveSheet.Range(ActiveCell, ActiveCell.Offset(0, 16)).Select
With selection.Interior
.Pattern = xlSolid
.Interior.PatternColorIndex = xlAutomatic
.Interior.ThemeColor = xlThemeColorAccent6
.Interior.TintAndShade = 0
.Interior.PatternTintAndShade = 0
End With
With selection.Font
.Bold = True
End With
h = h + 1
Loop
I get a compile error: Expected function or variable #"selection.interior"
The comments already identify the issues with your code; but here is an alternative using Filter and SpecialCells to select the visible data. Comments are contained in the code.
Sub FliterWithConditionalFormatting()
Dim rng As Range
'properly defing and reference your workbook and worksheet, change as requiried
Set rng = ThisWorkbook.Sheets("Sheet1").Range("A1").CurrentRegion
'The WITH..END WITH statement allows you to shorten your code and avoid using SELECT and ACTIVATE
With rng
.AutoFilter Field:=1, Criteria1:="Phase", Operator:=xlAnd 'filter the rng
'set the range, to conditionally format only the visible data, skipping the header row
With .Range(Cells(2, 1), Cells(rng.Rows.Count, 17)).SpecialCells(xlCellTypeVisible)
With .Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = xlThemeColorAccent6
.TintAndShade = 0
.PatternTintAndShade = 0
End With
With .Font
.Bold = True
End With
End With
.AutoFilter 'Remove the filter
End With
End Sub
Related
I am working on a macro that copies, pastes, and then creates templates forms of various sizes. Before the macro saves the template sheet as a separate file, I have it searching through a range - typically through D14:G end of data range - and highlights blank cells in a custom color. However, I have one very specific use case where there are no blank cells within the range (D14:G16), so it has been selecting all blank cells below this range (A17 to end of sheet). Can anyone help me work past this? Below is the excerpt from the macro that highlights the blankcells:
Set rLastCell = Sheets("Diversity Form").Cells.find(What:="*", After:=Sheets("Diversity Form").Cells(1, 1), LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious, MatchCase:=False)
'ColumnLetter2 = Split(Cells(1, rLastCell.Column).Address, "$")(1)
lCol = Sheets("Diversity Form").Cells(Rows.count, 4).End(xlUp).Row
'Dim ColumnLetter As String
'color only blank cells
For h = 4 To 7
ColumnLetter = Split(Cells(1, h).Address, "$")(1)
Let item = ColumnLetter & "14:G" & lCol
Sheets("Diversity Form").Range(item).SpecialCells(xlCellTypeBlanks).Select
On Error Resume Next
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.599993896298105
.PatternTintAndShade = 0
End With
Next
No need to loop here, or to mess with column letters, or to Select.
Use WorksheetFunction.CountBlank first to test if there are any blanks.
With Sheets("Diversity Form")
Dim lastRow As Long
lastRow = .Cells(.Rows.Count, 4).End(xlUp).Row
Dim checkRange As Range
Set checkRange = .Range(.Cells(14, 4), .Cells(lastRow, 7)) ' Or .Range("D14:G" & LastRow)
End With
If WorksheetFunction.CountBlank(checkRange) > 0 Then
With checkRange.SpecialCells(xlCellTypeBlanks).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent1
.TintAndShade = 0.599993896298105
.PatternTintAndShade = 0
End With
End If
Hi there i have create the following code to format the Grand Total Row in excel spreadsheet. My problem is that I want to select dynamic the cells from Grand Total and right because I don’t have always 15 columns. I make a try with ActiveCell but it didnt work. Can anyone help me to change this code to fit my need?
Range("A1").Select
FindRow1 = Range("A:A").FIND(What:="Grand Total", LookIn:=xlValues, LookAt:=xlWhole).Activate
ActiveCell.Resize(, 15).Select
'Range(ActiveCell, Cells(, ActiveCell.End(xlToRight).Column)).Select
Selection.Font.Bold = True
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End With
Selection.Font.Size = 12
[EDIT]: Here's a screenshot of my problem after trying suggested solutions:
You don't have to select the range. Just be sure of the address of the range you're using, and you're good.
It'd be better if you specify the worksheet you're working with, so
if you have multiple sheets in the workbook you'd still be working
on the right one.
Instead of activating the cell you found with Find, pass the row of that cell to a variable called myRow and use this variable in another function to define the range you need.
Once you have defined the range you need, pass it to a variable like myRange, and use it instead of using Selection in the rest of your code.
To make your range change its size dynamically (assuming you want your range to have one row and all the filled cells of that row), then you'll need to find the column of the last filled cell in your table, pass it to a variable lastCol and use it to define your range.
Sub formatRange()
Dim ws As Worksheet
Dim myRow As Long, lastCol As Integer, myRange As Range
Set ws = ThisWorkbook.ActiveSheet 'Change this to the name of the sheet you're working with
myRow = ws.Range("A:A").Find(What:="Grand Total", LookIn:=xlValues, LookAt:=xlWhole).Row 'The row that has "Grand Total"
lastCol = ws.Cells(myRow, Columns.Count).End(xlToLeft).Column 'The column of the last filled cell in `myRow`
Set myRange = ws.Range("A" & myRow).Resize(1, lastCol) 'The desired range has 1 row and (lastCol) columns
myRange.Font.Bold = True
With myRange.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End With
myRange.Font.Size = 12
End Sub
Consider this case:
If the column of the last cell in the row myRow is NOT the same as the last column in the whole table (see screenshot), you have 2 choices to define your lastCol:
You can define lastCol as the last column of the row myRow (screenshot 1), and in that case you keep the code above as it is.
You can define it as the last column of the whole table (screenshot 2), and in that case you'd have to replace the lastCol line above with this:
'The column of the last filled cell in the whole table
lastCol = ws.Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
P.S, If the column of the last cell is the same in all your rows, you can ignore this last paragraph.
Another example as to how to avoid Select/Selection/Activate/ActiveXXX pattern and how to use nested With...End With structure:
With Range("A1", Range("A:A").Find(What:="Grand Total", LookIn:=xlValues, LookAt:=xlWhole).End(xlToRight))
With .Font
.Bold = True
.Size = 12
End With
With .Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.399975585192419
.PatternTintAndShade = 0
End With
End With
I am trying a code which would select a value from a Data Validation Dropdown list only if the cell, which is two blocks to its left, is highlighted. But I am not able to figure out how to do this. Can anyone help please? Thanks
I have the following code which is wrong but just as an example:
Sub AssignBided()
Worksheets("Monday").Select
With Worksheets("Monday")
If Hilight.range("B12") = True Then
range("B12").Activate
ActiveCell.Offset(0, -2).Select
.Selection.Value = "ABC"
End If
End With
End Sub
The code to highlight cells is as follows:
Sub Hilight(RNG As range, Hilight As Boolean)
With RNG.Interior
If Hilight Then
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = RGB(100, 250, 150)
.TintAndShade = 0
.PatternTintAndShade = 0
Else
.Pattern = xlNone
.PatternTintAndShade = 0
End If
End With
End Sub
The hilight Sub is used as follows:
Dim L8Product As String
Dim i As Long
Dim L8Rnge As range
L8Product = range("Line8_P_Mon")
'Line 8 Resource requirement code
'Determine if change was made in cell B39
If Not Intersect(Target, Me.range("Line8_P_Mon")) Is Nothing Then
Hilight range("Line8_Hilight_Mon"), False
'Below Code searches in the KP and Osgood Table and then highlights the
appropriate cells
If Trim(L8Product) <> "" Then
With Sheets("Products").range("KP_Table")
'searchs in the KP Table on Sheet Overtime_Pos_Table
'The code below will search the KP table for the product that you will select from the Line 8 drop down
Set L8Rnge = .Find(what:=L8Product, _
after:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
lookat:=xlWhole, _
searchorder:=xlByRows, _
searchdirection:=xlNext, _
MatchCase:=False)
If Not L8Rnge Is Nothing Then
Hilight range("KP_Hilight_Mon"), True
'Hilights the cells for the KP and the Prep material required
Else: With Sheets("Products").range("Osgood_Table")
Set L8Rnge = .Find(what:=L8Product, _
after:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
lookat:=xlWhole, _
searchorder:=xlByRows, _
searchdirection:=xlNext, _
MatchCase:=False)
If Not L8Rnge Is Nothing Then
Hilight range("Osgood_Hilight_Mon"), True
'Hilights the cells for the Osgood and the Prep material required
End If
End With
End If
End With
Else: Hilight range("Line8_Hilight_Mon"), False
End If
End If
Hope the question is clear. Thank you in advance.
You can create a simple function to check for highlighting...
'use a constant to store the highlight color, since it's used
' in multiple places in your code
Const HIGHLIGHT_COLOR = 9894500 'RGB(100, 250, 150)
Sub AssignBided()
With Worksheets("Monday")
If IsHighlighted(.Range("B12")) Then
.Range("B12").Offset(0, 2).Value = "ABC" 'changed offset from -2...
End If
End With
End Sub
'Is a cell highlighted? EDIT: changed the function name to IsHighlighted
Function IsHighlighted(c As Range)
IsHighlighted = (c.Interior.Color = HIGHLIGHT_COLOR)
End Function
Sub Hilight(RNG As Range, Hilight As Boolean)
With RNG.Interior
If Hilight Then
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = HIGHLIGHT_COLOR '<< use contant here
.TintAndShade = 0
.PatternTintAndShade = 0
Else
.Pattern = xlNone
.PatternTintAndShade = 0
End If
End With
End Sub
I'm doing an assignment in VBA. I recorded a macro that found cells with the search criteria 'central', then I colored it blue-green and got the following Macro:
Sub Color()
' Color Macro
' Color a region
'
' Keyboard Shortcut: Ctrl+m
'
Cells.Find(What:="central", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 6723891
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End sub
There are 23 occurances of the word 'central' so I thought I could add for k=1 to 23 above the line that starts with cells.find(what...), then add Next K above end with but when I try I get the error
next without for
Bruce Wayne already told you why you got that error
but if you want your macro to find and process all occurrences of "central" in your currently active sheet no matter how many of them, then you can wrap Find() method inside a loop that goes on until all wanted occurrences are found, like follows (explanation in comments):
Dim f As Range
Dim firstAddress As String
With ActiveSheet.UsedRange 'reference currently active sheet used range
Set f = .Find(What:="central", LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False) 'search referenced range for first occurrence of "central"
If Not f Is Nothing Then ' if found...
firstAddress = f.Address ' store first occurrence cell
Do
With f.Interior 'reference found cell "Interior" property
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 6723891
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Set f = .FindNext(f) ' search for the next "central" occurrence
Loop While f.Address <> firstAddress ' loop till you wrap back to initial occurrence
End If
End With
I am trying to select certain rows in a pivot table and highlight them using vba. I have been trying a few things, but I have only been able to highlight one cell. The below code isn't working, but maybe a few tweaks to it will fix it. I need to do this in vba and not use conditional formatting.
Edit: Improved code using suggestion from answer below and own knowledge. It is still not working correctly though.
Sub Highlight()
Dim fnd As Variant
fnds = Array("abc", "dfy", "zxc")
For i = 0 To UBound(fnds)
Cells.Find(What:=(fnds), After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False).Activate
With Selection.EntireRow.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Next
End Sub
by using .Find you are only finding the first instance of each element of the array fnds, is this what you are wanting? I think you are after every occurrence in which case we need to put a loop in there.
Also personal preference here but I prefer to create reference to the cells / rows / columns to be manipulated then only do the actual manipulation once. Not such a biggy when you are only shading but when making changes such as deletions and updates it can be a massive process time saver.
Sub Highlight()
Dim i As Long, DelRange As String
For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
If InStr(1, Cells(i, 1), "abc") <> 0 Or InStr(1, Cells(i, 1), "dfy") <> 0 Or InStr(1, Cells(i, 1), "zxc") <> 0 Then DelRange = DelRange & "," & i & ":" & i
Next i
With Range(Right(DelRange, Len(DelRange) - 1)).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
End Sub
The problem is the Rows collection you are making reference to. Instead you probably want EntireRow of the selected range.
With Selection.EntireRow.Interior
.Pattern = xlSolid
...