Reference to ...ListColumns("<name>"").index in Conditional Formatting Formula

Hans Troost

New Member
Joined
Jan 6, 2015
Messages
30
Office Version
  1. 365
  2. 2019
  3. 2016
Platform
  1. Windows
3 years ago as beginner VBA programmer I developed an application for the Food Bank: a "hand-out-list" for food-packages based on client-data in our "dossier"-system.
Data extracted with Power Query and "enriched" with a VBA-script to the resulting "hand-out-list".

List size about 730 rows, example of 18 rows of fake data:
The Power Query:

VBnuHighlight.xlsm
ABCDEFGHIJKLMNOPQRSTUVWXYZAAABACAD
1VB.nuW/D/VL.U.VKPPKWSpeciaalPakketAanh.NaamStraatAanwBez.LeegPCWoonplaatsNiet geweestAfgemelddatumstopzettingredenstopzettingOpmerkingJongsteTel1Tel2NieuwGestopt3WSindsJJ
264612de heerAA A646026-8-2023
3621W25-2-2024234familieAmersfoorttest1 HTeststraat1 13811AA01202
4622W1-12-2023224familieAmersfoorttest2 T2Teststraat2 23811AB230611111110622026-8-2023
560924-4-2022121de heerASolutions_Achternaam17-02 28-1106090026-8-2023
6578V30-12-202316mevrouwBoer dePakketweg 41234AAErgens0
7579V1-8-2022118GR + BLhalalde heerFarVBAweg 151234TTAmersfoort1579026-8-20231
8677D28-2-2024224familieGerritsen HTroostweg 43456AAAmersfoort2033436789065123479802
9577W13-12-2023112GR + GR + BLhalalmevrouwJansen | SSP pas + sport rugtas TArgonweg 101234AAAmersfoort10-035770026-8-2023
10584W16-9-2021118GR + BLde heerJanssen ! 21aug LAATSTE KEI PAKKETVoedselstraat 221234BBNergenshuizen46584026-8-2023
11674M13-8-202311KEIde heerJanssen J0612222222674026-8-2023
12582V5-12-202315halalde heerJonge ! bel Tst.31 deUraniumweg 211234AALeusden06-040
13600V13-2-2024112de heerKlaassen11600026-8-20231
14583W3-1-2024111GR + GR + WIde heerKlaassenKeistraat 141234CCAmersfoort0
15605W21-2-202415halalde heerPeters (collega)0
16585W19-1-2024144de heerPietersWederik 213831AWLeusden06-042585026-8-20232
17535W13-3-2022244halalfamiliePietersen | Cieka heeft een vraag G1535026-8-20234
186531de heerTEst ICT653026-8-2023
1953822-2-2024223familieTëst_1Teststraat 13000AA202
Uitgiftelijst


And the resulting "hand-out list"

2023-08-30.xlsx
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1VB.nuW/D/VL.U.VKPPKWSpeciaalPakketAanh.NaamStraatAanwBez.LeegPCWoonplaatsNiet geweestAfgemelddatumstopzettingredenstopzettingOpmerkingTel1Tel2NieuwSinds
264612de heerAA A64626-08-2023
3621W25-02-2024234familieAmersfoorttest1 HTeststraat1 13811AA12
4622W01-12-2023224familieAmersfoorttest2 T2Teststraat2 23811AB061111111062226-08-2023
560924-04-2022121de heerASolutions_Achternaam17-02 28-1160926-08-2023
6578V30-12-202316mevrouwBoer dePakketweg 41234AAErgens
7579V01-08-2022118GR + BLhalalde heerFarVBAweg 151234TTAmersfoort57926-08-2023
8677D28-02-2024224familieGerritsen HTroostweg 43456AAAmersfoort0334367890651234798
9577W13-12-2023112GR + GR + BLhalalmevrouwJansen | SSP pas + sport rugtas TArgonweg 101234AAAmersfoort10-0357726-08-2023
10584W16-09-2021118GR + BLde heerJanssen ! 21aug LAATSTE KEI PAKKETVoedselstraat 221234BBNergenshuizen58426-08-2023
11674M13-08-202311KEIde heerJanssen J061222222267426-08-2023
12582V05-12-202315halalde heerJonge ! bel Tst.31 deUraniumweg 211234AALeusden06-04
13583W03-01-2024111GR + GR + WIde heerKlaassenKeistraat 141234CCAmersfoort
14600V13-02-2024112de heerKlaassen60026-08-2023
15605W21-02-202415halalde heerPeters (collega)
16585W19-01-2024144de heerPietersWederik 213831AWLeusden06-0458526-08-2023
17535W13-03-2022244halalfamiliePietersen | Cieka heeft een vraag G53526-08-2023
186531de heerTEst ICT65326-08-2023
1953822-02-2024223familieTëst_1Teststraat 13000AA
30-08 totaal
Cells with Conditional Formatting
CellConditionCell FormatStop If True
K2:K19Cell Valuecontains " ! "textYES
K2:K19Cell Valuecontains " | "textYES


For a lot of columns I started with Conditional Formatting of data, often bases on values in other columns from de Power Query - which I delete afterwards, Deletion is possible because I wrote a small sub to replace the conditional format with permanent fillcolor

Now business' requirements change and new columns are coming, some are shifting to other positions and others will be deleted. And the code I wrote uses fixed column numbers in the conditional formatting, like this: .FormatConditions.Add Type:=xlExpression, Formula1:="=[B]$A2=$Z2[/B]".
But I did not succeed in getting it working

I now need more flexible code, just using column names to refer to them. like .ListColumns("<name>").index.

Here is the code I used, for the 1st (left most) column VB.nu: not for the column Name, which still has the conditional format.:
VBA Code:
Sub VBnuHighlight()
'Stripped the code as as much as possible

    Dim tTbl As ListObject 'Target Table
    Dim rFiltered As Range ' gefilterde regels
    Dim rRecord As Range ' specifieke regel uit gefilterde regel

    Set tTbl = ThisWorkbook.Sheets(1).ListObjects("Uitgiftelijst") 'adapted - reduced code - for MrExcel posting

    With tTbl.ListColumns("VB.nu").DataBodyRange
        .Font.Bold = True
        .HorizontalAlignment = xlLeft
    
'
' worked for years, replacing the $A2=$Z2 with liscolum-names based version did not work. See some attempts below.
        .FormatConditions.Add Type:=xlExpression, Formula1:="=[B]$A2=$Z2[/B]"
'        .FormatConditions.Add Type:=xlExpression, Formula1:="=ttbl.listcolumns(""VB.nu"").value=ttbl.listcolumns(""Nieuw"").value"
'        .FormatConditions.Add Type:=xlExpression, Formula1:=""=RC" & tTbl.ListColumns("VB.nu").Index & "=RC" & tTbl.ListColumns("Nieuw").Index & """"
'        .FormatConditions.Add Type:=xlExpression, Formula1:="=RC1=RC26"
'        .FormatConditions(.FormatConditions.Count).SetFirstPriority
        With .FormatConditions(1).Interior
            .Color = vbBlue
            .TintAndShade = 0.75
        End With
        .FormatConditions(1).StopIfTrue = False
    End With
    tTbl.AutoFilter.ShowAllData
    RemoveCF tTbl.ListColumns("VB.nu").DataBodyRange 'zet Cond. Format om in permanente vulkleur.
End Sub

and the RemoveCF routine:

VBA Code:
Sub RemoveCF(ByRef mySel As Range) ' vervang conditional format door permanent format MySel = My Selection

    Dim myCell As Range
    
    For Each myCell In mySel
        myCell.Interior.Color = myCell.DisplayFormat.Interior.Color
        myCell.Font.Color = myCell.DisplayFormat.Font.Color
    Next myCell

    mySel.FormatConditions.Delete

End Sub

The only thing I could achieve, for me is a poor-man's-solution: using another mechanism including looping over regarding records:

VBA Code:
Sub VBnuColorPoor()
'
' a "poor-man's-solution" implemented:
    Dim tSh As Worksheet ' Target Worksheet
    Dim tTbl As ListObject 'Target Table
    Dim rFiltered As Range ' gefilterde regels
    Dim rRecord As Range ' specifieke regel uit gefilterde regel

    Set tSh = ThisWorkbook.ActiveSheet
    Set tTbl = ThisWorkbook.Sheets(1).ListObjects("Uitgiftelijst") 'adapted - reduced code - for MrExcel posting

With tTbl.DataBodyRange
    .AutoFilter field:=tTbl.ListColumns("Nieuw").Index, Criteria1:="<>", Operator:=xlAnd, Criteria2:="<>"""
    Set rFiltered = Nothing
    Set rRecord = Nothing
    On Error Resume Next ' voor als er geen Gemaakte Passen zouden zijn: komt in principe niet voor
        Set rFiltered = .SpecialCells(xlCellTypeVisible).EntireRow
    On Error GoTo 0
    If rFiltered Is Nothing Then
    Else
        For Each rRecord In rFiltered.Rows
            If tSh.Cells(rRecord.Row, tTbl.ListColumns("VB.nu").Index).Value = tSh.Cells(rRecord.Row, tTbl.ListColumns("Nieuw").Index).Value Then
                With tSh.Cells(rRecord.Row, tTbl.ListColumns("VB.nu").Index).Interior
                    .Color = vbBlue
                    .TintAndShade = 0.75
                End With
            End If
        Next rRecord
    End If
End With
tTbl.AutoFilter.ShowAllData

End Sub

So my question is:
Is it possible do use references to ListColumn-names in stead of column numbers/alphabet char's in the Cond. Format formula's ?

Wish (not a requirement):- no loop over all table records.

Please keep in mind: I have to do this (as I currently do) with a lot of columds in this sheets.

I hope that someone can help me with this. Thank you for at least reading my post!

Kind regards, Hans Troost
 

Excel Facts

Fastest way to copy a worksheet?
Hold down the Ctrl key while dragging tab for Sheet1 to the right. Excel will make a copy of the worksheet.
My apologies: I ruined the "bolded" 1st example code bij "bolding"the cell reference, so making it un-runnable (is this English?).
So please find below the right code, which can be runned:

VBA Code:
Sub VBnuHighlight()
'Stripped the code as as much as possible

    Dim tTbl As ListObject 'Target Table
    Dim rFiltered As Range ' gefilterde regels
    Dim rRecord As Range ' specifieke regel uit gefilterde regel

    Set tTbl = ThisWorkbook.Sheets(1).ListObjects("Uitgiftelijst") 'adapted - reduced code - for MrExcel posting

    With tTbl.ListColumns("VB.nu").DataBodyRange
        .Font.Bold = True
        .HorizontalAlignment = xlLeft
    
'
' worked for years, replacing the $A2=$Z2 with liscolum-names based version did not work. See some attempts below.
        .FormatConditions.Add Type:=xlExpression, Formula1:="=$A2=$Z2"
'        .FormatConditions.Add Type:=xlExpression, Formula1:="=ttbl.listcolumns(""VB.nu"").value=ttbl.listcolumns(""Nieuw"").value"
'        .FormatConditions.Add Type:=xlExpression, Formula1:=""=RC" & tTbl.ListColumns("VB.nu").Index & "=RC" & tTbl.ListColumns("Nieuw").Index & """"
'        .FormatConditions.Add Type:=xlExpression, Formula1:="=RC1=RC26"
'        .FormatConditions(.FormatConditions.Count).SetFirstPriority
        With .FormatConditions(1).Interior
            .Color = vbBlue
            .TintAndShade = 0.75
        End With
        .FormatConditions(1).StopIfTrue = False
    End With
    tTbl.AutoFilter.ShowAllData
    RemoveCF tTbl.ListColumns("VB.nu").DataBodyRange 'zet Cond. Format om in permanente vulkleur.
End Sub

Regards, Hans
 
Upvote 0
In the meanwhile I kept thinking and working on it and made some progress:

Using R1C1-style cell references I got it syntactically right, but is seems that I do not understand the R1C1 good enough.

I changed my code from the always working from
.FormatConditions.Add Type:=xlExpression, Formula1:="=$A2=$Z2" to
.FormatConditions.Add Type:=xlExpression, Formula1:="=R[2]C" & tTbl.ListColumns("VB.nu").Index & "=R[2]C" & tTbl.ListColumns("Nieuw").Index & ""

So have the following code now
VBA Code:
Sub VBnuHighlight()
'Stripped the code as as much as possible

    Dim tTbl As ListObject 'Target Table

    Set tTbl = ThisWorkbook.Sheets(1).ListObjects("Uitgiftelijst") 'adapted - reduced code - for MrExcel posting

    With tTbl.ListColumns("VB.nu").DataBodyRange
'
' worked for years, replacing the $A2=$Z2 with liscolum-names based version did not work.
'
'        .FormatConditions.Add Type:=xlExpression, Formula1:="=$A2=$Z2" 'Old, working code
        .FormatConditions.Add Type:=xlExpression, Formula1:="=R[2]C" & tTbl.ListColumns("VB.nu").Index & "=R[2]C" & tTbl.ListColumns("Nieuw").Index & ""
        .FormatConditions(.FormatConditions.Count).SetFirstPriority
        With .FormatConditions(1).Interior
            .Color = vbBlue
            .TintAndShade = 0.75
        End With
        .FormatConditions(1).StopIfTrue = False
    End With
    tTbl.AutoFilter.ShowAllData
    RemoveCF tTbl.ListColumns("VB.nu").DataBodyRange 'zet Cond. Format om in permanente vulkleur.
End Sub

Sub RemoveCF(ByRef mySel As Range) ' trplace conditional format by permanent fill color. MySel = My Selection

    Dim myCell As Range
    
    For Each myCell In mySel
        myCell.Interior.Color = myCell.DisplayFormat.Interior.Color
        myCell.Font.Color = myCell.DisplayFormat.Font.Color
    Next myCell
    mySel.FormatConditions.Delete

End Sub

executed it - also using the debug immediate window - and got the following result:

VBnuHighlightSmall.xlsm
ABCD
1VB.nuW/D/VL.U.Nieuw
2646646
3621W25-2-2024
4622W1-12-2023622
560924-4-2022609
6578V30-12-2023
7579V1-8-2022579
8677D28-2-2024
9577W13-12-2023577
10584W16-9-2021584
11674M13-8-2023674
12582V5-12-2023
13600V13-2-2024600
14583W3-1-2024
15605W21-2-2024
16585W19-1-2024585
17535W13-3-2022535
18653653
1953822-2-2024
Uitgiftelijst


and the immediate window - breakpoint at : With .FormatConditions(1).Interior shows:
? .FormatConditions.count 1 ? .FormatConditions(1).formula1 =$A4=$D4 ? ttbl.databodyrange.row 2

What do I do wrong and where does the =$A4=$D4, this 4 originates from? The address should be =$A2=$Z2

Can someone explain me what is going on here?


Kind regards, Hans Troost
 
Upvote 0
I found the solution myself, so with future questions I will work better to solve, before posting questions. The solution:

Change to use R1C1-reference-style in the VBA-code in the right way and replace the original code line:
.FormatConditions.Add Type:=xlExpression, Formula1:="=$A2=$Z2"
by
.FormatConditions.Add Type:=xlExpression, Formula1:="=R[0]C" & tTbl.ListColumns("VB.nu").Index & "=R[0]C" & tTbl.ListColumns("Nieuw").Index & ""

Most important is understanding relative R1C1-references, especially the use of R[0]Cn, since this cond. formatting is not used on cell by cell but on a whole ListObject("<something">.ListColumn("<name>") at once.

This did the trick and will make future maintenance work on my XL-VBA programs independent of column positions and order, by just referring to their names.

Regards, Hans Troost
 
Last edited:
Upvote 0
Solution

Forum statistics

Threads
1,223,885
Messages
6,175,179
Members
452,615
Latest member
bogeys2birdies

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top