2016-05-25 19 views
1

Erstplakat hier, Amateur VBA-ist. Ich habe Code-Logic-Erfahrung in Matlab, aber ich habe festgestellt, dass VBA über mich hinaus ist. Unten ist der Code, den ich verwende, um lokale Minima und Maxima für einen bestimmten Datensatz mit mehreren Peaks zu bestimmen. Leider sind die Daten "Noisy"; Dies bedeutet, dass es mehrere lokale Maxima/Minima gibt, da wir die Trends zwischen den wahren Extrema aufgrund der Fluktuation im Zählerstand verfolgen.
Ich habe einen Code bearbeitet, den ich woanders gefunden habe. Ich dachte, er würde diese wahren Minimumpunkte bestimmen (ich kann sie bestimmen, wenn der Flow startet/stoppt), da die Maxima nie ein Problem waren. Aber wenn es die markierte Linie (zweite Runde von lngCnt = lngCnt + 1) erreicht, gibt es einen "Laufzeitfehler 9: Index außerhalb des Bereichs". Ich habe versucht, das Problem zu untersuchen, aber ich konnte nicht verstehen, was verschrieben wurde, um es zu beheben, oder sehen, wie die Antwort auf meinen Code angewendet wurde.Ermittlung der Minima, Index außerhalb des Bereichs Fehler

Hier ist mein Code Ich verwende:

Sub maxmin() 
Dim X 
Dim Y 
Dim lngRow As Long 
Dim lngCnt As Long 

X = Range([A2], Cells(Rows.Count, "C").End(xlUp)) 'self defining function for the range over which the data will be analyzed, data in spreadsheet must start in L26 
Y = Application.Transpose(X) 'creates a column rather than a row 


For lngRow = 2 To UBound(X, 1) - 1 'defines the function for the long variable row, to the upper bound of the column 
    If X(lngRow, 3) > X(lngRow - 1, 3) Then 'logic statement to assist in max/min 
     If X(lngRow, 3) > X(lngRow + 1, 3) Then 'logic statement 
      lngCnt = lngCnt + 1 
      Y(1, lngCnt) = X(lngRow, 1) 
      Y(2, lngCnt) = X(lngRow, 2) 
      Y(3, lngCnt) = X(lngRow, 3) 
     End If 
    Else 
     If X(lngRow - 1, 1) < 100 Then 'this and the following line determine where the min is located based off the change in flow rate 
      If X(lngRow, 1) > 150 Then 
       lngCnt = lngCnt + 1 
       Y(1, lngCnt) = X(lngRow, 1) 
       Y(2, lngCnt) = X(lngRow, 2) 
       Y(3, lngCnt) = X(lngRow, 3) 
      End If 
     End If 
    End If 
Next lngRow 

ReDim Preserve Y(1 To 3, 1 To lngCnt) 

Range("D2:F4300 ") = Application.Transpose(Y) 'prints my data to desired cells 
End Sub 

Mustersatz von Daten (über einen Zeitraum von etwa 55 Minuten, wobei die Ellipsen eine Fortsetzung dieses Trends darstellen) würde lauten:

0 3000 
0 2900 
0 2850 
0 2825 
0 2800 
24 2800 
23 2775 
21 2775 
19 2750 
170 3400 
245 3600 
290 3800 
290 4000 
290 4200 
... 
305 11600 
175 11800 
23 11700 
19 11600 
20 11500 
0 11400 
0 11300 
0 11200 
0 11100 

Was ist mit der Indizierung mit dieser Zeile gibt mir einen tiefgestellten Fehler?

Kann jemand auch eine bessere Weise anbieten, mein Ausgangsarray auf nur die Zellen zu skalieren, die dieses benötigt? Ich habe versucht, den lngCnt-Wert zu verwenden, aber es funktioniert nicht. Zuvor arbeitete der Code mit Array-Werten anstelle von 100 und 150.

Vielen Dank im Voraus für Ihre Hilfe!

+0

Die Stern Zeile sollte nie ein „Index außerhalb des zulässigen Bereichs“ Fehler produzieren - sind Sie sicher, Das ist die Problemlinie? –

+0

Auch: Ihr 'X' hat Dimensionen (#rows, 3), also wird nach der Transponierung' Y' (3, #rows) sein. Sie können Redim Preserve nicht verwenden, um * beide * Dimensionen anzupassen: es funktioniert nur bei der letzten Dimension eines mehrdimensionalen Arrays. –

+0

Vielen Dank für Ihre Antwort! Es stellt sich heraus, dass die Redim-Anweisung den Subscript-Fehler ausgelöst hat, obwohl das Debugging das lngCnt zeigt (was für mich keinen Sinn ergab). @TimWilliams In Bezug auf die zweite Frage, gibt es eine einfache Möglichkeit, das zu erreichen? –

Antwort

1
Range("D2:F4300") = Application.Transpose(Y) 

Range("D2").resize(Ubound(Y,2), Ubound(Y,1)).Value = Application.Transpose(Y) 

Ohne die transponieren könnte man die Grenzen um Flip würde:

Range("D2").resize(Ubound(Y,1), Ubound(Y,2)).Value = Y 
+0

Danke! Ich schätze deine Hilfe sehr –

Verwandte Themen