2016-08-03 105 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 

个人,虽然我已经发现,最大的性能提升一般自带停用计算。