VBA:在#VALUE错误上格式化单元格

我创build了一个函数来search范围上的特定值并返回相邻的特征。

Function Busca(valor As String) Dim bus(0 To 1) bus(0) = Worksheets("Sheet2").Range("A1:A10").Find(valor, LookAt:=xlWhole). _ Offset(0, 1) bus(1) = Worksheets("Sheet2").Range("A1:A10").Find(valor, LookAt:=xlWhole). _ Offset(0, 2) Busca = bus End Function 

如果在A1:A10不存在匹配,那么函数返回{#VALUE,#VALUE} ,但是我想返回类似于{"No match", ""} ,不匹配“给定颜色的单元格。 我试过数据validation,error handling, If ThenActiveCell.Interior.ColorIndex无济于事。 此外,如果错误得到纠正,我想单元格回到透明。

我想事件处理程序可以做到这一点,但我是VBA的新手,还有很多我不明白的东西。

编辑

如所build议的那样,要明确:

如果找不到匹配项,如何使输出单元格改变颜色,如果find匹配项(在VBA中)则不输出颜色?

根据提问者提供的新信息,这是一个完全重写的答案。

如果我理解正确,你想创build一个自定义函数,将改变单元格的颜色。 以下Microsoft自定义函数的帮助文本说,你不能:

可以在自定义函数中使用的VBA关键字的数量小于可以在macros中使用的数量。 自定义函数不允许执行任何操作,除了向工作表中的公式或另一个VBAmacros或函数中使用的expression式返回一个值。 例如,自定义函数无法调整窗口大小,编辑单元格中的公式,或者更改单元格中文本的字体,颜色或图案选项。 如果在一个函数过程中包含这种“动作”代码,函数返回#VALUE! 错误。

我知道两个可能符合你的要求的select。 后来又添加了第三种替代scheme,一闪而过。

备选scheme1:提供允许值的下拉列表

将光标定位到要限制值的单元格。 从工具栏中select数据,然后selectvalidation。 显示数据validation表单。

如果尚未select,请select“设置”选项卡。 点击“允许:”下的框并select列表。 在源框中input:“= $ A $ 1:$ A $ 10”。 (“=”是必需的,如果你希望能够创build这个单元格的副本,$ s很重要。)点击OK。

当用户将光标定位到该单元格时,他们可以input一个允许的值,也可以从列表中select一个允许的值。 尝试input任何其他值将导致错误消息。 数据validation表单中的其他选项卡允许您input帮助信息和您自己的错误信息。

由于源框中的$ s,可以将原始单元格及其validation复制到其他单元格。

备选2:条件格式

如果允许的值是一个范围,条件格式将符合您的要求。 例如,假设允许的范围是10到20。

从工具栏中select格式,然后select条件格式。

显示条件1的框。 “之间”已经显示。 在右边的框中input10和20。

单击添加以显示条件2的框。replace“by”小于“。在下一个框中input10.单击格式。单击颜色。select红色。单击确定。

单击添加以显示条件3的框。replace“by”大于“。在下一个框中input20.单击格式。单击颜色。select红色。单击确定。

单击确定以接受条件格式。

用户可以将任何他们喜欢的东西input到单元格中,但是除非它在10到20之间,否则它将是红色的。

您可以根据需要创build格式化单元的多个副本。

工作表更改事件

我以前应该想到事情。 我相信这确实是你想要的。

在VBA编辑器中,项目浏览器通常在屏幕左侧可见。 如果不是,请单击Ctrl+R

右键单击要控制选定值的工作表的行。 点击View Code

代码区域将以工作表为首,否则为空。 您可以在此区域放置各种例程,但相关的例程是工作表事件例程。 这些是在例如工作表激活或停用的事件发生时将被调用的例程。 你想要的事件是每当用户改变一个单元格时被调用的改变。 这个例程的吸引力在于它可以做任何你想做的事情。

将Worksheet_Change例程复制并粘贴到工作表代码区域。

它的参数是用户改变的单元格的地址。

TgtRngList被设置为你想巡视的范围列表。 我把这个设置为C1:C1000,F1:F1000和A1。 你将不得不改变你想巡逻的范围。

OKValueList被设置为巡逻范围的允许值列表。 他们可能在某个地方,但我认为在这里定义它们更容易。 将列表更改为任何你想要的。

代码将检查更改的单元是否位于巡逻区域之一中。 如果是,则检查是否有允许的值。 该检查的结果导致单元格被设置为黑色或红色。

 Option Explicit Sub Worksheet_Change(ByVal ChangedCell As Range) ' This routine is called whenever the user changes a cell. ' It is not called if a cell is changed by Calculate Dim ColChanged As Integer Dim InxOV As Integer Dim InxTR As Integer Dim OKValueList() As Variant Dim Patrolled As Boolean Dim RowChanged As Integer Dim TgtColLeft As Integer Dim TgtColRight As Integer Dim TgtRngPartList() As String Dim TgtRngList() As Variant Dim TgtRngPart As String Dim TgtRowBottom As Integer Dim TgtRowTop As Integer Dim ValueChanged As String Dim ValueOK As Boolean ' Fill TgtRngList withe ranges that are to be patrolled by this routine TgtRngList = Array("C1:C1000", "F1:F1000", "A1") ' Fill OKValueList with the permitted values for these cells. OKValueList = Array("V1", "V2", "V3", "V4", "V5", _ "V6", "V7", "V8", "V9", "V10") ColChanged = ChangedCell.Column RowChanged = ChangedCell.Row Patrolled = False For InxTR = LBound(TgtRngList) To UBound(TgtRngList) TgtRngPartList = Split(TgtRngList(InxTR), ":") ' Decode top left of range TgtRngPart = TgtRngPartList(LBound(TgtRngPartList)) TgtRowTop = Range(TgtRngPart).Row TgtColLeft = Range(TgtRngPart).Column If LBound(TgtRngPartList) = UBound(TgtRngPartList) Then ' There is no colon so single cell range TgtRowBottom = TgtRowTop TgtColRight = TgtColLeft Else TgtRngPart = TgtRngPartList(UBound(TgtRngPartList)) TgtRowBottom = Range(TgtRngPart).Row TgtColRight = Range(TgtRngPart).Column End If If RowChanged >= TgtRowTop And RowChanged <= TgtRowBottom And _ ColChanged >= TgtColLeft And ColChanged <= TgtColRight Then ' This is a patrolled cell Patrolled = True Exit For End If Next If Patrolled Then With ActiveSheet ValueChanged = .Cells(RowChanged, ColChanged).Value ' Check value against permitted list ValueOK = False For InxOV = LBound(OKValueList) To UBound(OKValueList) If ValueChanged = OKValueList(InxOV) Then ValueOK = True Exit For End If Next If ValueOK Then ' Set cell black .Cells(RowChanged, ColChanged).Font.Color = RGB(0, 0, 0) Else ' Set cell red .Cells(RowChanged, ColChanged).Font.Color = RGB(255, 0, 0) End If End With End If End Sub 

希望这可以帮助。

我不知道你要去哪里,偏移附加到xlWhole,这是指是否检查整个单元格。 这里有一些笔记,你会看到,返回一个对象:

 Function Busca(valor As String) ''http://msdn.microsoft.com/en-us/library/aa195730(v=office.11).aspx Dim bus(0 To 1) With Worksheets("Sheet2").Range("A1:A10") Set c = .Find(valor, LookAt:=xlWhole) If Not c Is Nothing Then bus(0) = c.Address Set c = .FindNext(c) If Not c Is Nothing Then bus(1) = c.Address Else bus(1) = "None" End If Else bus(0) = "None" End If End With Debug.Print bus(0), bus(1) Busca = bus End Function