Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Мне нужно решить неявное уравнение в VBA

Автор вопроса: blendОтветов: 2

Я хочу указать другие параметры, указанные в функции, и получить решение для (угла), но получаю сообщение об ошибке: "недопустимый вызов процедуры или аргумент". Ошибка выполнения 5. Мне нужно вызвать функцию в лист эксель. Это довольно длинное уравнение. Кроме того, может случиться так, что я вхожу в бесконечный цикл, но я не знаю, как этого избежать.

 Function calculateangle(r, h, C, g, d, m, t, x, y As Single) As Single

 Dim a As Single
 a = 0

 While y <> (d + r - r * Cos(a) + (x - (t - r + r * Sin(a))) * Tan(a) - (g
 / (2 * ((((C * m * (2 * g * (h - (d + r - r * Cos(a)))) ^
 (1 / 2)) + m * (2 * g * (h - (d + r - r * Cos(a)))) ^ (1 / 2)) / (m +
 0.04593)) ^ 2) * (Cos(a)) ^ 2)) * (x - (t - r + r * Sin(a))) ^ 2)

     a = a + 0.01
 Wend

 MsgBox Round(a, 2)

 End Function
  • Одно примечание: r, h, C, g, d, m, t, x - это все варианты, а не отдельные. Единственный сингл y Scott Craner 24.03.2018
  • @ScottCraner Спасибо! Я объявил их все как одиночные, и теперь я получаю сообщение об ошибке: Выражение слишком сложное. Могу ли я что-нибудь сделать? blend 24.03.2018
  • разбить формулу на более мелкие части. Scott Craner 24.03.2018
  • @ScottCraner да, действительно, но дело в том, что я не могу разбить формулу на части, так как неизвестное (а) встречается во многих местах. blend 24.03.2018
  • 1. Если y уже выше или ниже (неизвестно, продвигает ли a = a + 0,01 результат вниз или вверх), то результат никогда не будет достигнут. 2. У вас может возникнуть проблема с a = a + 0,01, превышающим действительное значение equals, возможно, из-за 15-значной точности. Лучше округлить результат до значащих цифр y и увеличить a, чтобы не пропустить ни одного возможного результата совпадения. 3. Даже если вы нашли действительно равное уравнение, вы все равно а = а + 0,01 перед выходом из цикла, поэтому а - это первый шаг после равенства. 24.03.2018
  • @Jeeped 1. Y всегда положителен, и a также должно быть положительным, поэтому, начиная с 0, он обязательно увеличивается. 2. Да, я округлил до 2 цифр, а также попробовал код на питоне, и он работает, но здесь я все еще получаю слишком сложное выражение. blend 24.03.2018

excelvbaimplicitequation-solving

Ответы

Ответ 1 · рейтинг 1 · AJD

Одна очевидная проблема заключается в том, что вы используете Function, но не возвращаете значение.

Это действительно сложный кусок спагетти! Тем не менее, я предлагаю подход, подобный приведенному ниже, который поможет разделить различные биты и, таким образом, упростить отладку.

Function calculateangle(<...all the bits ...>) As Double
Dim a As Double
Dim tTolerance as Double
dim f1 as Double  ' sub sections to help untangle the spaghetti
Dim f2 as Double
Dim f3 as Double
Dim fFinal as Double
Dim tWithinTolerance as Boolean
    tWithinTolerance = false
    a = 0
    tTolerance = 0.01
    While not tWithinTolerance
        f1 = d + r - r * Cos(a)
        f2 = m*2*g*(h - f1)
        f3 = x - (t - r + r * Sin(a))
        fFinal = (f1 + f3 * Tan(a) - (g  / (2 * ((((C * f2) ^
 (1 / 2)) + f2 ^ (1 / 2)) / (m + 0.04593)) ^ 2) * (Cos(a)) ^ 2)) * f3 ^ 2)
     tWithinTolerance = (Abs(y - fFinal) < tTolerance)
        a = a + 0.01
    Wend
    Calculateangle = a ' note how this sets a return value for the function
End Function

Я оставил округление (что является проблемой представления) коду, который вызывает эту функцию - таким образом вы можете отобразить ответ с любым уровнем детализации, который вы хотите!

(извините, если я исказил какие-либо расчеты по пути - но вы поняли концепцию!)

Ответ 2 · user6698332

Для автора и тех, кто хочет разобраться с его пасьянсом. Надеюсь ничего не перепутал в скобках и упрощениях.

Do

    vCosA = Cos(a)
    vCosADR = d + r * (1 - vCosA) ' d + r - r * vCosA '
    vCosMGHADR = m * (2 * g * (h - vCosADR))
    vSinAXTR = (x - (t - r * (1 - Sin(a)))) ' - r + r * Sin(a)

   '((C * vCosMGHADR) + vCosMGHADR) == ((C + 1) * vCosMGHADR)

    If (y = _
            (vCosADR + vSinAXTR * Tan(a) - _
                (g / _
                    (2 * _
                        ( _
                            ( _
                                ((C + 1) * vCosMGHADR) / _
                                (m + 0.04593) _
                            ) ^ 2 _
                        ) * (vCosA ^ 2) _
                    ) _
                ) * vSinAXTR ^ 2 _
            )) Then Exit Do          ' *** EXIT DO ***

    a = a + 0.01

Loop

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы