First time poster here, amateur VBA-ist. I have past code-logic experience in Matlab, but I've found VBA is beyond me. Below is the code I'm using to determine local minima and maxima for a certain data set with multiple peaks. Unfortunately the data is "Noisy"; meaning there are multiple local maxima/minima as we follow the trends between the true extrema due to the fluctuation in the meter reading.
I have edited some code I found elsewhere in a way I thought it would determine these true minimum points (I can determine them via when flow starts/stops), as the maxima never seemed a problem. But when it reaches the starred line (second round of lngCnt = lngCnt + 1) there is a "Run time error 9: subscript out of range". I tried to research the problem but I was not able to understand what was being prescribed to fix it, or see how the answer applied to my code.
第一次海报,业余VBA-ist。我以前在Matlab中有过代码逻辑的经验,但是我发现VBA已经超出了我的能力范围。下面是我用来确定具有多个峰值的特定数据集的局部最小值和最大值的代码。不幸的是,数据是“嘈杂的”;也就是说,当我们跟踪真极值之间的趋势时,由于仪表读数的波动,存在多个局部极大值/极小值。我编辑了一些我在别处找到的代码,我认为它可以确定这些真正的最小点(我可以通过流何时开始/停止来确定它们),因为最大值似乎从来都不是问题。但当它到达星形线(lngCnt = lngCnt + 1的第二轮)时,会出现“运行时间错误9:下标超出范围”。我试着研究这个问题,但是我不明白要用什么来解决这个问题,也不知道这个答案是如何应用到我的代码中的。
Here is my code I'm using:
下面是我使用的代码:
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
Sample set of data (over a period of approximately 55 minutes, where the ellipses represent a continuation of that trend) would read:
样本数据集(在大约55分钟内,椭圆表示趋势的延续)如下:
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
What about the indexing with that line gives me a subscript error?
用这一行的索引会给我一个下标错误吗?
Also, can anyone offer a better way to scale my output array to only the cells this needs? I've tried using the lngCnt value but it does not work. Previously the code worked by using array values in place of the 100 and 150.
另外,谁能提供一种更好的方法来将输出数组扩展到只需要的单元格中呢?我尝试过使用lngCnt值,但它不起作用。以前,代码使用数组值代替100和150。
Thank you ahead of time for your help!
提前感谢您的帮助!
1 个解决方案
#1
1
Range("D2:F4300") = Application.Transpose(Y)
could be
可能是
Range("D2").resize(Ubound(Y,2), Ubound(Y,1)).Value = Application.Transpose(Y)
Without the transpose you would flip the bounds around:
如果没有转置,你就会翻转边界:
Range("D2").resize(Ubound(Y,1), Ubound(Y,2)).Value = Y
#1
1
Range("D2:F4300") = Application.Transpose(Y)
could be
可能是
Range("D2").resize(Ubound(Y,2), Ubound(Y,1)).Value = Application.Transpose(Y)
Without the transpose you would flip the bounds around:
如果没有转置,你就会翻转边界:
Range("D2").resize(Ubound(Y,1), Ubound(Y,2)).Value = Y