2016-12-02 121 views
1

這是一個函數,用於檢查B列和C列中的單元格,並根據特定測試應用Proper函數。Excel VBA在特定範圍內使用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循環,但不能得到它的工作,什麼是最好的方式來寫這個,所以它不會減慢表單的速度?

感謝

+0

如何多行數據,你呢? – Brian

+0

我們需要知道你的工作表是什麼樣的。一旦你達到了數據的結尾,你就想讓循環中斷,但是你還沒有給我們一個方法來確定它在哪裏。 – Fritz

回答

1

嘗試這種變化(未測試):

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 

但我也發現最後一排,在另一個答案建議,並設置rng只對使用範圍。另外,正如Thomas指出的那樣,如果您將常量單元格作爲先例,將揮發性函數或函數添加到其中,則需要添加Application.ScreenUpdating.Calculation。這也可能是提高速度的關鍵。

+0

感謝您的支持。很好奇,看看是否可以通過將Proper更改爲Lower來對Lower函數使用相同的代碼,但它不起作用? – Pete

+0

@Pete更改'WorksheetFunction.Proper(cell.Value) ''到LCASE(cell.Value)'(或'UCase'爲大寫)。另外,如果我的代碼解決了您的問題,請用綠色複選標記標記。 :-) – Brian

0

你可能會,如果你通過每一個細胞中的.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列中最後使用的列,然後在C列,並使用較大者作爲範圍的終點。

我們還可以使用其他方法,例如使用UsedRange屬性來查找文件中實際使用了多少行和列,但是如果沒有看到數據,很難說這些數據中的哪一個可能對您更好或不。

編輯以展開:

現在,你提到你寧願過程只看包含文本的單元格;有幾種方法可以做到這一點。

選項1:檢查空單元

如果你懷疑你經歷了很多空單元格的彈跳,你可以簡單地在你的。如果條件檢查單元格內容。

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

選項2:檢查非文本值

不幸的是,我們沒有能夠檢查字母數字文本的簡單,功能單一;我們需要走一條消除的道路。因此:

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循環中堆疊儘可能多的檢查。

1

我不是工作表功能Proper的粉絲,因爲它沒有正確地大寫收縮(例如can't, doesn't, I'll變成Can'T, Doesn'T, I'Ll)。我對Proper Case with extra rules in Excel的回答有我自己的功能TitleCase正確的大寫收縮。

Target範圍僅包含具有恆定值(無公式)

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

關閉ScreenUpdatingCalculation大大提高了性能的非空白單元格。 Application.ScreenUpdating =假 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 
+1

也許我不完全理解,但爲什麼你測試'如果不是cell.HasFormula',如果Range'Target'只是'xlCellTypeConstants'? – Brian