【问题标题】:Dynamic formula that subtracts 2 cell values based on values from 2 other cells根据来自其他 2 个单元格的值减去 2 个单元格值的动态公式
【发布时间】:2017-01-19 17:12:04
【问题描述】:

我正在努力为这个问题想出一个标题,因为我不知道如何最好地提出这个问题。我相信我可以在下面用图片更好地解释我的问题。

这也可能对公式要求太高,需要VBA编码

我想生成一个公式来分析 2 列值的范围。第一列是股票的调整收盘价。第二列是一个计算出的振荡器,旨在预测超买和欠买状态。

在这个公式中,如果计算出的震荡指标低于 30,则认为股票是欠买的,如果高于 80,则认为是超买。因此,我想计算第一次出现欠买和下一次超买之间的收盘价差.

然后我希望这个公式循环遍历该年度股票价格的所有实例。理论上,股票会出现多次超买和超买。

我认为这些范围基本上是在周期中的。周期的开始是在最后一个超买值之后的第一个欠买数。周期结束是下一个超买值。

股票欠买/超买的天数范围很大,因此这需要一个动态公式。

我考虑过使用嵌套的 if 和 choose 语句,但我想不出足够强大的东西。有人可以为我指明正确的方向,使用哪些功能来完成此任务?这是需要 VBA 的东西吗?

我想做的例子

感谢您抽出宝贵时间阅读和思考此问题。如果我可以为您澄清任何事情,请告诉我。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    您需要为此类问题设置一个有限状态机,使用 VBA 或辅助列都没有关系。

    所以有三种状态

    (1)初始状态

    (2)“已启动”状态

    (3) 处于周期状态

    三个过渡

    (A) 从 (1) 到 (2) 发现超买股票时

    (B) 从 (2) 到 (3) 找到下一个买进不足的股票时

    (C) 当发现下一个超买股票时,从 (3) 回到 (1)。

    所以你需要设置一个列来处理这些包含公式的状态和转换

    =IF(AND(I2=1,H3>80),2,IF(AND(I2=2,H3<30),3,IF(AND(I2=3,H3>80),1,I2)))
    

    从(比如)I3 开始(I2 设置为 1)。

    那么你需要另外两个帮助列来计算句点的结束和开始

    =IF(AND(I1=2,I2=3),MAX(J$1:J1)+1,"")
    
    =IF(AND(I1=3,I2=1),MAX(K$1:K1)+1,"")
    

    最后是一个专栏来总结​​差异

    =IFERROR(INDEX(G$2:G$100,MATCH(ROWS(L$1:L1),J$2:J$100,0))-INDEX(G$2:G$100,MATCH(ROWS(L$1:L1),K$2:K$100,0)),"")
    

    找到第 n 个周期的差异的 VBA 如下所示 - 您可以从(比如)I2 开始这样称呼它

    =IFERROR(stock(G$2:G$100,H$2:H$100,ROWS(N$1:N1)),"")
    

    所以当你拉下公式时,它会寻找下一个周期。

    Option Explicit
    
    Function Stock(Actual As Range, Predicted As Range, n As Integer) As Variant
    
    Dim i, rows, LastRow, period As Long
    Dim state As Integer
    Dim startFound, endFound As Boolean
    Dim actualValue, predictedValue, startValue, endValue As Double
    
    state = 1
    period = 0
    startFound = False
    endFound = False
    rows = Actual.rows.Count
    If rows <> Predicted.rows.Count Then
        Stock = CVErr(xlErrValue)
        Return
    End If
    
    For i = 1 To rows
        actualValue = Actual.Cells(i, 1).Value
        predictedValue = Predicted.Cells(i, 1).Value
    
        If state = 1 And predictedValue > 80 Then
            state = 2
        Else
            If state = 2 And predictedValue < 30 Then
                state = 3
                period = period + 1
                If period = n Then
                    startValue = actualValue
                    startFound = True
                End If
            Else
                If state = 3 And predictedValue > 80 Then
                    state = 1
                    If period = n Then
                        endValue = actualValue
                        endFound = True
                        Exit For
                    End If
                End If
            End If
        End If
    
    Next I
    
    If startFound And endFound Then
        Stock = startValue - endValue
    Else
        Stock = CVErr(xlErrValue)
    End If
    End Function
    

    【讨论】:

    • 非常感谢您的回复!我想我最初错过了我的目标。我希望这些州是连续的。我的意思是,状态 1 将是第一个超买状态的欠买状态。状态 2 将是下一个第一个欠买状态到下一个超买状态的第一个实例。这种模式在工作表中进行,直到没有留下任何东西。我假设总共会有 7-15 个州。因此,不是只有 3 个状态和这 3 个之间的计算公式,而是可以让它分配唯一的
    • 每个州的数字?再次感谢您抽出宝贵时间来解决这个问题!
    • 这是一个潮湿的日子,老实说,没有太多其他事情发生,所以这是练习我的 VBA 的好机会。问题是状态会从 1 到 2 到 3 循环再回到 1,但是每次周期数增加一个,因此它应该能够处理任意数量的周期(实际数据中只有两个)。可能需要调整的地方是状态在周期结束时设置回 1,也许应该是 2,因为该周期以超买股票结束,因此下一个欠买股票可能会触发新周期。
    • 抱歉延迟回复。您能澄清一下公式中要更改的内容吗?我玩过这个公式,无法正确分配句点。我仍然无法让它按递增顺序排列。它只有 1-3 的数字。如果我增加重置值,它仍然会重复更高级别的数字。
    • 我已经在我的家用电脑上设置好了,所以直到今天晚上才能完成这些公式。我没有举例说明如何调用 UDF - 将其添加到我的答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多