返回列表 上一主題 發帖

[發問] (己解決!) 想請教各位,那一種寫法比較快一點? (想優化一下)

[發問] (己解決!) 想請教各位,那一種寫法比較快一點? (想優化一下)

本帖最後由 StanleyVic 於 2011-8-9 14:50 編輯

各位大大好,本人想優化一下代碼, 請教如下:
如果把公式 : AN6 =IF(D6<>"",T6-AI6,"") 寫成 vba
1. 本人有幾萬行記錄,所以寫了2種寫法,想請教那一個比種可以跑得快一點?
   (可以的話..解釋一下)
2. 如各位大大有更好的寫法,請指教.

====================================================
寫法 (一)
Private Sub CommandButton12_Click()
Dim j,AA as integer
    Sheets("Status B Log").Activate
    For j = 6 To Range("A65536").End(xlUp).Row
        If Cells(j, "D") <> "" Then
           AA = Cells(j, "T") - Cells(j, "AI")
           Cells(j, "AN") = Application.WorksheetFunction.Round(AA, 2)
        Else
           Cells(j, "AN") = ""
        End If
    Next j
        ThisWorkbook.Save
        MsgBox (" Quoted vs Invoice ( Variance ) - OK !")
End Sub

------------
寫法 (二)

Private Sub CommandButton12_Click()
Dim i As Integer
    Sheets("Status B Log").Activate
    For i = 6 To Range("D65536").End(xlUp).Row
        Cells(i, "AN").FormulaR1C1 = "=IF(RC[-36]<>"""",RC[-20]-RC[-5],"""")"
        Cells(i, "AN") = Round(Cells(i, "AN").Value, 2)
    Next i
        ThisWorkbook.Save
        MsgBox (" Quoted vs Invoice ( Variance ) - OK !")
End Sub
NeverTry , NeverNo !

本帖最後由 StanleyVic 於 2011-7-19 14:45 編輯

回復 8# GBKEE

謝謝"GBKEE-版主"給我的意見..
感謝你引導了我.. 關於Timer 和與Time 區別.
現在我可以實現了"毫秒"的出現.

另外 :
不明白的地方.......... 我.......
好的..我會再多多學習.增強一下自己的基本功.
謝謝你對我們新人的期待 ^_^"
NeverTry , NeverNo !

TOP

回復 6# StanleyVic    回復 7# StanleyVic
你的疑問論壇已提問很多了, 不是不回答你.建議你多看 論壇裡的發問.
期待你說:"我了解啦"

format 是如何寫才能算出 毫秒 ?
Timer (從前一個午夜算起到現在所經過的秒數秒數) 與 Time(系統時間)   有差別

TOP

本帖最後由 StanleyVic 於 2011-7-19 12:30 編輯

回復 3# oobird

回方法四 : "oobird" 您好! 你的方法是先全都定義好.能快速跑完代碼.謝謝你的建議.
但本人真的很新手..也有很多代碼的地方,還未了解透.因想多學習....希望你不介意..能為我解釋一下.萬分感謝.
一. 代碼中 Dim j&, n&, d, t, ai, arr   的 & 是什麼時意思..?

   n = .Range("d65536").End(xlUp).Row
   d = .Range("d6:d" & n)
   t = .Range("t6:t" & n)
   ai = .Range("ai6:ai" & n)

二. 以上我了解到是你想預先定義好, 方便運行vba 公式 AN6 =IF(D6<>"",T6-AI6,"") 而建立的
   可能我對 ReDim arr 不太熟和不了解,讓我下面不能解讀了.. (以下綠色是我了解的地方,如有錯請更正我的思考)

   ReDim arr(1 To UBound(d), 0)                                                                       ' 數組 由 [D6:DN]    
    For j = 1 To n - 6                                                                                      ' 記錄的行數 (只有內容的行數 6~n)    
        If d(j, 1) <> "" Then                                                                               ' 公式裏的判斷語句.if(d6<>""    
          arr(j, 0) = Application.WorksheetFunction.Round(t(j, 1) - ai(j, 1), 2)             ' 這句 arr(j,0) 中的 0 是什麼 ?   
        End If
    Next j                                                                                                        
    .Cells(6, "AN").Resize(UBound(d), 1) = arr                                                       ' 不明白這句代碼    
    End With

再次謝過"oobird" 辛苦了.. !! :loveliness: :handshake
NeverTry , NeverNo !

TOP

本帖最後由 StanleyVic 於 2011-7-19 11:39 編輯

首先,本人十分感謝"GBKEE" 和 "oobird" 的回答,
真想不到..一個公式 AN6 =IF(D6<>"",T6-AI6,"")  在vba 中可以千萬萬化.
好. 我現就總結一下 : 如果我了解錯,請各位大大指出.

我的寫法1 和 2 的時間都一樣是 1.157407 秒.
但如果要我說快, 我會選2, 因為1中我細心查真的如 GBKEE 所說,我迴了圈子.
因為寫法1當中, 可以直接把 AA 代入,不用再多一層.所以我寫 2會比1 快一點.
AA = Cells(j, "T") - Cells(j, "AI")
Cells(j, "AN") = Application.WorksheetFunction.Round(AA, 2)

'----------------------------
方法3 (GBKEE) 和 方法4 (oobird)
老實說,太令我震驚, 我的 顯示是 0秒..
問題 :
1. 請問大大, 你們的format 是如何寫才能算出 毫秒 ?
2. 請問方法3(GBKEE) 中 以下這句代碼的用處是什麼 ?
    Set Rng = Rng.SpecialCells(xlCellTypeConstants)   'D欄有資料範圍
   我不明白它的意思..
NeverTry , NeverNo !

TOP

呵呵!些微的差距倒是不必去計較
只是提供個人的思考方向供樓主參考。

TOP

本帖最後由 GBKEE 於 2011-7-19 08:16 編輯

回復 3# oobird超版
是你的快 只給一次值          .Cells(6, "AN").Resize(UBound(d), 1) = arr
我的程式給了二次值           .Value = "=Round(IF(RC[-36]<>"""",RC[-20]-RC[-5],""""),2)"
                                                  .Value = .Value
於我的PC約慢了 0.078秒   
PS : 2003 用 Rows.Count 測試

TOP

幾萬行應該用陣列方式
  1. Private Sub CommandButton1_Click()
  2. Dim j&, n&, d, t, ai, arr
  3. tm = Timer
  4.    With Sheets("Status B Log")
  5.    n = .Range("d65536").End(xlUp).Row
  6.    d = .Range("d6:d" & n)
  7.    t = .Range("t6:t" & n)
  8.    ai = .Range("ai6:ai" & n)
  9.    ReDim arr(1 To UBound(d), 0)
  10.     For j = 1 To n - 6
  11.         If d(j, 1) <> "" Then
  12.           arr(j, 0) = Application.WorksheetFunction.Round(t(j, 1) - ai(j, 1), 2)
  13.         End If
  14.     Next j
  15.     .Cells(6, "AN").Resize(UBound(d), 1) = arr
  16.     End With
  17.         ThisWorkbook.Save
  18.         MsgBox (" Quoted vs Invoice ( Variance ) - OK !") & "用時" & Timer - tm & "秒"
  19. End Sub
複製代碼

TOP

回復 1# StanleyVic
你可在兩寫法 設立一變數為Time,程式結束前   MsgBox    Time-變數  測試哪一寫法快
另提供一不用迴圈的解法
  1. Sub Ex()
  2.     Dim Rng As Range, T As Date
  3.     T = Time
  4.     With Sheets("Status B Log")
  5.         Set Rng = Range("D6", Range("D65536").End(xlUp))  'D欄資料範圍
  6.         Rng.Offset(, 36) = ""                             'N欄清除 (將D欄的範圍位移到N欄的範圍)
  7.         Set Rng = Rng.SpecialCells(xlCellTypeConstants)   'D欄有資料範圍
  8.         With Rng.Offset(, 36)                             'D欄有資料範圍位移到N欄的範圍
  9.             .Value = "=Round(IF(RC[-36]<>"""",RC[-20]-RC[-5],""""),2)"
  10.             .Value = .Value
  11.         End With
  12.     End With
  13.     ThisWorkbook.Save
  14.     MsgBox (" Quoted vs Invoice ( Variance ) - OK !" & Chr(10) & "共用時: " & Format(Time - T, "HH:MM:SS"))
  15. End Sub
複製代碼

TOP

        靜思自在 : 多做多得。少做多失。
返回列表 上一主題