2017-05-04 4 views
0

Ich möchte ein Feedback bekommen, wie ich mein gewünschtes VBA-Modul schreiben kann. In meiner Datei habe ich mehrere Spalten, in denen sich die Werte ändern, wenn neue Daten von einer externen Quelle (Bloomberg) gesammelt werden. Als nächstes möchte ich eine Nachricht erhalten, wenn einer der Werte innerhalb dieser Bereiche größer ist als das Produkt zweier Zellen, die immer gleich sind ($ A $ 1 und $ A $ 2). Außerdem habe ich mehrere Blätter, deshalb möchte ich sicherstellen, dass das Modul für jedes Blatt gilt.VBA-Modul: Verwenden Sie die Funktion "Schnittmenge" für mehrere Bereiche

Nachdem die Suche im Internet und Stackoverflow Ich kam mit zwei Alternativen auf:

Die erste Alternative:

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") 

jedoch, wie ich das Internet erforschen ich ähnliche Fragen sehen, wo die Antworten umfassen die „Intersect "-Funktion. Ich verstehe, dass Intersect ein Range-Objekt zurückgibt, das den Schnittpunkt von zwei oder mehr Bereichen darstellt. Was ist aber genau der Unterschied zu meinem Modul? Und welche Methode ist schneller? Ich möchte das schnellste Modul, da meine Datei riesig ist!

Ich habe versucht, ein zweites Modul mit der Intersect-Funktion

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 

Welche Set-up zu schreiben bevorzugen Sie und haben Sie Raum für Verbesserungen sehen?

Hilfe wird sehr geschätzt!

+0

Nur der erste Ansatz funktioniert (sobald alle Fehler entfernt wurden). Das ist jedoch nicht der schnellste Ansatz. Der schnellste Ansatz wäre ein Array. Danach sollte das Array nach allen möglichen "Übereinstimmungen" durchsucht werden und dann sollten sie (wenn mehrere Vorkommen dann alle gleichzeitig sind) in einem Meldungsfeld angezeigt werden. Ich schlage vor, dass Sie ein funktionierendes Sub schreiben und es dann auf [Code Review] (http://codereview.stackexchange.com/) für Verbesserungen veröffentlichen. – Ralph

+0

Danke für Ihre Antwort! Könntest du mich in eine Richtung mit den Fehlern drängen? Und im Idealfall möchte ich für jeden Vorfall eine Benachrichtigung im Nachrichtenfenster. Sollte ich in diesem Fall trotzdem Ihrem Rat folgen? Mit freundlichen Grüßen. – HJA24

Antwort

0

Ich hoffe, diese Beispiele waren nur als Pseudo-Code gedacht und zeigen Ihnen eine Lösung. Wenn das als gültige VBA-Code bestimmt war, bitte meine Notizen auf den Fehler unter

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 

Hinweis sehen Sie nichts tun müssen mit Kreuzung oder Vereinigung von Bereichen zu tun, schreiben Sie sie einfach alle in einem Bereich Objekt .. .

Das Aufsperren mehrerer Nachrichtenfelder ist ziemlich benutzerunfreundlich, besonders wenn Ihre "Datei riesig" ist und es potenziell viele davon gibt. Ich würde empfehlen, alle gewünschten Adressen in einer Zeichenfolge zu speichern und dann die eine Zeichenfolge irgendwo in Ihrer Arbeitsmappe auszugeben.


Fehler: Es gibt noch andere kleinere Probleme, aber jedes dieser Probleme würde dazu führen, dass Unter einen fatalen Fehler haben.

  • Sie müssen U-Boote beenden, mit Blöcken und ifs mit den entsprechenden End Sub, End With, End If.
  • Muss für Schleifen mit Next loopvariable enden.
  • Verwenden Sie Variablen, die Sie nicht wie row und column definiert haben.
  • Versuch Bereichswerte zuzugreifen, indem nur unter Angabe ihrer Adresse wie $A$1 wenn es Sh.Range("A1").Value
  • sein sollte MsgBox keinen String in Klammern nicht nehmen, wenn Sie den zurückgegebenen Wert zu etwas zuweisen, verwenden Sie einfach MsgBox "my message" nicht MsgBox ("my message")
  • Wenn Sie With Sh verwenden, müssen Sie nichts mit Sh. starten, verwenden Sie einfach ., wie Set r1 = .Range("A1").Dies würde keinen Fehler verursachen, aber macht den With sinnlos.
Verwandte Themen