2017-05-04 2 views
0

希望のVBAモジュールを書く方法をフィードバックしたいと思います。 私のファイルには、新しいデータが外部ソース(Bloomberg)から収集されるときに値が変化する複数の列があります。次に、これらの範囲内の値の1つが、常に同じ($ A $ 1と$ A $ 2)の2つのセルの積より大きい場合は、メッセージを取得したいと思います。さらに、私は複数のシートを持っているので、モジュールがすべてのシートに適用されていることを確認したいと思います。私は、インターネットを探るように私は答えが「交差が含まれる同様の質問を参照してください、しかしVBAモジュール:複数の範囲に "交差"機能を使用する

Private Sub Workbook_SheetCalculate(ByVal Sh As Object) 
With Sh 
    Set r1 = Sh.Range("N1:N50") 
    Set r2 = Sh.Range("AA1:AA50") 
    Set r3 = Sh.Range("AN1:AN50") 
    Set r4 = Sh.Range("BA1:BA50") 
    Set r5 = Sh.Range("BN1:BN50") 
    Set r6 = Sh.Range("CA1:CA50") 
    Set myMultipleRange = Union(r1, r2, r3, r4, r5, r6) 
    Dim myMultipleRange as Range 
    Dim Cell as Range 
    For Each Cell in myMultipleRange.Cells 
    With Cell 
    If .Value2 > 0.1 * $A$1 * $A$2 Then 
    MsgBox ("Ticker: " & Sh.Name & ", Today's volume in the " & Cells(row,column -1) " & " serie is " & Cells" & " contracts") 

最初の選択肢:

は、インターネットとのStackOverflowを検索した後、私は二つの選択肢を思い付きました"-関数。私は、2つ以上の範囲の交差を表すRangeオブジェクトを返すことを理解しています。しかし、モジュールとの違いは何ですか?どの方法がより速いのですか?私は私のファイルが巨大なので、最速のモジュールを欲しい!

私はアップセット交差機能

Private Sub Workbook_SheetCalculate(ByVal Sh As Object) 
With Sh 
    Dim r1, r2, r3, r4, r5, r6, my MultipleRange as Range 
    Set r1 = Sh.Range("N1:N50") 
    Set r2 = Sh.Range("AA1:AA50") 
    Set r3 = Sh.Range("AN1:AN50") 
    Set r4 = Sh.Range("BA1:BA50") 
    Set r5 = Sh.Range("BN1:BN50") 
    Set r6 = Sh.Range("CA1:CA50") 
    Set myMultipleRange = Union(r1, r2, r3, r4, r5, r6) 
    If Target.Value > (0.1 * sh.Range("A1").Value * sh.Range("A2").Value 
    If Not Intersect(Target, myMultipleRange) Is Nothing Then 
    MsgBox ("Ticker: " & Sh.Name & ", Today's volume in the " & Cells(row,column -1) " & " serie is " & Cells" & " contracts 

と第二のモジュールを記述しようとしたあなたが好む、あなたは改善の余地を参照していますか?

大変助かりました!

+0

のみ最初のアプローチは動作します。しかし、これは最速の方法ではありません。最速のアプローチは配列です。その後、すべての可能性のある "一致"が検索され、メッセージボックスに表示されます(複数の場合は一度にすべて表示されます)。私はあなたが作業用のサブを書いてから、[Code Review](http://codereview.stackexchange.com/)に投稿して改善することをお勧めします。 – Ralph

+0

あなたの返信ありがとう!エラーのある方向に私を押し込むことができますか?そして、理想的には、それぞれの発生に対してメッセージボックス通知をしたいと思います。この場合、私はあなたの助言に従うべきですか?敬具。 – HJA24

答えて

0

これらの例が擬似コードとして意図されており、解決策を示してくれることを願っています。それは有効なVBAコードとして意図されていた場合は、

Sub Workbook_SheetCalculate(ByVal Sh As Object) 
    ' Assign range to an array for speed, could just use the range object in a similar way 
    Dim myRange As Range 
    Dim myArray As Variant 
    Set myRange = Sh.Range("N1:N50,AA1:AA50,AN1:AN50,BA1:BA50,BN1:BN50,CA1:CA50") 
    myArray = myRange.Cells 
    ' Just calculate the product once 
    Dim product As Double 
    product = Sh.Range("A1").Value * Sh.Range("A2").Value 
    ' Loop through range, message if value is greater than product 
    Dim n As Long 
    For n = 1 To UBound(myArray) 
     If myArray(n, 1) > product Then 
      MsgBox "Sheet name: " & Sh.Name & ", Cell address: " & myRange.Cells(n).Address 
     End If 
    Next n 
End Sub 

以下のエラーで私のノートを参照してください。あなたが範囲の交差点または共用を行うには何も必要はありません、ただ1つの範囲のオブジェクトでそれらをすべてリスト..

複数のメッセージボックスをポップアップするのは、特に「ファイルが巨大」であり、潜在的に多くのメッセージボックスがある場合は、ユーザーにとって使い勝手が悪いです。私はあなたのブックのどこかに1つの文字列を出力し、文字列にすべての希望のアドレスを格納することをお勧めします。


エラーが:その他の小さな問題がありますが、これらの問題のそれぞれは、あなたのサブは、致命的なエラーを持ってしまいます。

  • あなたは、関連するEnd SubEnd WithEnd Ifでブロックし、IFSとの潜水艦を終了する必要があります。
  • ループの終了はNext loopvariableとする必要があります。
  • 定義していない変数を使用すると、rowcolumnのようになります。
  • だけMsgBox "my message"ないMsgBox ("my message")
  • を使用し、それはあなたが何かに返された値を代入している場合を除きSh.Range("A1").Value
  • MsgBoxは、括弧内の文字列を取らないべきであるときだけ$A$1のように自分のアドレスを明記して、範囲の値にアクセスしようとすると、 With Shを使用している場合は、Sh.で何かを開始する必要はありません。(Set r1 = .Range("A1")など)を使用してください。これによりエラーは発生しませんが、Withは無意味です。 (すべてのエラーが削除されたら)