【问题标题】:Excel VBA Function Works In Some Places But Not OthersExcel VBA 函数在某些地方有效,但在其他地方无效
【发布时间】:2017-04-05 05:47:51
【问题描述】:

我在电子表格的模块中插入了以下简单函数:

Function CellName(cel As Range) As Variant
Dim nm As Name
    For Each nm In Names
        If nm.RefersTo = "=" & cel.Parent.Name & "!" & cel.Address Then
            CellName = nm.Name
            Exit Function
        End If
    Next
CellName = CVErr(xlErrNA)
End Function

我只想用相邻列中单元格的命名变量填充一列。

奇怪的是,此函数在某些 CELLS 中有效,但在其他 CELLS 中会引发 #N/A 错误。在有名字的单元格中。

谁能帮我理解?我不是 VBA 专家;我确实对这个 Q 做了一些研究,但只找到了比这更复杂的问题的答案。

谢谢。

【问题讨论】:

  • 如果您使用的单元格有一个“定义的名称”(并且只有),那么您将获得该名称(如果有多个,则只是它遇到的第一个名称)。如果没有“名称”直接进入此单元格,那么您将获得“#N/A”。什么细节在这里不起作用?
  • 这个函数似乎对我有用,它返回引用对象cel 的#N/A 值没有Name
  • 名称可以限定为工作簿或工作表。您没有限定您正在迭代的 Names 集合,因此它隐含地指代 ThisWorkbook.Names (或 ActiveWorkbook.Names,...不确定.. 也可能是 ActiveSheet.Names .. 不是隐含的东西不错?) - 是否考虑到这一点?即所有名称都在同一范围内吗?
  • Dirk:例如,工作表“model-input”的单元格 D3 的值为 2.25%,并分配了名称 third_pty_sales_costs_pct。在单元格 E3 中,我有 {=cellname(D3)},它产生 #N/A 在同一个工作簿中,在工作表“输入”的单元格 C3 上,值是 588,000,名称是 property_size。在单元格 D3 中,公式为 {=cellname(C3)},生成“property_size”。看?我很困惑。但话又说回来,就像我说的,我不是这方面的专家。
  • 我会猜测并说它不适用于工作表名称包含空格或其他“奇怪”字符的工作表。在这些情况下,RefersTo 看起来像 "='" & cel.Parent.Name & "'!" & cel.Address Then。例如,=model-input!$D$3 中的 RefersTo 会因为 - 而无效,因此必须使用引号使其有效。

标签: vba excel


【解决方案1】:

要在任何地方获取名称,您可以使用以下内容:

Public Function CellName(cel As Range) As Variant
  Dim nm As Name, sht As Worksheet

  For Each nm In ThisWorkbook.Names
    If nm.RefersTo = "=" & cel.Parent.Name & "!" & cel.Address Then
      CellName = nm.Name
      Exit Function
    End If
  Next

  For Each sht In ThisWorkbook.Worksheets
    For Each nm In sht.Names
      If nm.RefersTo = "=" & cel.Parent.Name & "!" & cel.Address Then
        CellName = nm.Name
        Exit Function
      End If
    Next
  Next

  '----- skip from here if you only want single-cells

  For Each nm In ThisWorkbook.Names
    If Not Intersect(Range(nm.RefersTo), cel) Is Nothing Then
      CellName = "* " & nm.Name
      Exit Function
    End If
  Next

  For Each sht In ThisWorkbook.Worksheets
    For Each nm In sht.Names
      If Not Intersect(Range(nm.RefersTo), cel) Is Nothing Then
        CellName = "* " & nm.Name
        Exit Function
      End If
    Next
  Next

  '----- skip till here if you only want single-cells

CellName = CVErr(xlErrNA)

End Function

如果没有找到单一引用,第二部分还将显示包含单元格的范围(输出以 "* " 开头(如果不需要,可以删除)

【讨论】:

  • 丹克德克!我认为这解决了 YowE3K 遇到的问题。谢谢你们的帮助。 (每一个,我都学了一点。)
【解决方案2】:

尝试将您的功能更改为:

Function CellName(cel As Range) As Variant
    Dim nm As Name
    For Each nm In Names
        If nm.RefersTo = "=" & cel.Parent.Name & "!" & cel.Address Or _
           nm.RefersTo = "='" & Replace(cel.Parent.Name, "'", "''") & "'!" & cel.Address Then
            CellName = nm.Name
            Exit Function
        End If
    Next
    CellName = CVErr(xlErrNA)
End Function

为了保留语法规则,一些工作表名称需要用引号引起来。

编辑:根据 David Zemens 的评论,我更新了公式以执行 Replace(cel.Parent.Name, "'", "''"),以确保工作表名称中的任何嵌入引号都被两个引号替换。

【讨论】:

  • @DavidZemens - 不,这行不通 - 例如一张名为 Sh e'et1 的工作表。到单元格 A1 的 RefersTo 将是 ='Sh e''t1'!$A$1。因此Replace(nm.RefersTo, "'",vbNullString) 将给出=Sh et1!$A$1,而=Sh e't1!$A$1 将不匹配。您必须在等式的两边都进行替换,如果您有名为Sh e'et1 Sh eet1 的工作表,则会出现问题。 (为什么有人会有这些名字的床单完全是另一个问题!!)
  • 啊,你是对的,我认为 ' 是工作表名称中的非法字符 :)
  • @DavidZemens - 我已经在 cel.Parent.Name 上使用了 Replace - 这应该可以解决问题。 (我预计 ' 在工作表名称中也会无效 - 令人惊讶的是什么是允许的,什么是不允许的。)
  • Dirk 写的那个(我在上面检查的答案)有效。 :)
猜你喜欢
  • 2011-03-21
  • 2020-02-23
  • 1970-01-01
  • 2017-05-23
  • 2018-08-11
  • 2014-09-05
  • 2014-02-06
  • 2019-05-17
  • 1970-01-01
相关资源
最近更新 更多