Помогите найти ошибку в программе VBA: вычисление функции, график

Не факт. Но может. Я об этом выше и писал, там прямо в руководстве по ВБА русским по белому написано “не рекомендуется”. :smile:

Там у меня ещё вопросы к вычислению формулы касательной к графику есть.

UPD. В данном случае, скорее всего, и правда отработает неверно. Нужен другой цикл, не for

А Fun примерно так переделать, рекуррентно навряд-ли получится из-за синуса:

Function Fun(x As Double) As Double
Dim s As Double, i As Long, s1 As Double, s2 As Double
s = 0
s1 = 1
s2 =  -1
For i = 1 To 16
 s1 = s1 + 0.2
 s2 = -s2 * 2 * 2
 s = s + sin(x ^ s1) / s2
Next i
Fun = s
End Function

Я так перелопатил:

Function Fun(x As Double) As Double
Dim s As Double, i As Long
s = 0
For i = 1 To 16
    s = s + ((-1) ^ (i + 1)) * (Sin(x ^ (1 + 0.2 * i)) / (2 ^ (2 * i)))
Next i
Fun = s
End Function

график оказалось не загрузился. там немного он внизу, и его почти не видно

Я вчера Ваш код засунул в эксель - не знаю, где там внизу график, у меня он по центру листа сформировался

код работает? значит проблема в моем компьютере

скажите пожалуйста, а можно ли округлить синус? просто какую я бы не вводил функцию из преведенных вами, Excel ругается на функцию.

Я так понял, что дело в диапазоне. Но судя по вашим словам лучше не использовать String

Скажите пожалуйста, что на этот раз не так
Public Sub zadanie2()
Dim a As Double, b As Double, h As Double, x0 As Double, namesh As String
namesh = “Лист2”
Worksheets(1).Select
a = -1: b = 1: h = 0.05: x0 = 0.2
Call Graphics(a, b, h, x0)
End Sub
Function Fun(x As Double) As Double
Dim s As Double, i As Long, s1 As Single, s2 As Single, k As String
s = 0
For i = 1 To 15
s1 = 1 + 0.2 * i
s2 = 2 * i
k = k + (Sin(x ^ s1) / 2 ^ s2) - (Sin(x ^ s1 + 0.2) / 2 ^ (s2 + 0.2))
s = s + k
Next i
Fun = s
End Function

Function FunDiv(x As Double) As Double
Dim d As Double
d = 0.001
FunDiv = (Fun(x + d) - Fun(x)) / d
End Function
Function FunTang(x As Double, x0 As Double) As Double
FunTang = Fun(x0) + FunDiv(x0) * (x - x0)
End Function

Sub Graphics(a As Double, b As Double, h As Double, x0 As Double, x As Double)
Dim x As String, n As Long
n = 1
Cells(n, 1) = “X”
Cells(n, 2) = “Функция”
Cells(n, 3) = “Касательная”
For x = a To b Step h
n = n + 1
Cells(n, 1) = x
Cells(n, 2) = Fun(x)
Cells(n, 3) = FunTang(x, x0)
Next x
Range(“A1:C63”).Select
Charts.Add
ActiveChart.ChartType = xlXYScatterLinesNoMarkers
ActiveChart.SetSourceData Source:=Sheets(“Лист2”).Range(“A1:C63”), PlotBy:= _
xlColumns
ActiveChart.Location Where:=xlLocationAsObject, Name:=“Лист2”
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = “График функции и качательной”
.Axes(xlCategory, xlPrimary).HasTitle = False
.Axes(xlValue, xlPrimary).HasTitle = False
End With
End Sub

Вот собственно тот образец, который нам скинула преподавательница. Кроме этого кода она вообще ничего не скинула

Public Sub zadanie2()
Dim a As Double, b As Double, h As Double, x0 As Double, namesh As String
namesh = “Лист2”
Worksheets(namesh).Select
a = 0: b = 3.1415: h = 0.05: x0 = 0.2
Call Graphics(a, b, h, x0)
End Sub
Function Fun(x As Double) As Double
Dim s, s1, s2 As Double, xn As Double, i As Long, z As Long
xn = x: s1 = 0: s2 = 1: s = 0: z = 1:
For i = 1 To 30
s1 = s1 + z * Cos(i * xn)
s2 = s2 + z * Sin(i * xn)
s = s + s1 / s2
z = -z
Next i
Fun = s
End Function

Function FunDiv(x As Double) As Double
Dim d As Double
d = 0.000001
FunDiv = (Fun(x + d) - Fun(x)) / d
End Function
Function FunTang(x As Double, x0 As Double) As Double
FunTang = Fun(x0) + FunDiv(x0) * (x - x0)
End Function

Sub Graphics(a As Double, b As Double, h As Double, x0 As Double)
Dim x As Double, n As Long
n = 1
Cells(n, 1) = “X”
Cells(n, 2) = “ФУНКЦИЯ”
Cells(n, 3) = “КАСАТЕЛЬНАЯ”
For x = a To b Step h
n = n + 1
Cells(n, 1) = x
Cells(n, 2) = Fun(x)
Cells(n, 3) = FunTang(x, x0)
Next x
Range(“A1:C63”).Select
Charts.Add 'Добавить диаграмму
ActiveChart.ChartType = xlXYScatterLinesNoMarkers
’ задает область, где находятся данные для построения графика
ActiveChart.SetSourceData Source:=Sheets(“Лист2”).Range(“A1:C63”), PlotBy:= _
xlColumns
’ где строить диаграмму
ActiveChart.Location Where:=xlLocationAsObject, Name:=“Лист2”
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = “График функции и касательной”
.Axes(xlCategory, xlPrimary).HasTitle = False
.Axes(xlValue, xlPrimary).HasTitle = False
End With
End Sub

Попробуйте так. Поскольку степень там чётная (1.2 = 12/10 = корень 10 степени из x в 12 степени) - знаком перед иксом можно пренебречь, то есть брать модуль числа.

Ещё у Вас во второй части формулы ошибка, должно быть так:
Sin(x ^( s1 + 0.2))

Вообще можно обойтись без k, s1, s2 - формулы приведены в комментариях выше.

Бесполезно. Все формулы, которые даны выше не помогают

Надо так:

Public Sub zadanie2()
Dim a As Double, b As Double, h As Double, x0 As Double, namesh As String
namesh = "Лист2"
Worksheets("Лист2").Select
a = -1: b = 1: h = 0.05: x0 = 0.2
Call Graphics(a, b, h, x0)
End Sub
Function Fun(x As Double) As Double
Dim s As Double, i As Long
s = 0
For i = 1 To 16
    s = s + ((-1) ^ (i + 1)) * (Sin(Abs(x) ^ (1 + 0.2 * i)) / (2 ^ (2 * i)))
Next i
Fun = s
End Function


Function FunDiv(x As Double) As Double
Dim d As Double
d = 0.000001
FunDiv = (Fun(x + d) - Fun(x)) / d
End Function
Function FunTang(x As Double, x0 As Double) As Double
FunTang = Fun(x0) + FunDiv(x0) * (x - x0)
End Function

Sub Graphics(a As Double, b As Double, h As Double, x0 As Double)
Dim x As Double, n As Long
n = 1
Cells(n, 1) = "X"
Cells(n, 2) = "ФУНКЦИЯ"
Cells(n, 3) = "КАСАТЕЛЬНАЯ"
For x = a To b Step h
n = n + 1
Cells(n, 1) = x
Cells(n, 2) = Fun(x)
Cells(n, 3) = FunTang(x, x0)
Next x
Range("A1:C63").Select
    Charts.Add
    ActiveChart.ChartType = xlXYScatterLinesNoMarkers
    ActiveChart.SetSourceData Source:=Sheets("Лист2").Range("A1:C63"), PlotBy:= _
        xlColumns
    ActiveChart.Location Where:=xlLocationAsObject, Name:="Лист2"
    With ActiveChart
        .HasTitle = True
        .ChartTitle.Characters.Text = "График функции  и касательной"
        .Axes(xlCategory, xlPrimary).HasTitle = False
        .Axes(xlValue, xlPrimary).HasTitle = False
    End With
End Sub

Спасибо большое. Теперь работает без проблем) Я Вам сильно благодарен

Рано ещё, у Вас касательная неверно вычисляется. Потому что в примере преподавателя исходная функция Котангенс, её производная Тангенс, он и вычисляется.

У Вас другая исходная функция - Синус. Производная его - Косинус.

Вот это надо переписать на правильную функцию:

Function FunDiv(x As Double) As Double
Dim d As Double
d = 0.000001
FunDiv = (Fun(x + d) - Fun(x)) / d
End Function
Function FunTang(x As Double, x0 As Double) As Double
FunTang = Fun(x0) + FunDiv(x0) * (x - x0)
End Function

и на этом все?

В общем да. Функция FunDiv должна вычислять производную, а та, которая сейчас называется FunTang - это как раз формула касательной в точке.

А что тут менять надо? Тут вроде как правильно, разве нет?

Вы правы, это я сглупил. Тут используется дифференциальный метод вычисления производной, про который я за давностью лет подзабыл :slight_smile:

ага, если скобки так расставить - корень 10 степени из (x в 12 степени)
а почему не - (корень 10 степени из x) в 12 степени ?

Просто отрицательные x для дробных показателей степеней вне области определения без всяких эквилибристик с четностью. И тогда либо неверная запись и там модуль должен быть, либо функция определена только для неотрицательных иксов