- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个函数,在搜索整个事件工作表后,该函数将返回包含特定字符串的单元格总数。很像“查找和替换”中“找到的 x 个单元格”的工作原理。
到目前为止我有这个:
Function FINDIST(stringToFind)
Dim counter As Integer: counter = 0
For Each Cell In ActiveSheet.UsedRange.Cells
If InStr (Cell, stringToFind) > 0
Then counter = counter + 1
End If
Next
End Function
最佳答案
另一种方法:
Function FINDIST(stringToFind) As Long
FINDIST = Evaluate("SUM(IFERROR(SEARCH(" & Chr(34) _
& "*" & stringToFind & "*" & Chr(34) & "," _
& ActiveSheet.UsedRange.Address & ",1),0))")
End Function
这会在使用范围内的每个单元格中搜索stringToFind
,如果在单元格中找到该字符串,则返回一个包含 1 的数组;如果未找到,则返回错误。使用 IFERROR
部分将错误强制转换为零,并且 SUM
对生成的二进制数组求和。
这只会计算每个单元格中 stringToFind
的出现一次,即使它出现多次,但查看您的代码,我认为这就是您正在寻找的内容。
希望对您有帮助!
更新
出于好奇,我做了一些测试来看看这两种方法如何比较(直接从范围读取与使用评估)。这是我使用的代码:
Option Explicit
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long
Sub test()
Dim ticks As Long
Range("A1:AA100000").Value = "adlrkjgalbabyajglakrjg"
ticks = GetTickCount
FINDIST1 ("baby")
Debug.Print "Read from range: ", GetTickCount - ticks
ticks = GetTickCount
FINDIST ("baby")
Debug.Print "Evaluate: ", GetTickCount - ticks
End Sub
Function FINDIST(stringToFind) As Long
FINDIST = Evaluate("SUM(IFERROR(SEARCH(" & Chr(34) _
& "*" & stringToFind & "*" & Chr(34) & "," _
& ActiveSheet.UsedRange.Address & ",1),0))")
End Function
Function FINDIST1(stringToFind) As Long
Dim counter As Long: counter = 0
Dim c As Range
Dim firstAddress As String
With ActiveSheet.UsedRange
Set c = .Find(stringToFind, LookIn:=xlValues, LookAt:=xlPart)
If Not c Is Nothing Then
firstAddress = c.Address
Do
counter = counter + 1
Set c = .FindNext(c)
Loop While Not c Is Nothing And c.Address <> firstAddress
End If
End With
FINDIST1 = counter
End Function
更新2
克里斯·尼尔森在下面的评论中提出了两个非常好的观点:
ActiveSheet.Evaluate
比 Application.Evaluate
更快。评论中 Charles Williams 的文本链接解释了这种行为。Variant
数组将比任何其他方法执行得更好。为了完整起见,我发布了我测试的variant
数组方法的版本:
Function FINDIST_looping(stringToFind) As Long
Dim vContents, lRow As Long, lCol As Long, lCounter As Long
vContents = ActiveSheet.UsedRange.Value2
For lRow = LBound(vContents, 1) To UBound(vContents, 1)
For lCol = LBound(vContents, 2) To UBound(vContents, 2)
lCounter = IIf(InStr(vContents(lRow, lCol), stringToFind), _
lCounter + 1, lCounter)
Next lCol
Next lRow
FINDIST_looping = lCounter
End Function
Doug Glancy 提出了另一个非常好的观点,即可以使用 COUNTIF
代替 SEARCH
。这导致了一个非数组公式解决方案,并且在性能方面应该主导我的原始公式。
这是道格的公式:
FINDIST_COUNTIF = ActiveSheet.Evaluate("COUNTIF(" _
& ActiveSheet.Cells.Address & "," & Chr(34) & "*" _
& stringToFind & "*" & Chr(34) & ")")
事实上,Doug 的观点意味着 Evaluate()
不是必需的。我们可以从 WorksheetFunction
对象调用 Countif
。因此,如果目标是从电子表格调用此函数,则无需使用 Evaluate()
或将其包装在 UDF
中 - 这是典型的带有通配符的 COUNTIF
应用程序。
结果:
Read from range: 247,495 ms (~ 4 mins 7 secs)
Application.Evaluate: 3,261 ms (~ 3.2 secs)
Variant Array: 1,706 ms (~ 1.7 secs)
ActiveSheet.Evaluate: 1,257 ms (~ 1.3 secs)
ActiveSheet.Evaluate (DG): 602 ms (~ 0.6 secs)
WorksheetFunction.CountIf (DG):550 ms (~ 0.55 secs)
与使用 Range.Find()
相比,Application.Evaluate
的速度似乎快了约 75 倍(?!)此外,原始代码(使用 Integer
更改为 Long
)在约 8 秒内运行。
此外,在这种特殊情况下,Activesheet.Evaluate
似乎实际上比 Variant
数组更快。作为 WorksheetFunction
方法调用 CountIf
与 Evaluate
方法之间的区别似乎很小。
警告:在 UsedRange
中找到 stringToFind
的频率可能会影响几种方法的相对性能。我使用上述范围 (A1:AA100000)
运行了 Activesheet.Evaluate
和 Variant Array
方法,但只有前十个单元格具有匹配的值字符串。
结果(6 次运行的平均值,方差几乎很小):
Activesheet.Evaluate: 920 ms (~ 1. sec)
Variant Array: 1654 ms (~ 1.7 secs)
这很有趣 - 在这种情况下,ActiveSheet.Evaluate
的性能似乎比变体数组稍好(除非我在循环代码中做了一些可怕的事情,在这种情况下,请告诉我)。此外,Variant
方法的性能实际上......相对于字符串的频率是不变的。
在Win7
下的EXCEL 2010
上运行。
关于function - 自定义查找功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24338296/
main.cpp #include "Primes.h" #include int main(){ std::string choose; int num1, num2; w
似乎函数 qwertyInches() 应该可以工作但是当我在 main() 中调用它时它给了我 [Error] called object 'qwertyInches' is not a funct
我无法理解 C++ 语法的工作原理。 #include using namespace std; class Accumulator{ private: int value; public:
在 类中声明 函数成员时,我们可以同时执行这两种操作; Function first; Function() second; 它们之间有什么区别? 最佳答案 Function 代表任意函数: void
“colonna”怎么可能是一个简单的字符串: $('td.' + colonna).css('background-color','#ffddaa'); 可以正确突出显示有趣单元格的背景,并且: $
我正在尝试将网页中的动态参数中继到函数中,然后函数将它们传递给函数内部的调用。比如下面这个简化的代码片段,现在这样,直接传入参数是没有问题的。但是,如何在不为每个可能的 colorbox 参数设置 s
C++ 中是否有一种模式允许您返回一个函数,它返回一个函数本身。例如 std::function func = ...; do { func = func(); } while (func);
我正在将 Windows 程序集移植到 Linux。我有一些代码要移植。我实际上是 linux 中 C 的新手。我知道 C 基础知识是一样的! typedef struct sReader {
我一直在寻找一个很好的解释,所以我很清楚。示例: this.onDeleteHandler(index)}/> 对比 对比 this.nameChangedhandler(event, perso
function(){}.__proto__ === Function.prototype 和 Function.prototype === function(){}.__proto__ 得到不同的结
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function 据说 Propert
VBA 中的函数没有特殊类型。我很难理解如何在 Excel VBA 中将函数作为参数添加到函数中。 我想要完成的是这样的事情: function f(g as function, x as strin
所以我正在尝试制作一个包(我没有在下面包含我的 roxygen2 header ): 我有这个功能: date_from_text % dplyr::mutate(!!name := lubr
尝试从 std::function 派生一个类,对于初学者来说,继承构造函数。这是我的猜测: #include #include using namespace std; template cla
我正在尝试编写一个返回另一个函数的函数。我的目标是编写一个函数,它接受一个对象并返回另一个函数“search”。当我使用键调用搜索函数时,我想从第一个函数中给定的对象返回该键的值。 propertyO
我非常清楚函数式编程技术和命令式编程技术之间的区别。但是现在有一种普遍的趋势是谈论“函数式语言”,这确实让我感到困惑。 当然,像 Haskell 这样的一些语言比 C 等其他语言更欢迎函数式编程。但即
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 8 年前。 Improv
我在stackoverflow上查过很多类似的问题,比如call.call 1 , call.call 2 ,但我是新人,无法发表任何评论。我希望我能找到关于 JavaScript 解释器如何执行这些
向 Twilio 发送 SMS 时,Twilio 会向指定的 URL 发送多个请求,以通过 Webhook 提供该 SMS 传送的状态。我想让这个回调异步,所以我开发了一个 Cloud Functio
作为 IaC 的一部分,A 功能应用 ,让我们将其命名为 FuncAppX 是使用 Terraform 部署的,它有一个内置函数。 我需要使用 Terraform 在函数应用程序中访问相同函数的 Ur
我是一名优秀的程序员,十分优秀!