Excel 仅清除包含公式的单元格
我需要一个VBA代码,它只清除包含公式的单元格,跳过包含给定Excel工作表中值的单元格。 我有以下代码:Excel 仅清除包含公式的单元格,excel,vba,excel-formula,Excel,Vba,Excel Formula,我需要一个VBA代码,它只清除包含公式的单元格,跳过包含给定Excel工作表中值的单元格。 我有以下代码: Dim rng As Range, cl As Range Set rng = ThisWorkbook.Sheets("MATRIX").Range("C2:AU10000") For Each cl In rng If cl.Hyperlinks = .Hyperlinks Then cl.ClearContents En
Dim rng As Range, cl As Range
Set rng = ThisWorkbook.Sheets("MATRIX").Range("C2:AU10000")
For Each cl In rng
If cl.Hyperlinks = .Hyperlinks Then
cl.ClearContents
End If
Next cl
请尝试这种方法:
If cl.HasFormula Then
cl.ClearContents
End If
这应该是最快的方法
rng.SpecialCells(xlCellTypeFormulas).ClearContents
HasFormula vs SpecialCells(xlTypeCellTypeFormulas)
通过范围的XML结构删除公式 出于艺术的考虑,为了完成上述解决方案,我演示了一种相当未知的方法,使用范围的xml电子表格值(
.value(11)
):
示例调用的进一步提示
您也可以通过以下方式将整个数据集(包括格式)复制到另一张图纸,而不是替换相同的范围:
Sheet2.Range("D2").Resize(rng.Rows.Count, rng.Columns.Count).value(11) = s
警告
正如@ChrisNeilson所指出的,
“在某些情况下,这也会产生意想不到的结果
其中ClearFormulas处理的范围包括一些单元格
包含引用正在处理的范围之外的单元格的公式”
对照其他解决方案测试值(11)
使用20%的公式速率(在双列范围内)进行测试表明,
方法(由@Storax和@vbasic208发布)启动速度非常快,但一旦数据范围超过~115100行,就会与我的值(11)
方法发生冲突
HasFormula
解决方案(@FaneDuru)似乎仅限于较小的范围,在超过10000行的范围内很快就会消耗大量时间
它尊重“原则”,为什么简单如果复杂是可能的,但有趣的方法…:)投票通过。感谢您的反馈;xml语法看起来很复杂,这是正确的。。。我总是尝试探索非传统的方法,并让它们发挥作用,以便从中学习。因此,先验的重点不是放在简单上仅供参考刚刚编辑的最近测试数据显示了一些可能的意外结果@FaneDuru@t.m.这有一个不幸的副作用,即使前公式单元格包含空字符串,而不是真正的空(其他方法正确地清除公式单元格)。可以通过将
For
循环的内容替换为cell.ParentNode.RemoveChild cell
@t.m来解决此问题。在某些情况下,如果ClearFormulea
处理的范围包括一些包含引用正在处理范围之外的单元格的公式的单元格,则也会产生意外结果(例如,如果A1
=1
,B1
==D1
,D1
=2
,在A1:B1
上运行ClearFormulea
会导致A1
=1
,B1
==2
)@chrisneilsen-感谢您的宝贵提示:(1)在我看来,一个真正的空的ing可以在
子节点上执行,否则在完全删除单元后,我必须重新索引单元的所有后续相邻节点我了解到,对超出范围的单元格的引用被解释为纯数字类型的数据,没有任何可能的公式痕迹。-非常感谢,将编辑一条警告:-)衷心邀请您为您认为是最好的解决方案勾选绿色复选标记,在过去三年中,您已经获得了许多有价值的答案。见@苏萨索洛
Option Explicit
Sub ExampleCall()
Dim rng As Range: Set rng = Sheet1.Range("a11:b14")
'a) Get range data as xml spreadsheet value
Dim s As String: s = rng.value(xlRangeValueXMLSpreadsheet) ' //or: s = rng.Value(11)
'b) delete formulae and write data back to range
ClearFormulae s ' call sub changing s (By Reference)
rng.value(xlRangeValueXMLSpreadsheet) = s
End Sub
Sub ClearFormulae(s)
'Purpose: delete formulae in xlRangeValueXMLSpreadsheet contents of a given range
'Author : https://stackoverflow.com/users/6460297/t-m
'Date : 2020-07-18
'[1]Set xml document to memory
Dim xDoc As Object: Set xDoc = CreateObject("MSXML2.DOMDocument.6.0")
'[2]Add namespaces.
xDoc.SetProperty "SelectionNamespaces", _
"xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet' " & _
"xmlns:ht='http://www.w3.org/TR/REC-html40'"
'[3]Load cells with formulae into xml document.
If xDoc.LoadXML(s) Then ' load wellformed string content
Dim cell As Object, cells As Object
Set cells = xDoc.SelectNodes("//ss:Cell[@ss:Formula]") ' XPath using namespace prefixes
For Each cell In cells
cell.RemoveAttribute ("ss:Formula")
cell.SelectSingleNode("ss:Data/@ss:Type").Text = "String"
cell.SelectSingleNode("ss:Data").Text = ""
Next cell
'[4] return xml as string content
s = xDoc.XML
End If
End Sub
Sheet2.Range("D2").Resize(rng.Rows.Count, rng.Columns.Count).value(11) = s