使用相对于活动单元格的单元格内容作为自定义 If 函数中的条件的问题
Posted
技术标签:
【中文标题】使用相对于活动单元格的单元格内容作为自定义 If 函数中的条件的问题【英文标题】:Issue with Using Contents of Cell Relative to Active Cell as a Condition in a Custom If Function 【发布时间】:2016-05-09 07:55:12 【问题描述】:我正在尝试在 Excel Visual Basic 编辑器中创建我的第一个用户定义函数。我在带有 OS X El Capitan 版本 10.11.1 的 Macbook Pro 2011 上使用 Excel 2011
我正在创建一个工作簿,它将使用我的函数来计算 4 分区格式的桶赛结果。划分如下:
一等分或“1D”是最快时间,最多比最快时间低 0.499 秒。
二等分或“2D”是第二快的时间,距离最快时间 0.5 到 0.999 秒。
三等分或“3D”时间与最快时间相差 1 秒到 1.499 秒。
最后,四分法或“4D”时间比最快时间慢了 1.5 秒或更多。
这是我必须计算这些划分的当前代码:
Function DIV(pVal)
If pVal = "Z" Then
DIV = ""
ElseIf pVal = 999 Then
DIV = "DQ"
ElseIf pVal > 100 Then
DIV = "NT"
ElseIf pVal < (Range("B2") + 0.5) Then
DIV = "X1D"
ElseIf ActiveCell.Offset(-1, 0) = "X1D" And pVal < (Range("B2") + 1) Then
DIV = "2D"
ElseIf pVal < (Range("B2") + 1) Then
DIV = "X2D"
ElseIf pVal < (Range("B2") + 1.5) Then
DIV = "X3D"
ElseIf pVal > (Range("B2") + 1.499) Then
DIV = "X4D"
Else
DIV = "Incorrect"
End If
End Function
现在,我只希望每个分区中的第一次产生“2D”、“3D”和“4D”,而每个分区的其余时间产生“X1D”、“X2D”、“X3D” " & "X4D" 因为我将应用条件格式,以便以 "X" 开头的任何内容都将出现在白色文本中,因此在查看时是不可见的,但是,我仍然可以将它用于将来的功能进入每个部门的排名。
因此,例如,我目前正在处理 2D,我希望在最快时间的 0.5 到 0.999 秒之间的所有时间都返回“X2D”的结果,第一个结果除外,这意味着上面的单元格会显示“X1D”。
上面代码中的所有内容都可以正常工作,除了应该返回“2D”的 ElseIf。它返回为 false 并转到下一个 ElseIf,然后返回“X2D”。
我一次删除了部分代码并对其进行了测试。我已将问题缩小到 ActiveCell.Offset 部分。
在过去的三天里,我在整个互联网上进行了搜索,试图找出我缺少的东西,但我就是找不到。以下是我根据我在网上找到的所有尝试输入它的方法,但到目前为止没有任何效果。
ElseIf ActiveCell.Offset(rowOffset:=-1, columnOffset:=0) = "X1D" And pVal < (Range("B2") + 1) Then DIV = "2D"
ElseIf pVal < (Range("B2") + 1) And ActiveCell.Offset(-1, 0) = "X1D" Then DIV = "2D"
ElseIf pVal < (Range("B2") + 1) And ActiveCell.Offset(-1, 0).Select = "X1D" Then DIV = "2D"
ElseIf pVal < (Range("B2") + 1) And ActiveCell.Offset(-1, 0).Range = "X1D" Then DIV = "2D"
ElseIf pVal < (Range("B2") + 1) And ActiveCell.Offset(-1, 0).Activate = "X1D" Then DIV = "2D"
我根据某人在另一个网站上的建议尝试了另一种编码方式,就是这样:
Function DIV(pVal)
If pVal = "Z" Then DIV = ""
If pVal = 999 Then DIV = "DQ"
If pVal > 100 Then DIV = "NT"
If pVal < (Range("B2") + 0.5) Then DIV = "X1D"
If ActiveCell.Offset(-1, 0) = "X1D" And pVal < (Range("B2") + 1) Then DIV = "2D"
If pVal < 100 Then DIV = "Correct"
If DIV = "" Then DIV = "Incorrect"
End Function
当我尝试这个时,它使整个功能停止工作,所有结果都返回为“正确”。
我完全不知道该怎么做才能解决这个问题,如果有人有任何建议,我将不胜感激。
谢谢!
编辑** 此函数将仅用于除 C1 和 C2 之外的所有 C 列,因为 C1 是标题单元格,而 C2 将始终为 1D。
如何使用函数的具体示例:
假设有 12 次,每个部门 3 次。
总是在 B2 的快速时间是 15.000。
B5 中的时间是 15.5,这是第一个 2D 时间。
该函数在 C5 中,应首先询问 B5 是否 = "Z",如果为真则应将单元格留空,如果不为真则应询问 B5 是否 = 999,如果为真则应返回 "DQ" , 如果不为真则应询问 B5 是否 > 100,如果为真则应返回“NT”,如果不为真则应询问 B5 是否
我希望这会有所帮助!
【问题讨论】:
您应该将所有三个值从单元格中直接传递给函数 -pval
、上方单元格中的值和 B2 中的值。否则,您将需要使您的功能不稳定。在 UDF 中使用ActiveCell
几乎从来没有是个好主意,因为您不知道函数计算时哪个单元格可能处于活动状态。
ActiveCell 属性不属于 UDF。见UDF returns the same value everywhere。
感谢您的回复。就像我说的,我是创建 UDF 的新手。在本周末之前我什至从未见过 VBA,所以当你说我应该将所有三个值都直接传递给函数时,我不确定你的意思是什么?
【参考方案1】:
您需要重新设计函数的逻辑,而且在设计 UDF 时将所有变量传递给它,而不是在函数中分配它们。这就是我认为你的函数应该是这样的:
Public Function DIV(pVal As Double, testRng As Range, testX1D As Range) As String
Dim ret As String
If testX1D.value = "X1D" Then
If pVal < testRng.value + 1 Then
DIV = "2D"
Exit Function
End If
End If
Select Case CVar(pVal)
Case "Z": ret = vbNullString
Case 999: ret = "DQ"
Case Is > 100: ret = "NT"
Case Is < (testRng.value + 0.5): ret = "X1D"
Case Is < (testRng.value + 1): ret = "X2D"
Case Is < (testRng.value + 1.5): ret = "X3D"
Case Is > (testRng.value + 1.499): ret = "X4D"
Case Else: ret = "Incorrect"
End Select
DIV = ret
End Function
还值得注意的是,在以这种方式比较值时,您必须非常仔细地指定测试的顺序。例如,如果在这种情况下pVal
的值为999
:
Case 999: ret = "DQ"
Case Is > 100: ret = "NT"
它将返回“DQ”,因为这是第一次测试,但是如果反过来:
Case Is > 100: ret = "NT"
Case 999: ret = "DQ"
你会得到“NT”,因为pVal
也大于 100。只是需要记住的一点......
使用此 UDF
例如,在 C5 中输入的公式,其中 pVal 是 B5 中的值
=DIV(B5,C4,$B$2)
(注意 B2 的绝对引用)
【讨论】:
我尝试使用您创建的函数,现在所有结果都以“#VALUE!”的形式返回。我希望如果它有效,我可以用它作为起点来了解更多关于创建 UDF 的信息。另外就旁注而言,如果该值等于 testrng.value +1.499 那么它应该以 X3D 的形式返回,因为它 你是怎么调用函数的? 我并不是要听起来像个白痴,如果让您感到沮丧,我很抱歉,除了过去三天从试图创造这个。因此,当您说我如何调用该函数时,我不确定您的意思。我最初只是使用嵌套的 if 函数和 and & or 函数来完成所有这些工作,直到我进入过程中更复杂的部分,包括计算排名和支出,然后我的函数变得太长了。跨度> 查看我上面的编辑 - 我已经包含了您应该如何调用该函数,这有意义吗? 好的,我明白你现在在问什么。而我做错了。我改变了它,它仍然在说#VALUE!但我认为我们正在接近答案。我的下一个问题是为什么要使用 B1?它只是一个标题单元格。我将添加一个具体示例,说明如何在我的原始问题中使用此功能。我认为这可能会有所帮助以上是关于使用相对于活动单元格的单元格内容作为自定义 If 函数中的条件的问题的主要内容,如果未能解决你的问题,请参考以下文章
尝试从 iOS 中 UITableView 的自定义单元格内的 textField 获取活动单元格的索引