【问题标题】:How to create a VBA formula that takes value and format from source cell如何创建从源单元格获取值和格式的 VBA 公式
【发布时间】:2016-12-16 06:05:09
【问题描述】:

在 Excel 的 VBA 中,我想创建一个从源单元格中获取值和格式的公式。

目前我有:

Function formEq(cellRefd As Range) As Variant
    'thisBackCol = cellRefd.Interior.Color
    'With Application.Caller
    '    .Interior.Color = thisBackCol
    'End With
    formEq = cellRefd.Value
End Function`

这将返回单元格的当前值。我注释掉的部分在单元格中返回 #VALUE 错误。取消注释时,似乎参考的颜色已保存,但 Application.Caller 返回 2023 错误。这是否意味着 this 没有返回所需的 Range 对象?

如果是这样,我如何获取引用该函数所使用单元格的范围对象? [显然是为了将颜色设置为源值]。

【问题讨论】:

  • 用作 UDF 的函数只能返回一个值 - 它们本身无法更改调用它们的单元格或其他单元格的任何其他内容。
  • 没有别的办法吗?这似乎是 VBA 应用程序中的一个巨大且非常奇怪的缺陷。可能有充分的理由,但 VBA 处理范围对象的方式似乎不一致。
  • 我可以在函数之外调用一个单独的子程序吗?或者我可以通过其他方式解决这个问题吗?我猜这可能与 Excel 在源单元格更改值时所做的持续更新有关。
  • 这是一种似乎可用的方法,但您需要进行测试以确保它不会产生任何意外后果:stackoverflow.com/questions/23433096/…
  • 如果您需要引用调用单元格(例如使用Application.CallerApplication.ThisCell),那么您可以在UDF 本身中执行此操作,并将地址作为参数传递给使用调用的代码Evaluate。为了安全起见,最好让 UDF 向调用单元格返回一个值,并且不要让 Evaluate'd 代码更新该单元格,否则您很可能会陷入循环。

标签: vba excel cell


【解决方案1】:

这是我使用 Tim William 的magic 找到的上述问题的解决方案:

Function cq(thisCel As Range, srcCel As Range) As Variant
    thisCel.Parent.Evaluate "colorEq(" & srcCel.Address(False, False) _ 
    & "," & thisCel.Address(False, False) & ")"
    cq = srcCel.Value
End Function

Sub colorEq(srcCell, destCell)
    destCell.Interior.Color = srcCell.Interior.Color
End Sub

destCell 只是对调用函数的单元格的单元格引用。

interior.color 可以与其他格式规则交换或添加。此解决方案中需要注意的三个额外点:

  1. 通过将值计算保留在公式中,这可以在 destCell 引用自身时阻止循环引用的可能性。如果放在sub 中,则它会不断重新计算;和
  2. 如果仅在更改源值时更改格式,而不是格式,因为这是 UDF 运行并因此更改格式的唯一触发器;
  3. Application.CallerApplication.ThisCell 无法集成,因为当它引用自身并为自身返回值时,它会触发无限循环或“循环引用”错误。如果与地址合并以创建字符串,那么尽管按照蒂姆威廉的回答,这仍然有效。

【讨论】:

  • 我是对的,不能使用这种技术来返回一个值并直接格式化这个值吗? (例如,生成文本作为函数的返回值,并直接用粗体/斜体/下划线格式化此文本中的某些单词)如果这是不可能的,那么最好的解决方法是什么?
  • @Andy 直接“直接”是什么意思? 3 年前我得到了这个工作,颜色被复制了,值也被复制了。我用它来将不可靠的答案标记为红色,并在电子表格中传播该警告。
  • 用“直接”我的意思是,该函数正在返回/构建一个更大的字符串,我想格式化这个字符串的一些单词并将其返回到存储公式的单元格。比如:“这个 is 是一个 test 字符串。”或者换句话说:返回带有一些格式化单词的文本。
  • @Andy 我明白了,没试过。正如你所说,你不能直接格式化字符串。这使用源单元格格式并将其复制。您可以尝试录制一个宏并查看文本是如何直接格式化的,然后将其放入Evaluate,因为这是“潜入”格式化的唯一方法。
  • 备注:当公式结果更新时,Worksheet_Change 不起作用。看起来应该使用 Worksheet_Calculate(见extendoffice.com/documents/excel/…
【解决方案2】:

这里有一种方法显示您仍然可以使用ThisCell

Function CopyFormat(rngFrom, rngTo)
    rngTo.Interior.Color = rngFrom.Interior.Color
    rngTo.Font.Color = rngFrom.Font.Color
End Function



Function formEq(cellRefd As Range) As Variant
    cellRefd.Parent.Evaluate "CopyFormat(" & cellRefd.Address() & "," & _
                         Application.ThisCell.Address() & ")"
    formEq = cellRefd.Value
End Function

【讨论】:

  • 在工作表和工作簿之间使用包括 CopyFormat 中的工作表和工作簿名称对象。
猜你喜欢
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-18
相关资源
最近更新 更多