VBA速度慢,不适用于更长的数据集

时间:2018-07-13 17:36:26

标签: excel vba excel-vba

感谢您抽出宝贵的时间对此进行研究。我试图弄清楚为什么此宏与较小的关键字列表一起使用,但是当我们将其放入较大的列表中时,它将无法正常工作并且执行速度太慢。

程序的工作原理如下: 输入A列:我们粘贴感兴趣的关键字 B列是输出1:它填充了A不需要的所有杂音词或停用词。(会有第二张纸,我们可以在该表中创建诸如、、但是,等等) 列C为输出2:其中填充了A中的所有特殊字符。

这就是我的...用较小的词而不用较大的词集。被困了一段时间。

n=tt.tensordot(mu_gk, np.ones((C_k, 1)), [[2], [1]]),
p=tt.tensordot(np.ones((G, 1)), p_kc, [[1], [0]])

3 个答案:

答案 0 :(得分:2)

使用Characters集合非常慢,因此您可能会陷入某种程度的性能低下。

但是,可能有些地方可以节省时间。

例如:

For j = 1 To Len(s)
    cell.Characters(j, 1).Text = Replace(cell.Characters(j, 1).Text, Chr(147), """")
    cell.Characters(j, 1).Text = Replace(cell.Characters(j, 1).Text, Chr(148), """")

这里完全不需要使用字符集:由于您只清除了所有字体颜色,因此无需使用Characters方法,而只需通过.Value进行替换< / p>

编辑:可能值得在其中设置一个标记以循环跟踪是否已应用任何字符级格式,因此可以避免不必要地使用{ {1}}并依靠.Characters


您可以将其从循环中删除:

.Value

并替换为

 cell.Interior.Color = vbWhite
 cell.Characters.Font.Color = vbBlack

循环之前


KeywordSearch.Interior.Color = vbWhite
KeywordSearch.Font.Color = vbBlack

可能更快,因为:

If word = "and" Or word = "not" Or word = "or" Then
    For j = 1 To Len(word)
        cell.Characters(offset + j - 1, 1).Text = UCase(Mid(word, j, 1))
    Next
End If

答案 1 :(得分:1)

要加快在电子表格中修改值的速度,需要先禁用屏幕更新并在处理完成后重新启用:

禁用更新:

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

重新启用更新:

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

答案 2 :(得分:0)

问题肯定与您使用Characters集合有关。如果您想给找到的不同单词加上颜色,可以,但是在操作所有字符串值之后再做。

边注 :重复使用ActiveSheet令我感到恐惧。请在子例程的开头将其设置为变量,并改用该变量。

Dim Sheet as Worksheet
Set Sheet = ActiveSheet
.
Sheet.Range(...
.
Set Sheet = nothing

考虑将数据读取/写入变量,而不是范围。 (至少对于文本操作而言)这是一个如何将Range加载到变体中的示例:

Dim vNoiseWords as Variant
vNoiseWords = Sheet.Range("B2", Sheet.Range("B2").End(xlDown)).Value2

写作正好相反(但我通常必须转置数组)。

然后,您可以遍历变体数组并标识需要在单元格中着色的文本。

最小化与工作表的所有互动

...因此限制以ActiveSheet.Cell.Range.开头的任何行,并仅在需要完成时才进行处理。

即使Cell = UCase(Cell)也浪费大量时间。

您做得更好

Value = UCase(Cell.Value2)
If Value <> Cell.Value2 then Cell.Value2 = Value

更新

仅供参考,通过在代码部分之间添加时间戳,可以很容易地指出代码的慢速部分。这是一个简单的例程,我可以用来跟踪时间间隔并在立即窗口中显示结果。

Public Sub TimeStamp(Optional Prompt As String, Optional StartTimer As Boolean)
Static s_fTimer As Single, s_fIntervalTimer As Single
Dim fCurrTime As Single
    fCurrTime = Timer
    If StartTimer Then
        s_fTimer = fCurrTime
        s_fIntervalTimer = fCurrTime
    End If
    If Prompt <> vbNullString Then Prompt = " - " & Prompt
    Debug.Print Format((fCurrTime - s_fTimer), "0.000s") & Format((fCurrTime - s_fIntervalTimer), "(0.000s)") & Prompt
    s_fIntervalTimer = fCurrTime
End Sub

第一次调用它(或随时要重置总时间计数器)时,应像这样设置StartTimer = True

TimeStamp "Start of Program", True

之后,只需调用例程,并在可选提示下跟踪代码段即可:

TimeStamp "After Smart Quote Loop"

TimeStamp "The End"

然后,只需查看时间间隔,找到最大的时间间隔,然后将其缩小(如果您认为它们不合理)。您会发现与UI /单元格的每一次交互都是阻碍,但是在后台处理数据只需要很少的时间。