使用 VBA 将用户定义的函数输入到列中
Posted
技术标签:
【中文标题】使用 VBA 将用户定义的函数输入到列中【英文标题】:Enter User Defined Function into Column Using VBA 【发布时间】:2018-12-20 17:17:10 【问题描述】:我目前正在我的工作簿第 2 表的 J 列中使用一个公式,该公式将从第 1 表的 5 列中查找值并返回相应的文本。例如,如果工作表 2 上 M 列中的值与工作表 1 上 J 列中的任何值匹配,它将返回“N”,如果不匹配,它将在 K 列中查找,如果匹配其中的任何值,则返回 D,依此类推.我在 VBA 中这样做,所以使用的公式是
ActiveSheet.Range("J2:J" & intLastRow).FormulaR1C1 = _
"=IFERROR(IF(ISNUMBER(MATCH(RC[3],Sheet1!C10,0)),""N"",
IF(ISNUMBER(MATCH(RC[3],Sheet1!C11,0)),""D"",
IF(ISNUMBER(MATCH(RC[3],Sheet1!C12,0)),""R"",
IF(ISNUMBER(MATCH(RC[3],Sheet1!C13,0)),""G"",
IF(ISNUMBER(MATCH(RC[3],Sheet1!C14,0)),""F"",""""))))), """")"
这个公式效果很好,并填写了相应的值。然后,我创建了一个用户定义的函数,它将查找 J 列中与 C 列中的 ID 号相关联的所有值,并用逗号分隔它们。此功能在输入单元格时也能正常工作。
Function get_areas(ID As String) As String
Dim rng As Range, cel As Range
Set rng = Range("A2:A" & Cells(rows.count,1).End(xlUp).Row)
Dim areas As String
For Each cel In rng
If IsNumeric(Left(cel, 1)) And cel.Offset(0, 2) = ID Then
If InStr(1, areas, cel.Offset(0, 9)) = 0 Then
areas = cel.Offset(0, 9) & ", " & areas
End If
End If
Next cel
areas = Trim(Left(areas, Len(areas) - 2))
get_areas = areas
End Function
理想情况下,我想做的是在 J 列中的所有单元格中运行原始公式,这些单元格不以 A 列中的 Master 开头,然后在所有以 master 开头的单元格中运行 get_areas($C2) 函数在 A 列中。如果这不可行,那么我想在 VBA 中的所有空白单元格中运行 get_areas 函数(这意味着它们没有从原始公式返回任何内容,但仍然有公式)。我已经尝试修改原始公式以阅读
ActiveSheet.Range("J2:J" & intLastRow).FormulaR1C1 =
"=IFERROR(IF(LEFT(RC[-9],6)=""master"", get_areas(RC[-7]),
IF(ISNUMBER(MATCH(RC[3],Sheet1!C10,0)),""N"",
IF(ISNUMBER(MATCH(RC[3],Sheet1!C11,0)),""D"",
IF(ISNUMBER(MATCH(RC[3],Sheet1!C12,0)),""R"",
IF(ISNUMBER(MATCH(RC[3],Sheet1!C13,0)),""G"",
IF(ISNUMBER(MATCH(RC[3],Sheet1!C14,0)),""F"","""")))))), """")"
但收到有关 get_areas 函数的错误。
【问题讨论】:
你得到什么错误? @BigBen 我得到运行时错误'5':无效的过程调用或参数,当我调试它时,它会突出显示这部分功能 area = Trim(Left(areas, Len(areas ) - 2)).Len(areas)
那时可能不大于 2。
@BigBen 但是,如果我只是将公式 =get_areas(C2) 输入到单元格 J2 中,它可以工作,所以我不确定问题是什么。
无论哪种方式,您都需要在尝试使用Left(areas, Len(areas) - 2)
之前检查If Len(areas) > 2
【参考方案1】:
WorksheetFunction.Trim
所有这些可能与您的情况无关,但在某些类似情况下可能有用。它只是一直在我的脑海里响起,当你无法闭嘴时,你知道它是怎么回事。
我会这样写函数:
Function get_areas(ID As String) As String
Dim rng As Range
Dim i As Long
Dim areas As String
Set rng = Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row)
With rng
For i = 1 To .Cells.Count
If IsNumeric(Left(.Cells(i, 1))) And .Cells(i, 1).Offset(0, 2) = ID Then
If InStr(1, areas, .Cells(i, 1).Offset(0, 9)) = 0 Then
If i > 1 Then
areas = areas & ", " & .Cells(i, 1).Offset(0, 9)
Else
areas = .Cells(i, 1).Offset(0, 9)
End If
End If
End If
Next
End With
get_areas = WorksheetFunction.Trim(areas)
End Function
这根本不像'WorksheetFunction'部分那么重要。
WorksheetFunction.Trim 去除单词之间除了单个空格之外的所有空格,而 VBA 的Trim
函数只去除左右空格。
另一个最明显的区别是“If i > 1
”块。
【讨论】:
欣赏编辑!当我尝试使用此代码时,我收到“参数不是可选”错误,并在 If IsNumeric 之后突出显示“左”。 我忘了左边的第二个参数。我应该是'IsNumeric(Left(.Cells(i,1),1))'。对不起。 谢谢!此代码有效,但它们都以“,”或“,”等开头,而不是字母本身,这可能是 Trim 的用途。 也许 'If Instr' 应该是 ' 0',我的意思是我不知道代码的作用。您显然得到了空的分隔值。 嗯,我不确定。你知道我怎么能把它变成一个 Sub 而不是一个函数吗?以上是关于使用 VBA 将用户定义的函数输入到列中的主要内容,如果未能解决你的问题,请参考以下文章