Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么VBA添加条件格式时会出现偏移?_Vba_Excel_Conditional Formatting - Fatal编程技术网

为什么VBA添加条件格式时会出现偏移?

为什么VBA添加条件格式时会出现偏移?,vba,excel,conditional-formatting,Vba,Excel,Conditional Formatting,我试图添加如下条件格式: 1 -> empty cells 2 -> empty cells 3 -> empty cells 4 -> TitleCols -> A;B;C;...;H 5 -> Data to TitleCols . . . . . . 25 如果表达式=($G5“”)则将设置为绿色,将其用于$A$5:$H$25 尝试此操作后,工作正常,如预期,然后尝试将其作为VBA代码与以下代码相适应,这些代码正在工作,但不符合预期: With Act

我试图添加如下条件格式:

1 -> empty cells
2 -> empty cells
3 -> empty cells
4 -> TitleCols -> A;B;C;...;H
5 -> Data to TitleCols
. .
. .
. .
25
如果表达式
=($G5“”)
则将设置为绿色,将其用于$A$5:$H$25

尝试此操作后,工作正常,如预期,然后尝试将其作为VBA代码与以下代码相适应,这些代码正在工作,但不符合预期:

With ActiveSheet.UsedRange.Offset(1)
  .FormatConditions.Delete
  'set used row range to green interior color, if "Erledigt Datum" is not empty
  With .FormatConditions.Add(Type:=xlExpression, _
                             Formula1:="=($" & cstrDefaultProgressColumn & _
                                                      .row & "<>"""")")
        .Interior.ColorIndex = 4
      End With
End With
我的数据如下所示:

1 -> empty cells
2 -> empty cells
3 -> empty cells
4 -> TitleCols -> A;B;C;...;H
5 -> Data to TitleCols
. .
. .
. .
25
当我在Excel2007上执行此编辑的代码并在条件对话框中查找公式时,它是
=($G1048571“”)
-它应该是
=($G1“”)
,然后一切正常

更奇怪的是,这是一个精细工作代码的编辑版本,用于为每行添加条件格式。但后来我意识到,写一个表达式是可能的,它可以格式化整行或其中的一部分,我想这会在一分钟内被修改,现在这个^^

编辑:其他任务信息

我在这里使用条件格式,因为此函数将设置一个表,以便对用户输入作出反应。因此,如果设置正确,并且用户编辑了此选项卡的“我的条件化列”中的某些单元格,则对于所使用的行范围,相应的行将变为绿色

现在,因为在主标题行之前可能有行,并且可能有不同数量的数据列,而且目标列可能会更改,所以我当然会使用一些特定的信息

为了使它们最小化,我确实使用NamedRanges来确定正确的偏移量和正确的
defaultprogescolumn

GetTitleRow
用于按名称范围或标题内容确定标题行

With ActiveSheet.UsedRange.Offset(GetTitleRow(ActiveSheet.UsedRange) - _
                                ActiveSheet.UsedRange.Rows(1).row + 1)
更正了我的公式1,因为我发现之前的构造形式不正确

Formula1:="=(" & Cells(.row, _
           Range(strMatchCol1).Column).Address(RowAbsolute:=False) & _
           "<>"""")"
公式1:=”=(“&单元格(.row)_
范围(strMatchCol1).Column.Address(RowAbsolute:=False)和_
""""")"

stratchcol1
-是一个范围的名称。

明白了,lol。在进行大量工作之前设置ActiveCell

ActiveSheet.Range("A1").Activate
Excel正在进行automagic范围调整,当添加FromatCondition时,它会抛出公式。

一个简单的示例:

Sub Format_Range()

Dim oRange          As Range
Dim iRange_Rows     As Integer
Dim iCnt            As Integer


'First, create a named range manually in Excel (eg. "FORMAT_RANGE")
'In your case that would be range "$A$5:$H$25". 
'You only need to do this once, 
'through VBA you can afterwards dynamically adapt size + location at any time. 

'If you don't feel comfortable with that, you can create headers 
'and look for the headers dynamically in the sheet to retrieve 
'their position dynamically too. 

'Setting this range makes it independent
'from which sheet in the workbook is active
'No unnecessary .Activate is needed and certainly no hard coded "A1" cell. 
'(which makes it more potentially subject to bugs later on) 
Set oRange = ThisWorkbook.Names("FORMAT_RANGE").RefersToRange
iRange_Rows = oRange.Rows.Count

For iCnt = 1 To iRange_Rows
    If oRange(iCnt, 1) <> oRange(iCnt, 2) Then
        oRange(iCnt, 2).Interior.ColorIndex = 4
    End If
Next iCnt

End Sub
子格式_范围()
暗橙色作为射程
将iRange\u行设置为整数
作为整数的Dim-iCnt
'首先,在Excel中手动创建一个命名范围(例如“格式化范围”)
'在您的情况下,范围为“$A$5:$H$25”。
“你只需要做一次,
'通过VBA,您可以随时动态调整大小和位置。
如果你觉得不舒服,你可以创建标题
'并在要检索的工作表中动态查找标题
他们的立场也是动态的。
'设置此范围使其独立
'工作簿中哪个工作表处于活动状态
'没有不必要的。需要激活,当然没有硬编码的“A1”单元。
(这使得它以后更容易受到bug的影响)
Set oRange=thispoolk.name(“格式\范围”).refrestorange
iRange_Rows=oRange.Rows.Count
对于iCnt=1到iRange_行
如果橙色(iCnt,1)橙色(iCnt,2),则
橙色(iCnt,2)。内饰颜色指数=4
如果结束
下一个iCnt
端接头
关于我对另一答复的评论:

如果必须对多行执行此操作,则将整个范围加载到内存(数组)中并检查数组中的条件肯定会更快,然后在需要写入(格式化)的单元格上执行写入操作。
我同意这种技术在这种情况下不是“必要的”——但这是一种很好的做法,因为它对于许多(任何类型的)定制都是灵活的,并且更容易调试(使用即时/本地/监视窗口)。
我不是Offset的粉丝,虽然我没有说它不能正常工作,在一些有限的场景中,我可以说出现问题的机会“可能”很小:我体验到一些业务用户倾向于经常使用它(这里是Offset+3,那里是Offset-3,然后是-2,等等);虽然写起来很容易,但我可以告诉你,修改是非常困难的。当最终用户进行更改时,它也经常会出现错误。
我非常赞成使用标题(尽管我也喜欢减少Excel的数据库功能,因为对于许多人来说,这会导致避免访问),因为它将允许您非常灵活。即使我使用了第1列和第2列;更好的方法是根据标题的命名范围的位置动态检索列nr。如果插入另一列,则不会出现错误

最后但并非最不重要的一点是,这听起来有些夸张,但最后一次,我使用了一个带有属性和函数的类模块来动态执行每个工作表中潜在数据的所有检索,对我能想到的所有错误执行检查,并使用一些附加函数来执行特定任务。
因此,如果您需要特定工作表中的多种类型的数据,可以实例化该类,并使所有数据都可以通过定义的函数访问。到目前为止,我还没有注意到有人这样做,但它给您带来了一些麻烦,尽管需要做更多的工作(您可以反复使用相同的原则)。

现在我不认为这是你需要的;但也许有一天,你需要为那些不知道它是如何工作的,但会因为他们自己可能做的事情而抱怨很多的最终用户制作大型工具(即使这不是你的“错”);记住这一点很好

条件格式和数据验证之所以表现出这种奇怪的行为,是因为它们使用的公式超出了正常的计算链。它们必须是,以便您可以引用公式中的活动单元格。如果您在G1中,则无法键入
=G1=”“
,因为您将创建一个循环引用。但在CF或DV中,您可以键入该公式。与实际公式不同,这些公式与当前单元格不关联

当您输入CF公式时,它总是相对于ac
=ISBLANK($G2)
=ISBLANK(R[-3]C7)
=ISBLANK($G655536)
Sub test()

    Dim cstrDefaultProgressColumn As String
    Dim sFormula As String

    cstrDefaultProgressColumn = "$G"

    With ActiveSheet.UsedRange.Offset(1)
        .FormatConditions.Delete
        'set used row range to green interior color, if "Erledigt Datum" is not empty

        'Build formula
        sFormula = "=ISBLANK(" & cstrDefaultProgressColumn & .Row & ")"

        'convert to r1c1
        sFormula = Application.ConvertFormula(sFormula, xlA1, xlR1C1)

        'convert to a1 and make relative
        sFormula = Application.ConvertFormula(sFormula, xlR1C1, xlA1, , ActiveCell.Offset(ActiveCell.Row - .Cells(1).Row))

        With .FormatConditions.Add(Type:=xlExpression, _
                                 Formula1:=sFormula)

            .Interior.ColorIndex = 4
        End With

    End With

End Sub