Excel VBA在特定范围内使用Proper的性能

这是一个函数,它检查列B和C中的单元格,并根据特定的testing应用Proper函数。

 Sub proper_function() Dim rng, cell As Range Set rng = Range("B:B", "C:C") For Each cell In rng If Not cell.HasFormula Then cell.Value = WorksheetFunction.Proper(cell.Value) End If Next cell End Sub 

这需要很长的时间来处理,并已经崩溃Excel的场合。

我宁愿它通过与文本而不是整列的单元格,我认为我需要稍微修改for循环,但不能得到它的工作,什么是最好的方式来写这个,所以它不会慢放下床单?

谢谢

试试这个改变(未经testing):

 Sub proper_function() Dim rng as Range Dim cell As Variant Set rng = Range("B:B", "C:C") For Each cell In ActiveSheet.Range(rng.Address).SpecialCells(xlCellTypeConstants) cell.Value = WorksheetFunction.Proper(cell.Value) Next cell End Sub 

但是我也可以find最后一行,如另一个答案中所build议的那样,并且仅将rng设置为所使用的范围。 另外,正如Thomas指出的那样,如果您将具有常量单元格的volatile函数或函数作为先例,那么Application.ScreenUpdating.Calculation是非常重要的。 这也可能是提高你的速度的关键。

我不是WorksheetFunction Proper的粉丝,因为它不正确的大写收缩(例如can't, doesn't, I'll变得Can'T, Doesn'T, I'Ll )。 我在Excel中使用额外规则的正确案例的答案有我自己的函数TitleCase ,正确的大写收缩。

Target范围只包含具有常数值的非空白单元格(无公式)

 Set Target = Intersect(.Range("B:C"), .UsedRange).SpecialCells(xlCellTypeConstants) 

closuresScreenUpdatingCalculation大大提高了性能。 Application.ScreenUpdating = False Application.Calculation = xlCalculationManual


 Sub proper_function() Dim Target As Range, cell As Range With Worksheets("Sheet1") On Error Resume Next Set Target = Intersect(.Range("B:C"), .UsedRange).SpecialCells(xlCellTypeConstants) On Error GoTo 0 End With If Not Target Is Nothing Then Application.ScreenUpdating = False Application.Calculation = xlCalculationManual For Each cell In Target If Not cell.HasFormula Then cell.Value = WorksheetFunction.Proper(cell.Value) End If Next cell Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = False End If End Sub 

如果您尝试循环遍历.xlsx或.xlsm文件中的每个单元格,则可能会遇到问题,因为它们有1,048,576行,而且这样做了两次! 无论你做什么都会导致放缓。

您可以将其限制在可能包含数据的范围内,而不是使用B:B和C:C的全部范围。 没有看到你的工作表,我不能肯定地说,这样做的最好方法,但总的来说,尝试这样的事情:

 Sub Properiser() Dim rngAll As Range Dim rngCell As Range Dim lngLast As Long lngLast = Range("B" & Rows.Count).End(xlUp).Row If Range("C" & Rows.Count).End(xlUp).Row > lngLast Then lngLast = Range("C" & Rows.Count).End(xlUp).Row End If Set rngAll = Range("B1", "C" & lngLast) For Each rngCell In rngAll If Not rngCell.HasFormula Then rngCell.Value = WorksheetFunction.Proper(rngCell.Value) End If Next rngCell End Sub 

这将在列B中find最后使用的行,然后在列C中find,并使用较大的一个作为范围的结束点。

还有其他方法可以使用,比如使用UsedRange属性来查找文件中实际使用了多less行和列,但是在没有看到数据的情况下很难说出其中的一个可能对您有用。

编辑扩展:

现在,你提到你宁愿让这个过程只查看包含文本的单元格; 有几种方法可以做到这一点。

选项1:检查空单元格

如果你怀疑你是通过很多空单元格弹跳,你可以简单地检查你的If条件中的单元格内容。

 if len(rngCell.value) <> 0 then 'Function end if 

选项2:检查非文本值

不幸的是,我们没有一个简单的单一function,可以检查字母数字文本; 我们需要走一条消除的道路。 从而:

 if len(rngCell.value) <> 0 then if isnumeric(rngcell.value) = False AND _ iserror(rngcell.value) = false then 'Assume it's text and perform our function End if End if 

…等等。 您可以根据需要在IF循环中堆叠尽可能多的检查。