Excel条件格式设置公式和范围(VBA)

时间:2018-11-11 05:11:50

标签: excel vba conditional-formatting

我有一个FormatCondition。我正在阅读.Formula1.AppliesTo

我想查找公式是否包含将在AppliesTo指定的范围内变化的单元格引用,例如=NOT(ISNUMBER(C3))C3:D10范围内。

据我所知,该引用可能是相对的(例如C3)或混合的(例如$C3C$3),但不是绝对的。根据{{​​3}}和其他一些站点,它也是“应用范围内最左上角的单元格”。

如果范围类似于C3:D10,则很简单。使用例如myRange.Cells(1, 1)找到左上角,使用.Address或类似名称将其转换为字符串,然后在“公式”中查找该字符串,以及添加$的相关变体。当然,对于字符串之类的东西,我必须要小心(例如,左上方的单元格是C3' and formula is =“ CC3NE”`),但有可能(仍然,我欢迎提出有关如何做得更好的建议,但那不是问题)。

真正的问题是范围是否更复杂(如条件格式设置经常发生的那样)。一个示例是$CQ$39:$FT$39,$BE$39,$BE$8:$BE$9,$CU$8:$FT$9,$CU$12:$FT$14,$BE$12:$BE$14,$BE$16:$BE$30,$CQ$16:$FT$30,$CQ$32:$FT$36,$BE$32:$BE$36.Cells(1, 1)并没有为此提供正确的答案(根据Excel制定的公式,BE8)。

此外,如果范围是$A$5,$E$1之类的东西-没有“左上角”怎么办?那么excel(或用户)如何确定公式中应该包含哪些内容?

因此,主要问题是: Excel确定在公式中使用哪个单元格的系统是什么,因为我不认为它是“左上角”的-它可能是“找到最上一行,然后找到最左边的单元格,或者可能相反,或者完全不同。

第二个问题是:如何最好地找到给定范围内的那个单元格?

奖励问题(如果在这里没有得到回答,我很高兴)是:有没有一种好的方法可以在公式中查找对该单元的引用,包括该单元的相对和混合版本?

请注意,这些奇怪的范围是由于使用条件格式将行和列剪切和粘贴到工作表上而导致的,Excel结果是将条件格式切碎(更改范围和更改公式,这两种操作都无需用户输入) )。因此,在这种情况下,优先考虑的是处理将Excel自行设置公式的任何事情,不一定是用户可能会做的事情-但同时处理这两个问题会更好。

2 个答案:

答案 0 :(得分:1)

第一个答案: 简短版:Excel确实使用了最左上角的单元格-但是即使该单元格不在范围内,它也会使用

我创建了一个空白工作表,选择了A5,E1,然后将其设置为NOT BLANK的条件格式(Excel对公式进行处理)。 Excel创建了以下内容:

范围:$E$1,$A$5

公式:=LEN(TRIM(A1))>0

因此,即使A1不在范围内,这也是公式中使用的内容。

我通过在工作表周围复制来进行检查,并且保持一致。

因此,Excel在范围内找到最左边的列,在范围内找到最上面的行,并将它们组合起来以生成应被视为范围“左上角”的单元格,即使结果单元格是实际上不是该范围的一部分。

这也提示了对第二个问题的答案:找到该范围内最上面的行;找到最左边的列;然后使用将两者结合起来的单元格与公式进行比较。您可以通过遍历范围字符串来做到这一点,或者遍历范围本身来逐个单元;也许有更好的方法(欢迎您提出建议)。

这不是很漂亮,但是如果我能找到一种做这两件事的好方法,那会起作用的。

我仍然欢迎您:

  • 任何可以改进此答案的人都可以使用公式中的哪个单元格(我没有对此进行广泛测试)
  • 任何可以建议找到上述“左上单元格”的好方法的人
  • 任何可以提出一种在左上方的单元格中搜索公式字符串的好方法的人

编辑-这是Usmanhaq出色方法的替代代码方法-该过程以字符串形式通过范围:

Private Function FindTopLeft(rangeStr As String, rowabs As Boolean, colabs As Boolean) As String
    newRange = Replace(rangeStr, ":", ",")
    newRangeArray = Split(newRange, ",")
    Dim lowestRow As Long
    Dim lowestCol As Long
    lowestRow = 2147483647
    lowestCol = 2147483647

    For Each cell In newRangeArray
        cell = Trim(cell)
        If cell <> "" Then
            cCol = range(relativeCell).Column
            cRow = range(relativeCell).Row
            If cCol < lowestCol Then lowestCol = cCol
            If cRow < lowestRow Then lowestRow = cRow
        End If
    Next

    FindTopLeft = Cells(lowestRow, lowestCol).Address(rowabs, colabs)

End Function

答案 1 :(得分:1)

感谢您更新问题并在我的评论下方找到

Excel确定在公式中使用哪个单元格的系统是什么,因为我不认为它是“左上角”的-它可能是“查找最上面的行,然后找到那里的最左边的单元格” ,或者相反,或者完全不同。

通常,Excel中的范围类似于具有固定长度和宽度的框或矩形,例如B3:C8。在这种简单的框类型范围的情况下,最左上角的单元格是条件格式中所有公式的基础。换句话说,在第一次公式评估时,将根据条件格式中应用的公式检查此单元格的值。 (我们将此单元称为母单元)

例如

  • 如果将条件格式应用于单元格A1:D10和条件单元格 公式是B2> 0,这意味着如果值设置为对单元格A1进行格式化 B2> 0,对于其他值,如果a的值 偏移量为(1,1)的单元格(在A1情况下为B2)具有值 大于0。即将检查C3的B2格式。
  • 如果将条件格式应用于单元格A1:D10和条件单元格 公式为AND($ B1> = 30,$ B1 <= 60),表示将格式应用于 如果条件的值为true,则单元格A1,但是现在差值来了, 因为$ B导致B现在是静态的,用于条件格式化 B2条件将再次与AND($ B1> = 30,$ B1 <= 60)相同 和D1,但对于A2,B2,C2和D2,它将为AND($ B2> = 30,$ B2 <= 60)

在第一种情况下,根据公式检查的第一个单元格是A1,甚至在第二种情况下,根据条件公式检查的单元格是A1(我们称为母单元格)

现在,如果范围不像一个方框,则它是一个用逗号分隔的混合范围,即使在这种情况下,即使我们围绕该范围制作一个方框,母单元格也是左上角的单元格,它也不是第一个范围内的单元格,但框的第一个单元格。

对于第二个问题,我如何才能最好地找到给定范围内的那个单元格?

如果您想在像简单Range这样的框中找到母单元格,它就是单元格(1,1)

如果您想找到混合范围内的单元格,可能有一些功能,但我不知道;我会发现使用下面的循环

Sub find_topleft()

 Dim r, full_range As Range

 Set r = Range("$O$8:$O$17,$Q$4:$Q$13,$S$4:$S$6")

 Set full_range = Sheets("Sheet1").UsedRange

 row_num = full_range.Rows.Count + full_range.Row - 1
 col_num = full_range.Columns.Count + full_range.Column - 1

 For Each c In r
    If c.Row < row_num Then
    row_num = c.Row
    End If

    If c.Column < col_num Then
    col_num = c.Column
    End If
 Next

 Debug.Print row_num
 Debug.Print col_num

End Sub

是否有一种好的方法可以在公式中查找对该单元格的引用,包括该单元格的相对版本和混合版本?

该单元格与答案中第一个问题所述的公式直接相关。