Use VBA to Update Conditional Formatting Ranges? - excel

I'm trying to update the conditional formatting range for about 30 rows of data on a worksheet. Every month I update the data and I want to run a macro to adjust the ranges to incorporate the new month. I've already done this for my charts by updating the end of the series ranges by looping through the ChartObjects and SeriesCollection.
To do this on conditional formatting, everything I've found requires hardcoding a range (either a cell reference or a named range), e.g.:
With Worksheets(1).Range("e1:e10").FormatConditions(1)
I'd prefer to just loop through the collection of conditional formatting for the worksheet, but I can't find any evidence of this collection existing in the Excel VBA Object Model. Am I missing something here?

This is a little convoluted since there isn't really any great way to loop through formatconditions in a sheet. But, you can loop through specialcells and then loop through their formatconditions and dig in from there:
Sub test()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet1")
Dim rngCell As Range
Dim lng As Long
For Each rngCell In ws.Cells.SpecialCells(xlCellTypeAllFormatConditions).Cells
For lng = 1 To rngCell.FormatConditions.Count
On Error Resume Next
Debug.Print rngCell.FormatConditions(lng).Formula1, rngCell.FormatConditions(lng).AppliesTo.Address
Next lng
Next rngCell
End Sub
I poached the specialcells() idea from Dick Kusleika's excellent post on this very subject at dailydoseofexcel.com blog.

You can use code as below: Here Based on condition Highlighted the row in yellow color. You can use your formatting
LastColumnARows = WB_Source.Sheets(SheetName.Name).range("A" & Rows.Count).End(xlUp).Row
With WB_Source.Sheets(SheetName.Name)
For i = 2 To LastColumnARows
If .range("A" & i).Value > [Condition] Then
With .range("A" & i & ":E" & i)
.Interior.Color = vbYellow
.Font.Color = vbBlack
End With
End If
Next i
End With

Related

VBA Macro to run on a specific worksheet

I am looking to have a macro to run for a specific worksheet only. The purpose of the macro would be to look for a specified range and find negative values and if there is any to extract the whole row into a new worksheet and at the same time transform those negatives to positives. I came up with some but i know for sure that this is totally wrong...missing a lot of stuff. Still trying to learn, new to this vba stuff. Thanks in advance for any help that you can provide. fyi ntp stands for negativestopositives. Not sure if that will help, just thought i can write all the details to my small "code"
Sub ntp()
Dim ws As Worksheet
If ws.Name <> "originalNeg" Then
For Each Cell In Range("I2:I1048576")
If Cell.Value < 0 Then
Cell.Value = Abs(Cell.Value)
End If
Next Cell
End Sub
Sub ntp()
Dim ws As Worksheet
Dim cel As Range
With Activeworkbook.Worksheets("originalNeg")
For Each cel In .Range("I2:I" & .Range("I" & Rows.Count).End(xlUp).row)
If cel.Value < 0 Then cel.Value = Abs(cel.Value)
Next cel
End With
End Sub
This uses the worksheet, and note the . before Range() which links the range to that specific sheet.
Also, only rarely would you want to use all cells in a column. I used the .End(xlUp).Row to get the last used row in Column I for you to loop through.
Set ws = ThisWorkbook.Worksheets("originalNeg")
instead of the if on the name.

excel vba loop thru range and copy to single cell

I am trying to do a loop with Excel VBA, I have a data range in a1:a1000, I want to loop through them and copy one by one to single cell of C1, but below code not working, any idea what went wrong?
Dim I As Integer
For I = 1 To lastrow - 1
Sheets("display").Range("w1").Value = Sheets("data").Range("c1").Offset(I, 0).Value
msgbox Sheets("data").Range("c1").Value
Next I
You're setting the value in cell "W1" instead of "C1".
Updated After Author's Clarification of Question:
Below are two ways you can loop through cells and copy/paste. Neither one is "better". I would like to emphasize that there are probably more efficient methods than these to accomplish your task, but hopefully this answer gets you a resolution.
Sub LoopExampleUsingRange()
Dim aCell As Range
For Each aCell In Range("A1:A1000").Cells
aCell.Copy Range("C1")
Next aCell
End Sub
Sub LoopExampleUsingIntegerReference()
Dim i As Integer
For i = 1 To 1000
Range("A" & i).Copy Range("C1")
'I prefer to use offset, but they both work:
'Range("A1").Offset(i - 1, 0).Copy Range("C1")
Next i
End Sub

VBA to select columns with headers in excel (How to auto-fit columns with data?)

Using VBA how can I select all the columns with headers in Excel? or all the columns which are not blank? Basically select all the columns with data in them.
Autofit columns with data
Sub AutoFit()
Rows("1:1").SpecialCells(xlCellTypeConstants, 23).Columns.AutoFit
End Sub
Or possibly
Sub AutoFitCell()
Cells.SpecialCells(xlCellTypeConstants, 23).Columns.AutoFit
End Sub
One easy way is to use something like range("A1").CurrentRegion.
To address the columns: range("A1").CurrentRegion.Columns.
About "selecting": this is generally useless and just slowing down your code. Never Select unless you have a serious justification for it.
Not sure if this could be useful to you, but what if you were to select all the cells that have data in them? Here's a little Macro for you, just edit the ranges to match you criteria
Sub Macro1()
Dim LR As Long, cell As Range, rng As Range
With Sheets("Sheet1")
LR = .Range("G" & Rows.Count).End(xlUp).Row
For Each cell In .Range("A1:G" & LR)
If cell.Value <> "" Then
If rng Is Nothing Then
Set rng = cell
Else
Set rng = Union(rng, cell)
End If
End If
Next cell
rng.Select
End With
End Sub

Excel VBA: Index-Match Multiple Criteria

I am trying to produce a VBA function that will hide all columns for which cells D9:CC9 are not equal to "A6" and cells D8:CC8 are not equal to "12." Based on the script below, the system keeps returning an error. I am new to VBA, was hoping someone might be able to assist.
Thanks!
Dim MyCell As Range
Set MyCell = Range("D9:CC9,D8:CC8")
For Each cell In MyCell
If cell.Value <> WorksheetFunction.Index(Range("D9:CC9"),WorksheetFunction.Match(Range("A6")&"12",Range("D9:CC9")&Range("D8:CC8"), 0))
cell.EntireColumn.Hidden = True
End If
Next cell
Most operations are performed quite different using VBA than doing them manually. If you want to work with VBA then should do some research about working with variables and objects. This pages should be of interest.
Variables & Constants, Excel Objects, With Statement & Range Properties (Excel)
I have done some changes to your code, see comments within, and refer to the pages mentioned above.
Sub Rng_HideColumns()
Dim rTrg As Range, rCol As Range
Dim sCllVal As String
Rem Set rTrg = ThisWorkbook.Sheets("Sht(0)").Range("D9:CC9,D8:CC8")
Rem Refers to the worksheet you want to work with instead or using the active worksheet
With ThisWorkbook.Sheets("Sht(0)")
Rem Get value to match
sCllVal = .Range("A6").Value2 & 12
Rem Set Range to Search
Set rTrg = .Range("D8:CC9")
For Each rCol In rTrg.Columns
With rCol
If .Cells(2).Value2 & .Cells(1).Value2 = sCllVal Then
.EntireColumn.Hidden = 1
Else
.EntireColumn.Hidden = 0
End If: End With: Next: End With
End Sub

How to concatenate text from a column into a new column? VBA Excel

I'm new to vba programming and I would like to work on a function to fix salutations in an excel file.
To start, I would just like to append a Dear " to a name in the first column, and put this value in the next column, so that I would end up with the name in the first column and "Dear name" in the next column.
The function I have so far, is putting "Dear " in the next column, but it is not appending that to the text in the first column. Could someone help me correct my code?
Sub letterSalutationFixer()
Dim letterSalutationColumn As Range
Set letterSalutationColumn = Columns(1)
For Each Cell In letterSalutationColumn
Cell.Offset(, 1).Value = "Dear " & Cell.Text
Next
End Sub
PS. I do realise that I don't necessarily need to do this programmatically since it doesn't take that long to do with the functions already available, but I eventually want to expand this to fix other data with more complexity - and just thought I could start with something simple.
Many thanks in advance!
The reason it's blank is that Cell is equivalent to the whole column. You're close though. If you did...
For Each Cell In letterSalutationColumn.Cells
..l it would cycle through each cell.
However, the way it's written, it would cycle through each cell in the whole column, which could crash Excel, or at least slow things way down.
Here's a reworked version of what you're trying to do. It only acts on the cells in column A with content:
Sub Salutation()
Dim ws As Excel.Worksheet
Dim LastRow As Long
Dim NameRange As Excel.Range
Dim cell As Excel.Range
Set ws = ActiveSheet
With ws
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set NameRange = .Range("A2:A" & LastRow)
For Each cell In NameRange
cell.Offset(, 1) = "Dear " & cell.Text
Next cell
End With
End Sub
It also declares all variables, something you want to get in the habit of doing. Do a search on Option Explicit to learn how to force yourself to.
It also uses a With statement to fully qualify Object references, so that instead of just referring to Column(1) or Range(something) you're specifying that it's in ws, which has been set to the ActiveSheet.
Another way is the VBA alternative of
Using a formula in column B that runs the concatenation against the used part of column A (ie in B1 ="Dear " &A1 etc)
The formula then is copied over itself as a value to remove the formula
code
Sub QuickCon()
Dim rng1 As Range
Set rng1 = Range([a1], Cells(Rows.Count, "A").End(xlUp))
With rng1.Offset(0, 1)
.FormulaR1C1 = "=""Dear "" &RC[-1]"
.Value = .Value
End With
End Sub

Resources