寻找第一个最低值

时间:2021-01-24 05:13:14

标签: excel

enter image description here这是参考:Aggregate function (small) returns zeros rather than the smallest values

我看到了这些公式,想知道它们的一个版本是否适用于我的情况:

A2=$A:$A)*($B:$B<>"")), 1),AGGREGATE(15,7, ($B:$B)/(($A2=$A:$A)*($B:$B<>"")), 1), "")

INDEX($A:$A,MATCH("zzz",$A:$A)))*($B$1:INDEX($B:$B,MATCH("zzz",$A:$A))<>"")), 1), "")

我正在努力让这个公式对我有用:

`=IFERROR(INDEX([0MAS.xlsb]MAS!$G$3:$G$366957,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$A$1:$A$366957)/([0MAS.xlsb]MAS!$A$1:$A$366957=$A318)/(([0MAS.xlsb]MAS!$C$3:$C$366957<=$B318+IF($I318<=$H318,-M$1,M$1))),1))-$G318,"")`

这个公式在一个叫11-02的文件里,每天生成一个单独的文件,即11-03、11-04等。OMAS是每天股市所有股票的MAIN文件.以下是 OMAS 中的列列表:

A = SYM – 股票列表:A、AA、AAP 等

B = LAST – 当天股票的收盘价。

C = LOW – 当天股票的最低价格。

D = HIGH – 当天股票的最高价格。

E = DIFF – D-C

F = OPEN – 股票的开盘价。

G = 日期 – 日期

H = 买入 – B-C

我 = 卖出 – D-B

11-02 具有完全相同的列,但要小得多。

我正在尝试获取 OMAS 的 C 列中的第一个值,该值低于 11-02 的 B318 + M1,在本例中为“1”。 M1 – AA1 列编号为 1 - 15。

此公式的确定为 IH。

如果 H>I,此公式在 11-02 中有效: =IFERROR(INDEX([0MAS.xlsb]MAS!$G$2:$G$366957,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$A$1:$A$366957)/([0MAS.xlsb]MAS!$A$1:$A$366957=$A16)/([0MAS.xlsb]MAS!$D$2:$D$366957>=$B16+IF($I16>=$H16,T$1,-T$1)),1))-$G16,"")

这是我试图改变的,看看如果 I

我在一个文件中使用了这些公式的版本,其中我将 OMAS 和 11-02 合并为 1 个文件,它似乎可以正常工作,但当我有 2 个文件时就不行了。任何人都可以提供任何帮助,我们将不胜感激。

我已将文件上传至:https://www.excelforum.com/excel-formulas-and-functions/1331382-number-of-days-it-took-a-stock-to-rise-sink-above-a-certain-level.html#post5458971

我会在此处上传文件,但我不知道该怎么做。 提前致谢, 悬崖

附言我想我应该解释一下我想要完成的任务。在每日下载中,比如说 11-02,我在 A 列 (SYM) 中找到了一个值,在本解释中是 A2 中的“LMPX”。我想将 M-AA 添加到 B2,如果选择“M”,则为 B2+1。然后我看看哪个更高,H2 或 I2。由于 I2 较高,我想在 OMAS 的 D 列中找到 >= 的第一个最低值。如果 H2 更高,我想在 OMAS 的 C 列中找到下一个最低值。在这个例子中,B2+1 是 21.82,所以我想在 OMAS 的 D 列中找到下一个最小值,即 >= 21.82,即“24.87”。然后我想移动到 G 列中的相应日期,即 11/3。然后我减去 11-02 的 G2 并从 11/3 中减去它,这将留下 1。这就是我正在寻找的值......股票需要多少天才能上涨/下跌取决于 H2 还是I2 更高。

我知道这很难理解,所以如果有人有任何问题,请提问,因为我真的需要这方面的帮助。我已经为此工作了 4 到 5 个月,这让我发疯了。

NEW SCREENSHOT

1 个答案:

答案 0 :(得分:0)

公式解决方案

很难理解您在寻找什么。我希望我明白了。这是我的“Book10”(每日简短文件)单元格 M2 的公式:

=IFERROR((IF($H2<$I2,INDEX([0MAS.xlsb]MAS!$G:$G,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$D:$D>$B2+M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1))-$G2,"")&IF($H2>$I2,INDEX([0MAS.xlsb]MAS!$G:$G,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$C:$C<$B2-M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1))-$G2,""))*1,"")

把它切成碎片,我们得到这个:

=IFERROR(                                                       'In case of error, nothing will be shown.
         (                                                       'This brackets is to multiply the result by one to turn it into a number.
          IF(
             $H2<$I2,                                            'If "Buy" is greater than "Sell"
             INDEX(                                              'we target
                   [0MAS.xlsb]MAS!$G:$G,                         'a cell in the column G of 0MAS
                   AGGREGATE(                                    'with
                             15,                                 'the smallest
                             6,                                  'valid value
                             ROW([0MAS.xlsb]MAS!$D:$D)           'thanks to their row (in column D)
                             *1/([0MAS.xlsb]MAS!$D:$D>$B2+M$1)   'filtered according to the cells that contains a value greater than Last plus the M-AA extra,
                             *1/ISNUMBER([0MAS.xlsb]MAS!$D:$D)   'that is not a header (text) and
                             *1/([0MAS.xlsb]MAS!$A:$A=$A2),      'has the same Symbol of the actual row.
                             1
                            )
                  ) - $G2,                                       'Such cell has a date value that we subtract to the cell in the column G of the actual row.
             ""
            )
          &
          IF(
             $H2>$I2,                                            'If "Sell" is greater than "Buy"
             INDEX(                                              'we target
                   [0MAS.xlsb]MAS!$G:$G,                         'a cell in the column G of 0MAS
                   AGGREGATE(                                    'with
                             15,                                 'the smallest
                             6,                                  'valid value
                             ROW([0MAS.xlsb]MAS!$C:$C)           'thanks to their row (in column C)
                             *1/([0MAS.xlsb]MAS!$C:$C<$B2-M$1)   'filtered according to the cells that contains a value smaller than Last minus the M-AA extra,
                             *1/ISNUMBER([0MAS.xlsb]MAS!$C:$C)   'that is not a header (text) and
                             *1/([0MAS.xlsb]MAS!$A:$A=$A2),      'has the same Symbol of the actual row.
                             1
                            )
                  ) - $G2,                                       'Such cell has a date value that we subtract to the cell in the column G of the actual row.
             ""
            )
         ) * 1,                                                  'The result is multiplied to return a number.
         ""
        )

如您所见,如果“买入”等于“卖出”,则不会有结果。

奖金公式

您可以使用此公式获得有关公式所针对的单元格的反馈:

=IF($H2<$I2,"Targeting cell D","")&IF($H2>$I2,"Targeting cell C","")& IFERROR((IF($H2<$I2,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$D:$D>$B2+M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1),"")&IF($H2>$I2,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$C:$C<$B2-M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1),""))*1,"") & " (value " & IFERROR((IF($H2<$I2,INDEX([0MAS.xlsb]MAS!$G:$G,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$D:$D>$B2+M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1)),"")&IF($H2>$I2,INDEX([0MAS.xlsb]MAS!$G:$G,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$C:$C<$B2-M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1)),""))*1,"") & "), Sybol: " & IFERROR(IF($H2<$I2,INDEX([0MAS.xlsb]MAS!$A:$A,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$D:$D>$B2+M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1)),"")&IF($H2>$I2,INDEX([0MAS.xlsb]MAS!$A:$A,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$C:$C<$B2-M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1)),""),"")&", Low: " & IFERROR(IF($H2<$I2,INDEX([0MAS.xlsb]MAS!$C:$C,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$D:$D>$B2+M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$D:$D)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1)),"")&IF($H2>$I2,INDEX([0MAS.xlsb]MAS!$C:$C,AGGREGATE(15,6,ROW([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$C:$C<$B2-M$1)*1/ISNUMBER([0MAS.xlsb]MAS!$C:$C)*1/([0MAS.xlsb]MAS!$A:$A=$A2),1)),""),"") & ", Starting data: " & $A2 & ", " & $B2 & ", " & $G2 & ", " & $H2 & ", " & $I2 & ", " & $M1



VBA 解决方案

试试这个代码:

Sub SubFirstLowestValue()
    
    'Declarations.
    Dim WksSource As Worksheet
    Dim RngSource As Range
    Dim WksRecord As Worksheet
    Dim RngRecord As Range
    Dim RngRecordList As Range
    Dim WksResult As Worksheet
    Dim RngResult As Range
    Dim BytExtraMargin As Byte
    Dim BytExtraMarginMin As Byte
    Dim BytExtraMarginMax As Byte
    Dim DblSourceIndex As Double
    Dim DblSourceIndexCount As Double
    Dim RngSourceSYMBOL As Range
    Dim RngSourceLAST As Range
    Dim RngSourceDATE As Range
    Dim RngSourceBUY As Range
    Dim RngSourceSELL As Range
    Dim RngRecordSYMBOL As Range
    Dim RngRecordLOW As Range
    Dim RngRecordHIGH As Range
    Dim RngRecordDATE As Range
    Dim RngTarget As Range
    Dim StrExistingAutoFilterAddress As String
    Dim StrSYMBOL As String
    Dim StrDATE As String
    Dim BytCounter01 As Double
    Dim BlnStatusBar As Boolean
    
    'Settings.
    Set WksSource = ActiveSheet
    Set RngSource = WksSource.Range("A2")
    Set WksRecord = ActiveSheet
    
    'Checking for eventual autofilter.
    If WksRecord.AutoFilterMode = True Then
        'Setting StrExistingAutoFilterAddress.
        StrExistingAutoFilterAddress = ActiveSheet.AutoFilter.Range.Address
    End If
    
    'Removing eventual autofilter.
    WksRecord.AutoFilterMode = False
    
    'Settings.
    Set RngRecord = WksRecord.Range("A2")
    Set RngRecordList = WksRecord.Range(RngRecord, RngRecord.End(xlDown).End(xlToRight))
    Set WksResult = ActiveSheet
    Set RngResult = WksResult.Range("M1")
    Set RngSourceSYMBOL = WksSource.Range("A2")
    Set RngSourceLAST = WksSource.Range("B2")
    Set RngSourceDATE = WksSource.Range("G2")
    Set RngSourceBUY = WksSource.Range("H2")
    Set RngSourceSELL = WksSource.Range("I2")
    Set RngRecordSYMBOL = WksRecord.Range("A2")
    Set RngRecordLOW = WksRecord.Range("C2")
    Set RngRecordHIGH = WksRecord.Range("D2")
    Set RngRecordDATE = WksRecord.Range("G2")
    BytExtraMarginMin = 1
    BytExtraMarginMax = 15
    DblSourceIndexCount = RngSource.End(xlDown).Row - RngSource.Row
    
    'Setting an autofilter on RngRecordList.
    RngRecordList.Offset(-1, 0).Resize(RngRecordList.Rows.Count + 1, RngRecordList.Columns.Count).AutoFilter
    
    'Compiling extra margins' list headers.
    For BytCounter01 = 0 To (BytExtraMarginMax - BytExtraMarginMin)
        RngResult.Offset(0, BytCounter01).Value = "+-" & BytExtraMarginMin + BytCounter01
    Next
    
    'Resetting RngResult.
    Set RngResult = RngResult.Offset(1, 0)
    
    'Sorting RngRecordList.
    With WksRecord.Sort
        .SortFields.Clear
        .SortFields.Add Key:=Intersect(RngRecordList, RngRecordSYMBOL.EntireColumn), _
                        SortOn:=xlSortOnValues, _
                        Order:=xlAscending, _
                        DataOption:=xlSortNormal
        .SortFields.Add Key:=Intersect(RngRecordList, RngRecordDATE.EntireColumn), _
                        SortOn:=xlSortOnValues, _
                        Order:=xlAscending, _
                        DataOption:=xlSortNormal
        .SetRange RngRecordList
        .Header = xlGuess
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
        .SortFields.Clear
    End With
    
    'Setting status bar.
    BlnStatusBar = Application.DisplayStatusBar
    Application.DisplayStatusBar = True
    
    'Covering the whole list in WksSource.
    For DblSourceIndex = 1 To DblSourceIndexCount
        
        'Refreshing status bar message.
        Application.StatusBar = "Progress: " & Round(DblSourceIndex / DblSourceIndexCount * 100, 0) & "% (" & DblSourceIndex & " of " & DblSourceIndexCount & ")"
        
        'Clearing the result row.
        For BytExtraMargin = BytExtraMarginMin To BytExtraMarginMax
            RngResult.Offset(0, BytExtraMargin - BytExtraMarginMin).Value = ""
        Next
        
        'Filtering RngRecordList for the given symbol if changed.
        If RngSourceSYMBOL <> StrSYMBOL Then
            RngRecordList.AutoFilter Field:=RngRecordSYMBOL.Column - RngRecordList.Column + 1, Criteria1:=RngSourceSYMBOL.Value
            StrSYMBOL = RngSourceSYMBOL.Value
        End If
        
        'Filtering RngRecodlist for the given date if changed.
        If RngSourceDATE <> StrDATE Then
            RngRecordList.AutoFilter Field:=RngRecordDATE.Column - RngRecordList.Column + 1, Criteria1:=">" & Month(RngSourceDATE.Value) & "/" & Day(RngSourceDATE.Value) & "/" & Year(RngSourceDATE.Value)
            StrDATE = RngSourceDATE.Value
        End If
        
        'Checking if RngSourceBUY is greater than RngSourceSELL or vice versa.
        Select Case True
            Case Is = RngSourceBUY < RngSourceSELL
                
                'Covering each visible (alias: unfiltered) cell in the "High" column of RngRecordList.
                For Each RngTarget In RngRecordList.Columns(RngRecordHIGH.Column - RngRecordList.Column + 1).SpecialCells(xlCellTypeVisible)
                    
                    'Covering each extra margin.
                    For BytExtraMargin = BytExtraMarginMin To BytExtraMarginMax
                        
                        'Checking if the given cell's value is bigger than the value of RngSourceLAST plus the given extra margin.
                        If RngTarget.Value > RngSourceLAST + BytExtraMargin And RngResult.Offset(0, BytExtraMargin - BytExtraMarginMin).Value = "" Then
                            
                            'Reporting the dates' difference between the given row in the RngRecordList and the date in RngSourceDATE.
                            RngResult.Offset(0, BytExtraMargin - BytExtraMarginMin).Value = WksRecord.Cells(RngTarget.Row, RngRecordDATE.Column).Value - RngSourceDATE.Value
                            
                        End If
                        
                        'If all the results for the given row has been specified, the code is skipped to CP_Result_row_filled.
                        If Excel.WorksheetFunction.CountBlank(WksResult.Range(RngResult, RngResult.Offset(0, BytExtraMarginMax - BytExtraMarginMin))) = 0 Then GoTo CP_Result_row_filled
                        
                    Next
                Next
                
            Case Is = RngSourceBUY > RngSourceSELL
                
                'Covering each visible (alias: unfiltered) cell in the "Low" column of RngRecordList.
                For Each RngTarget In RngRecordList.Columns(RngRecordLOW.Column - RngRecordList.Column + 1).SpecialCells(xlCellTypeVisible)
                    
                    'Covering each extra margin.
                    For BytExtraMargin = BytExtraMarginMin To BytExtraMarginMax
                        
                        'Checking if the given cell's value is smaller than the value of RngSourceLAST minus the given extra margin.
                        If RngTarget.Value < RngSourceLAST - BytExtraMargin And RngResult.Offset(0, BytExtraMargin - BytExtraMarginMin).Value = "" Then
                            
                            'Reporting the dates' difference between the given row in the RngRecordList and the date in RngSourceDATE.
                            RngResult.Offset(0, BytExtraMargin - BytExtraMarginMin).Value = WksRecord.Cells(RngTarget.Row, RngRecordDATE.Column).Value - RngSourceDATE.Value
                            
                        End If
                        
                        'If all the results for the given row has been specified, the code is skipped to CP_Result_row_filled.
                        If Excel.WorksheetFunction.CountBlank(WksResult.Range(RngResult, RngResult.Offset(0, BytExtraMarginMax - BytExtraMarginMin))) = 0 Then GoTo CP_Result_row_filled
                        
                    Next
                Next
        End Select
CP_Result_row_filled:
        
        'Setting the variables for the next row in WksSource.
        Set RngSourceSYMBOL = RngSourceSYMBOL.Offset(1, 0)
        Set RngSourceLAST = RngSourceLAST.Offset(1, 0)
        Set RngSourceDATE = RngSourceDATE.Offset(1, 0)
        Set RngSourceBUY = RngSourceBUY.Offset(1, 0)
        Set RngSourceSELL = RngSourceSELL.Offset(1, 0)
        Set RngResult = RngResult.Offset(1, 0)
        
    Next
    
    'Restoring eventual previous autofiler.
    WksRecord.AutoFilterMode = False
    If StrExistingAutoFilterAddress <> "" Then
        WksRecord.Range(StrExistingAutoFilterAddress).AutoFilter
    End If
    
    'Resetting status bar.
    Application.StatusBar = False
    Application.DisplayStatusBar = BlnStatusBar
    
    
End Sub

代码可以定制,但现在它被设计用于活动工作表上,该工作表将包含一个列表,该列表既是“记录”列表(比如 0MAS 文件),又是起始数据列表(比如 Book10 文件)。测试一下:

  1. 打开0MAS文件;
  2. 将代码复制粘贴到 VBA 模块中;
  3. 选择 MAS 表;
  4. 启动代码。

您很可能需要将文件的扩展名从 .xlsb 更改为 .xlsm 以保留宏。

相关问题