Excel VBA脚本帮助

时间:2016-07-28 19:42:25

标签: excel vba excel-vba

我编写了一个VBA脚本来比较excel中的字段。 Excel冻结第二次我点击按钮。它从不显示任何错误消息。每次我尝试运行它时,我都必须使用control alt delete来关闭excel。 我的一个变量被注释掉了,因为在我开始工作之后,我计划将数据复制到另一张表而不是更改字体。只是一个FYI

Private Sub CommandButton4_Click()
Dim rng1, rng2, cell1, cell2 As Range
Set rng1 = Worksheets("Main").Range("B:B")
Set rng2 = Worksheets("CSV Transfer").Range("D:D")
'Set rng3 = Worksheets("Data").Range("A:A")

For Each cell1 In rng1
For Each cell2 In rng2

If IsEmpty(cell2.Value) Then Exit For
If cell1.Value = cell2.Value Then

 cell1.Font.Bold = True
 cell1.Font.ColorIndex = 2
 cell1.Interior.ColorIndex = 3
 cell1.Interior.Pattern = xlSolid
 cell2.Font.Bold = True
 cell2.Font.ColorIndex = 2
 cell2.Interior.ColorIndex = 3
 cell2.Interior.Pattern = xlSolid

End If

Next cell2
Next cell1


End Sub

编辑:已更改整个帖子以反映我的实际问题。

1 个答案:

答案 0 :(得分:1)

你的宏不冻结,你只是没有给它足够的时间来完成 - 这是一个lonnnngggg时间。 Excel的行限制为1,048,576行,您将每行中的每个单元格与另一行中的每个单元格进行比较。这总共有1,099,511,627,776个细胞比较。假设你每秒可以进行100,000次比较(这可能只是,而没有格式化),这最终将在127天内完成。

我建议做几件事。首先,当你为这样的列分配范围时......

a = [1, 2, 3]
b = ['a', 'b', 'c']
c = []

def foo(x, y):
    global c
    result = x * y
    c.append(result)
    return result


>>> c
[]

>>> [foo(x, y) for x, y in zip(a, b)]
['a', 'bb', 'ccc']

>>> c
['a', 'bb', 'ccc']

...你得到每个可能的单元格 - 而不仅仅是用过的单元格。找到每列中的最后一个非空单元格,并根据它设置范围:

Set rng1 = Worksheets("Main").Range("B:B")

除非您拥有庞大的数据集,否则这可能会使您的运行时间达到几分钟或几秒而不是几天。要进一步改进它们,请一次停止从工作表中请求单个值并将它们拉入数组:

Dim LastRow As Long
Dim ColumnB As Range
With Worksheets("Main")
    LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
    Set ColumnB = .Range("B1:B" + LastRow)
End With

然后,循环并比较内存中的值。它看起来可能更像这样(我将格式化为Sub):

Dim BValues As Variant
BValues = ColumnB.Value

如果你的表现仍然太低,我也至少会关闭ScreenUpdates。