Excel 条件格式公式和范围 (VBA)
Excel Conditional formatting formula and ranges (VBA)
我有一个FormatCondition
。我正在阅读 .Formula1
和 .AppliesTo
我想查找公式是否包含将在 AppliesTo 指定的范围内发生变化的单元格引用,例如 =NOT(ISNUMBER(C3))
在 C3:D10
.
范围内
据我所知,该引用可能是相对的(例如 C3
)或混合的(例如 $C3
或 C
),但不是绝对的。它也将是基于 https://www.ablebits.com/office-addins-blog/2014/08/07/relative-absolute-cell-references-excel-conditional-formatting/ 和其他一些网站的 'top-left most cell in the applied range'。
如果范围类似于 C3:D10
,那很容易。使用例如 myRange.Cells(1, 1)
找到左上角,使用 .Address
或类似方法将其转换为字符串,然后在公式中查找该字符串,以及添加 $
的相关变体。当然,我必须小心字符串之类的东西(例如左上角的单元格是 C3' and formula is
="CC3NE"`),但这是可能的(不过,我还是欢迎就如何做得更好提出建议,但这不是问题)。
真正的问题是范围是否更复杂,条件格式似乎经常发生。一个例子是 $CQ:$FT,$BE,$BE:$BE,$CU:$FT,$CU:$FT,$BE:$BE,$BE:$BE,$CQ:$FT,$CQ:$FT,$BE:$BE
。 .Cells(1, 1)
没有给出正确答案(BE8
,根据 Excel 制定的公式)。
此外,如果范围类似于 $A,$E
- 没有 'top left' 怎么办?那么excel(或用户)如何决定公式中应该包含哪些内容呢?
因此主要问题是:Excel 确定在公式中使用哪个单元格的系统是什么,因为我不相信它是 'top left' - 它可能是 'find the topmost row, then find the leftmost cell there',也可能是相反的,或者完全不同的东西。
第二个问题是:如何最好地找到给定范围内的单元格?
额外的问题(如果这里没有得到回答,我很高兴)是:有没有一种好的方法可以在公式中找到对该单元格的引用,包括相对和混合版本细胞的?
请注意,这些奇怪的范围是由于在 sheet 上使用条件格式剪切和粘贴行和列,结果 Excel 切断了条件格式(更改范围,并更改公式,两者都无需用户输入)。因此,当务之急是处理 Excel 在这种情况下将公式设置为独立的任何内容,不一定是用户可能会做的事情——但同时处理两者会更好。
第一个回答:
简短版本:Excel 确实使用最左上角的单元格 - 但它会这样做 即使单元格不属于范围 .
我创建了一个空白 sheet,选择了 A5,E1
,并输入了 NOT BLANK 的条件格式(Excel 使用公式)。 Excel 创建了以下内容:
范围:$E,$A
公式:=LEN(TRIM(A1))>0
所以即使 A1
不在范围内,公式中也使用了它。
我通过在 sheet 周围复制它来检查它,它保持一致。
因此 Excel 找到范围中最左边的列和范围中最上面的行,并将它们组合以生成应被视为 'top left' 的单元格范围,即使结果单元格实际上不是范围的一部分。
这也暗示了第二个问题的答案:找到范围内最上面的行;找到最左边的列;然后使用结合了两者的单元格与公式进行比较。您可以通过遍历范围字符串,或者逐个单元格遍历范围本身来做到这一点;也许有更好的方法(欢迎提出建议)。
它不是很漂亮,但如果我能找到一个好的方法来做这两件事,它会起作用。
我仍然欢迎:
- 任何可以改进这个关于公式中使用哪个单元格的答案的人(我没有对此进行广泛测试)
- 任何人都可以建议找到上述 'top left cell' 的好方法
- 任何可以提出搜索左上角单元格公式字符串的好方法的人
编辑 - 这是 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
感谢更新您的问题并在下面找到我的评论
Excel 确定在公式中使用哪个单元格的系统是什么,因为我不相信它是 'top left' - 它可能是 'find the topmost row, then find the leftmost cell there',也可能反过来,或者完全不同。
通常 Excel 中的范围类似于具有固定长度和宽度的框或矩形,例如B3:C8。在这种简单的框类型范围的情况下,最左上角的单元格是条件格式中所有公式的基础。换句话说,在第一次公式评估时,将根据条件格式中应用的公式检查此单元格的值。 (暂且称此细胞为母细胞)
例如
- 如果条件格式应用于单元格 A1:D10 并且有条件
公式为 B2 > 0,这意味着如果值为
B2 > 0,对于其他人,如果 a 的值适用于任何单元格
偏移量为 (1, 1) 的单元格(在 A1 情况下为 B2)具有值
大于 0。即,将检查 C3 的 B2 值的格式。
- 如果条件格式应用于单元格 A1:D10 并且有条件
公式是 AND($B1 >= 30, $B1 <= 60) 这意味着将格式应用于
如果条件值为真,则单元格 A1,但现在差异来了,
因为 B 现在因为 $B 是静态的,对于条件格式
B2 条件将再次为 AND($B1 >= 30, $B1 <= 60) 与 C1 相同
和 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:$O,$Q:$Q,$S:$S")
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
有没有一种好的方法可以在公式中找到对该单元格的引用,包括该单元格的相对版本和混合版本?
该单元格与第一个问题的答案中所述的公式直接相关联。
我有一个FormatCondition
。我正在阅读 .Formula1
和 .AppliesTo
我想查找公式是否包含将在 AppliesTo 指定的范围内发生变化的单元格引用,例如 =NOT(ISNUMBER(C3))
在 C3:D10
.
据我所知,该引用可能是相对的(例如 C3
)或混合的(例如 $C3
或 C
),但不是绝对的。它也将是基于 https://www.ablebits.com/office-addins-blog/2014/08/07/relative-absolute-cell-references-excel-conditional-formatting/ 和其他一些网站的 'top-left most cell in the applied range'。
如果范围类似于 C3:D10
,那很容易。使用例如 myRange.Cells(1, 1)
找到左上角,使用 .Address
或类似方法将其转换为字符串,然后在公式中查找该字符串,以及添加 $
的相关变体。当然,我必须小心字符串之类的东西(例如左上角的单元格是 C3' and formula is
="CC3NE"`),但这是可能的(不过,我还是欢迎就如何做得更好提出建议,但这不是问题)。
真正的问题是范围是否更复杂,条件格式似乎经常发生。一个例子是 $CQ:$FT,$BE,$BE:$BE,$CU:$FT,$CU:$FT,$BE:$BE,$BE:$BE,$CQ:$FT,$CQ:$FT,$BE:$BE
。 .Cells(1, 1)
没有给出正确答案(BE8
,根据 Excel 制定的公式)。
此外,如果范围类似于 $A,$E
- 没有 'top left' 怎么办?那么excel(或用户)如何决定公式中应该包含哪些内容呢?
因此主要问题是:Excel 确定在公式中使用哪个单元格的系统是什么,因为我不相信它是 'top left' - 它可能是 'find the topmost row, then find the leftmost cell there',也可能是相反的,或者完全不同的东西。
第二个问题是:如何最好地找到给定范围内的单元格?
额外的问题(如果这里没有得到回答,我很高兴)是:有没有一种好的方法可以在公式中找到对该单元格的引用,包括相对和混合版本细胞的?
请注意,这些奇怪的范围是由于在 sheet 上使用条件格式剪切和粘贴行和列,结果 Excel 切断了条件格式(更改范围,并更改公式,两者都无需用户输入)。因此,当务之急是处理 Excel 在这种情况下将公式设置为独立的任何内容,不一定是用户可能会做的事情——但同时处理两者会更好。
第一个回答: 简短版本:Excel 确实使用最左上角的单元格 - 但它会这样做 即使单元格不属于范围 .
我创建了一个空白 sheet,选择了 A5,E1
,并输入了 NOT BLANK 的条件格式(Excel 使用公式)。 Excel 创建了以下内容:
范围:$E,$A
公式:=LEN(TRIM(A1))>0
所以即使 A1
不在范围内,公式中也使用了它。
我通过在 sheet 周围复制它来检查它,它保持一致。
因此 Excel 找到范围中最左边的列和范围中最上面的行,并将它们组合以生成应被视为 'top left' 的单元格范围,即使结果单元格实际上不是范围的一部分。
这也暗示了第二个问题的答案:找到范围内最上面的行;找到最左边的列;然后使用结合了两者的单元格与公式进行比较。您可以通过遍历范围字符串,或者逐个单元格遍历范围本身来做到这一点;也许有更好的方法(欢迎提出建议)。
它不是很漂亮,但如果我能找到一个好的方法来做这两件事,它会起作用。
我仍然欢迎:
- 任何可以改进这个关于公式中使用哪个单元格的答案的人(我没有对此进行广泛测试)
- 任何人都可以建议找到上述 'top left cell' 的好方法
- 任何可以提出搜索左上角单元格公式字符串的好方法的人
编辑 - 这是 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
感谢更新您的问题并在下面找到我的评论
Excel 确定在公式中使用哪个单元格的系统是什么,因为我不相信它是 'top left' - 它可能是 'find the topmost row, then find the leftmost cell there',也可能反过来,或者完全不同。
通常 Excel 中的范围类似于具有固定长度和宽度的框或矩形,例如B3:C8。在这种简单的框类型范围的情况下,最左上角的单元格是条件格式中所有公式的基础。换句话说,在第一次公式评估时,将根据条件格式中应用的公式检查此单元格的值。 (暂且称此细胞为母细胞)
例如
- 如果条件格式应用于单元格 A1:D10 并且有条件 公式为 B2 > 0,这意味着如果值为 B2 > 0,对于其他人,如果 a 的值适用于任何单元格 偏移量为 (1, 1) 的单元格(在 A1 情况下为 B2)具有值 大于 0。即,将检查 C3 的 B2 值的格式。
- 如果条件格式应用于单元格 A1:D10 并且有条件 公式是 AND($B1 >= 30, $B1 <= 60) 这意味着将格式应用于 如果条件值为真,则单元格 A1,但现在差异来了, 因为 B 现在因为 $B 是静态的,对于条件格式 B2 条件将再次为 AND($B1 >= 30, $B1 <= 60) 与 C1 相同 和 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:$O,$Q:$Q,$S:$S")
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
有没有一种好的方法可以在公式中找到对该单元格的引用,包括该单元格的相对版本和混合版本?
该单元格与第一个问题的答案中所述的公式直接相关联。