2016-04-10 11 views
0

グッド...新VBAのプログラミングやイブニング

私はVBAに非常に新しいです...が、たったの約一週間のためにそれで遊んで、そして最適化するのに役立つする必要がありますされているVBAコードを最適化するための助けが必要マクロ。

現在、実行には約23秒かかっていますが、それを少し落としたいと考えていました。

最初のステップは、 を「ファイルの場所を選択」するプッシュボタンで、その後DBから一つのテーブルには「隠された」というワークシートにダウンロードされ、最終的には、列B:Lは、「UPS料金表」

に「非表示」からコピーされます

任意の提案を大幅にあなたは全体のプロセスを遅くすることができるOLEDB接続を行っている

Sub Selectfile() 

Dim filename As String 

filename = Application.GetOpenFilename(MultiSelect:=False) 

Range("c2") = filename 

Dim StartTime As Double 
Dim SecondsElapsed As Double 
StartTime = Timer 

Dim cnn As ADODB.Connection 
Dim rs As ADODB.Recordset 
Dim sQRY As String 
Dim rng As Range 
Dim cell As Range 
Dim sourcefile As String 


sourcefile = Sheet1.Range("C2") 
Sheets("Hidden").Visible = True 
Set cnn = New ADODB.Connection 
Set rs = New ADODB.Recordset 
Set rng = Sheet9.Range("B1:B762") 

cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
"Data Source=" & sourcefile & ";" 
sQRY = "SELECT * FROM Tariff" 
rs.CursorLocation = adUseClient 
rs.Open sQRY, cnn, adOpenStatic, adLockReadOnly 
Application.ScreenUpdating = False 
Sheet9.Range("A1").CopyFromRecordset rs 
rs.Close 
Set rs = Nothing 
cnn.Close 
Set cnn = Nothing 

For Each cell In rng 
If cell <> "Letter" And cell <> "NDA" And cell <> "NDAS" And cell <> "2DA" And cell <> "3DS" And cell <> "GND" Then cell.Value = cell.Value * 1 
Next cell 

    Sheets("Hidden").Select 
    Range("B1").Select 
    Range(Selection, Selection.End(xlToRight)).Select 
    Range(Selection, Selection.End(xlDown)).Select 
    Selection.Copy 
    Sheets("UPS Tariff").Select 
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ 
     :=False, Transpose:=False 
    Range("A1").Select 
    Sheets("Hidden").Select 
    Range("A1").Select 
    Range(Selection, Selection.End(xlToRight)).Select 
    Range(Selection, Selection.End(xlDown)).Select 
    Application.CutCopyMode = False 
    Selection.Clear 
    Sheets("Info").Select 

Sheets("Hidden").Visible = xlVeryHidden 
SecondsElapsed = Round(Timer - StartTime, 2) 

'Notify user in seconds 
    MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation 

End Sub 
+0

あなたの 'For Each'ループの目的は何ですか?あなたは 'cell.Value = cell.Value * 1'とは何を考えていますか?また、あなたのループの 'if'は、セルごとに6回、セルの値を読み、' Rng'のサイズ(762)を掛けたものに注意してください。そのため、変数を使って1回だけ読み取るか、配列を使用してください。 –

答えて

3

を高く評価しています。それにもかかわらず、あなたのコードで改善できるものはほとんどありません。

  • 1)あまり多くの範囲を選択しないでください。
  • 2)コードにwith文を使用してみます。これはあなたのプロセスをかなりスピードアップします。例えば

    次のコード:

    Sheets("Hidden").Select 
    Range("B1").Select 
    Range(Selection, Selection.End(xlToRight)).Select 
    Range(Selection, Selection.End(xlDown)).Select 
    Selection.Copy 
    Sheets("UPS Tariff").Select 
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ 
        :=False, Transpose:=False 
    Range("A1").Select 
    Sheets("Hidden").Select 
    Range("A1").Select 
    Range(Selection, Selection.End(xlToRight)).Select 
    Range(Selection, Selection.End(xlDown)).Select 
    Application.CutCopyMode = False 
    Selection.Clear 
    Sheets("Info").Select 
    

はこのような何かに変換することでした:

With Sheets("Hidden") 
     'copy your selection 
     .Range(.cells(1,2), .cells(.UsedRange.Rows.Count, .UsedRange.Columns.Count)).Copy' e.g. if you want to select the whole area in the worksheet 

     'paste selection to the destination cell 
     Sheets("UPS Tariff").Range("A1").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ 
      :=False, Transpose:=False 

     Application.CutCopyMode = False'gets rid of the highlighted copy area under your Sheets workbook 

     'clears the initial selection 
     .Range(.cells(1,2), .cells(.UsedRange.Rows.Count, .UsedRange.Columns.Count)).Clear 
    End With 

    Sheets("Info").Select 

だけでなく、コードはVBAプロセッサのための、より効率的になること、それ一度あなたがそれを見直し/変更する必要があるならば、あなたはもっと読みやすくなります。

本当にスピードアッププロセスは、以下の行であることをもう一つ:

Application.ScreenUpdating = False 

上記のコードの新しい行が実行されるたびにちらつき、画面を停止します。

Application.Calculation = xlCalculationManual 

上記は、ワークシートの変更を行うたびにすべての式が再計算されるのを停止します。あなたが確認する必要がありますしかし、このようなworksheet_Activate, Worksheet_Change, ...

など、すべてのワークシートのイベントを無効に

Application.EnableEvents = false 

もう一つ、一度すべてのコードが実行して終了したことを、あなたは再びこれらの機能を有効に(そうでない場合はあなたの細胞が停止します画面の再表示が停止します)。

通常、私はすべてのサポートコードを置く新しいモジュールを作成します。そこで私は、次の2つの関数を作成します。

Public Sub EnableExcel() 
    Application.ScreenUpdating = True 
    Application.Calculation = xlCalculationAutomatic 
    Application.EnableEvents = True 
End Sub 

Public Sub DisableExcel() 
    Application.ScreenUpdating = False 
    Application.Calculation = xlCalculationManual 
    Application.EnableEvents = False 
End Sub 

あなたが見ることができるように、これらの関数はpublicとしてマークされているので、あなたのワークブックの中にどこからでもアクセスすることができます。

その後、私の手順は、次のようになります。あなたが見ることができる何

Private Sub DoSomeStuff() 
    On Error GoTo EarlyExit 
    Call DisableExcel 

    'this will fail as it is division by zero 
    MsgBox 1/0 

EarlyExit: 
    Call EnableExcel 
    If Err.Description <> vbNullString Then MsgBox Err.Description 
End Sub 

は、重要なエラーキャッチャーです。私は本当にこれらのオンラインについてもっと読むことをお勧めします。基本的にコードが実行することは、コード実行中に何かが失敗した場合(私がゼロで割り算しようとしている例を作成した場合)、コードは完全に失敗するわけではなく、エラーメッセージをユーザーに表示します。エラーの説明。また、コードが失敗した場合は、EnableExcelマクロが何であっても実行されるようにします。

これは実際にほんのちょっとしたヒントです。 VBAでより多くのことを処理したり、より多くのことを読んだりすると(例えばStackOverflowで)、より良いものになります。がんばろう!

+1

返事と助けをありがとうございました。 私はこれでもっと遊んでいきます。 よろしくお願いいたします –

関連する問題