【问题标题】:Finding first lowest value找到第一个最低值
【发布时间】:2021-01-24 05:13:14
【问题描述】:

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 = DATE - 日期

H = 买入 - B-C

I = 卖出 - D-B

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

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

这个公式的确定是11-02中的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&gt;=$B16+IF($I16&gt;=$H16,T$1,-T$1)),1))-$G16,"")

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

我在一个文件中使用了这些公式的版本,其中我将 OMAS 和 11-02 合并到一个文件中,它似乎工作正常,但当我有 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

【问题讨论】:

  • 为了下载文件,应该登录网站。我认为没有人会为了下载文件而花时间创建新的配置文件。您可以发布数据的图像。
  • 感谢邪恶蓝猴的提示。我更新了我的问题,希望它更容易理解。

标签: excel


【解决方案1】:

公式解决方案

很难理解您在寻找什么。我希望我明白了。这是我的“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 才能保留宏。

【讨论】:

  • 非常感谢 S-O。我会尝试一下,看看它是否适用于我的实际文件,如果我有任何问题,请告诉你。我特别喜欢你分解公式并解释每个部分的作用的方式。对于只了解 Excel 基础知识的人来说,你不知道这有多棒。
  • 邪恶蓝猴,再次感谢您的努力,但公式无法正常工作。我在 11-02 的 2 个版本上进行了尝试……一个独立版本和一个作为表单附加到 OMAS 的版本。在第一个版本中,我在工作表版本上得到一个值“0”和一个“2”。您是否可以通过 ATC1114@COX.NET 将您的电子邮件地址发送给我,我会将文件的副本发送给您,以便您查看我正在处理的内容。我会通过这个论坛发送它们,但它们太大了。 THX
  • 我的假设是:在单机版中,没有正确指定 0MAS 文件的链接。尝试在打开 0MAS 时粘贴公式。尽管如此,即使它工作正常,它也很可能返回与附加版本相同的结果(我猜不应该是 2 而是 1)。在这种情况下,我的假设是:公式不按日期过滤列表。在 0MAS 中,11/3 是 LMPX 行的最早日期吗?通过邮件共享文件将是最后一次恢复(毕​​竟这个网站是为公共解决而制作的)。我会先努力的。
  • 是的,11/3 是最早的日期,并且 OMAS 是同时开放的。我只建议仅将电子邮件用于向您发送实际文件的副本,这将为您提供与我正在使用的完全相同的数据,而我们的其余对话将在此论坛上进行,但我将继续玩你的公式,希望能找到解决方案。再次感谢。
  • 我添加了一个公式来获得有关该公式所针对的单元格的反馈。你能用它并报告结果吗?
猜你喜欢
  • 1970-01-01
  • 2018-05-03
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 2022-12-14
  • 1970-01-01
  • 2013-05-24
  • 2014-12-07
相关资源
最近更新 更多