2016-08-03 124 views
0

我對此很新(昨天開始),所以也許有人有一些建議。我創建了一個宏,它使用每月值的新列和公式更新下載表,同時保持每年和靜態值不變。該代碼執行其預期功能,而是通過穿過環需要近30分鐘,以循環時庫存= 25縮短VBA宏的運行時間

Sub New_monthly() 

    Dim i As Integer 

    Dim Measure As Integer 

    Dim Count As Integer 

    Dim Stock As Integer 

    Dim Monthend As Long 


    Stock = Application.WorksheetFunction.CountIf(Range("AP1:AP50"), ">0") 

    Monthend = Range("AS1").Value 


    For i = 0 To Stock - 1 
     ' Copy old values and move them over one space 

     Range("B54:B115").Offset(i * 115, 0).Select 
     Selection.Insert Shift:=xlToRight 

     ' Enter new values 

     Cells(108 + i * 115, 2).Value = Monthend 
     Cells(109 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(109 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(110 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(110 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(111 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(111 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(112 + i * 115, 2).Formula = "=BDH(" & Cells(112 + i * 115, 1).Address & "," & Cells(111 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(113 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(113 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(114 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(114 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(115 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(115 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 

     For Measure = 0 To 5 
      Cells(54 + i * 115 + Measure * 9, 3).Value = Monthend 
      For f = 0 To 7 
       Cells(55 + i * 115 + Measure * 9 + f, 3).Formula = "=BDH(" & Cells(19 + i * 115 + f, 1).Address & "," & Cells(54 + i * 115 + Measure * 9, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
      Next f 
      Cells(57 + i * 115 + Measure * 9, 3).Formula = "=AVERAGE(" & Cells(58 + i * 115 + Measure * 9, 3).Address & ":" & Cells(62 + i * 115 + Measure * 9, 3).Address & ")" 
     Next Measure 
    Next i 

End Sub 
+1

既然你開始了,這裏有一些提示...... 1.「CountIf」是找到最後一行的不可靠的方法。你可能想看到[This](http://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-vba/11169920#11169920)2.避免使用'.Select '。你可能想看到[This](http://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba-macros)。如果他們是連續的,你可以在一個範圍內一次輸入公式。你不需要單獨做。 –

+0

對於Bloomberg來說,最好的方法是通過傳遞數組來調用Vba中的函數,將返回值存儲在另一個數組中,並將結果數組轉儲到報表/數據表中。避免在單元格中寫很多公式。特別是BDH是異步的,它的管理將變得非常混亂。 – cyboashu

+0

謝謝,我將在未來記住這一點! –

回答

1

,您應該關閉ScreenUpdating和計算。

Sub New_monthly() 

    Dim i As Integer 
    Dim Measure As Integer 
    Dim Count As Integer 
    Dim Stock As Integer 
    Dim Monthend As Long 

    Stock = Application.WorksheetFunction.CountIf(Range("AP1:AP50"), ">0") 

    Monthend = Range("AS1").Value 

    With Application 
     .ScreenUpdating = False 
     .Calculation = xlCalculationManual 
    End With 

    For i = 0 To Stock - 1 
     ' Copy old values and move them over one space 

     Range("B54:B115").Offset(i * 115, 0).Select 
     Selection.Insert Shift:=xlToRight 

     ' Enter new values 

     Cells(108 + i * 115, 2).Value = Monthend 
     Cells(109 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(109 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(110 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(110 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(111 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(111 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(112 + i * 115, 2).Formula = "=BDH(" & Cells(112 + i * 115, 1).Address & "," & Cells(111 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(113 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(113 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(114 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(114 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
     Cells(115 + i * 115, 2).Formula = "=BDH(" & Cells(100 + i * 115, 1).Address & "," & Cells(115 + i * 115, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 

     For Measure = 0 To 5 

      Cells(54 + i * 115 + Measure * 9, 3).Value = Monthend 
      For f = 0 To 7 
       Cells(55 + i * 115 + Measure * 9 + f, 3).Formula = "=BDH(" & Cells(19 + i * 115 + f, 1).Address & "," & Cells(54 + i * 115 + Measure * 9, 1).Address & ",$AS$1,$AS$1,""DAYS=C"")" 
      Next f 
      Cells(57 + i * 115 + Measure * 9, 3).Formula = "=AVERAGE(" & Cells(58 + i * 115 + Measure * 9, 3).Address & ":" & Cells(62 + i * 115 + Measure * 9, 3).Address & ")" 
     Next Measure 
    Next i 

    With Application 
     .ScreenUpdating = True 
     .Calculation = xlCalculationAutomatic 
    End With 

End Sub 
+0

psst,你忘記在代碼結束時將它們重新打開,將它們關閉兩次atm;) – DragonSamu

+0

@DragonSamu謝謝! – 2016-08-03 08:48:09

+0

爲了確保您不會弄亂其他代碼部分,您應該保存ScreenUpdating和Calculation的以前的值,並在最後恢復保存的值(可能由於某些原因,Calculation的默認值爲xlCalculationSemiautomatic) –

1

除了什麼其他人說,這裏有個文章,我發現有幫助:

With Application.Excel 
    .ScreenUpdating = False 
    .DisplayStatusBar = False 
    .Calculation = xlCalculationManual 
    .EnableEvents = False 
End With 

https://blogs.office.com/2009/03/12/excel-vba-performance-coding-best-practices/

基本上在你的代碼的開頭添加此

並在此結束:

With Application.Excel 
    .ScreenUpdating = True 
    .DisplayStatusBar = True 
    .Calculation = xlCalculationAutomatic 
    .EnableEvents = True 
End With 

您還可以使用

ActiveSheet.DisplayPageBreaks = False 'at the beginning and True at the end 

個人,雖然我已經發現,最大的性能提升一般自帶停用計算。