С Новым годом! Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.52/60: Рейтинг темы: голосов - 60, средняя оценка - 4.52
0 / 0 / 0
Регистрация: 21.09.2011
Сообщений: 21
Word

Построить график функции y(x), которую вводит пользователь

18.01.2013, 17:54. Показов 11538. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день! Нужно написать программу, которая работает по принципу
1) пользователь вводит функцию y(x)
2) пользователь указывает пределы по x и по y, в рамках которых будет построен график
3) программа строит график функции

Примечание: функция непрерывная!

Скрипт нужно написать для VBA Word
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.01.2013, 17:54
Ответы с готовыми решениями:

Построить график зависимости (точечный график)
Здравствуйте, нужно построить график зависимости в VBA :) Грубо говоря график по точкам...

Построить график y=Nx^3, где N будет задавать пользователь
Сделать программу для постройке графика y=Nx^3, где N будет задавать пользователь.

Как построить график в VBA по данным, которые находятся в list box
Добрый вечер! Необходимо построить график, который будет отображаться в Excel, по данным из...

24
6082 / 1327 / 195
Регистрация: 12.12.2012
Сообщений: 1,023
19.01.2013, 18:26
Здравствуйте, k.00741.
Интересная задача. Допустим, у нас есть форма frmPlotter, в которой есть три текстовых поля: tbFormula, tbA и tbB, а также кнопка cbOk. В поле tbFormula заносится строка, определяющая функцию y(x), а в поля tbA и tbB заносятся границы отрезка [a, b] устанавливающего пределы функции по координате x (пределы функции по координате y для простоты не рассматриваем, так как их можно свести к пределам по координате x). Кнопка cbOk запускает процесс построения графика функции.

Сначала пользователь вызывает форму. Для этого можно написать процедуру вида:
Visual Basic
1
2
3
Sub CallPlotter()
    frmPlotter.Show
End Sub
Затем пользователь вводит данные в соответствующие поля, и после нажатия кнопки cbOk программа должна построить график функции. Из всех офисных программ графики удобнее всего строить в программе Excel, поэтому я открыл эту программу и записал в ней две процедуры: одну - вручную, а другую макрорекордером:

1) Процедура табулирования функции, т.е. представления ее в виде таблицы:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Sub TabulateFunction()
    Dim h As Double
    Dim i As Long
    Const functionstring = "X^2 - 5*X + 7"
    Const a = 2
    Const b = 5
    'Функция табулируется на 10 отрезков.
    Const n = 10
    'Заголовки.
    Evaluate("a1:b1") = Evaluate("{""X"",""Y""}")
    'Определяем шаг табуляции.
    h = (b - a) / n
    'Заполняем данные по X (в столбце a) и Y (в столбце b).
    For i = 0 To n
        Evaluate("a" & (i + 2)) = a + i * h
        Evaluate("b" & (i + 2)) = Evaluate(Replace(UCase(functionstring), "X", "a" & (i + 2)))
    Next i
End Sub
2) Процедура построения графика функции по табличным данным:
Visual Basic
1
2
3
4
5
6
7
Sub Macro1()
    ActiveSheet.Shapes.AddChart.Select
    ActiveChart.SetSourceData Source:=.Range("Sheet1!$B$1:$B$12")
    ActiveChart.ChartType = xlLine
    ActiveChart.SeriesCollection(1).XValues = "=Sheet1!$A$2:$A$12"
    ActiveChart.ChartArea.Copy
End Sub
Далее в программе Word был еще записан макрос вставки графика из буфера обмена:
Visual Basic
1
2
3
4
Sub Macro1()
    Selection.TypeParagraph
    Selection.PasteAndFormat (wdChartLinked)
End Sub
Теперь нужно было, скопировав код из Excel, адпатировать его к работе в Word и собрать из него, а также из одного вордовского макроса нечто целое - процедуру, которая бы объединяла вышеприведенный код и, кроме того, принимала бы параметры из полей формы frmPlotter. С этой задачей удалось справиться следующим образом:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
'Процедура табуляции функции, заданной строкой functionstring,
'на отрезке от a до b.
Sub TabulateFunction(ByVal eApp As Object, ByVal functionstring As String, ByVal a As Double, ByVal b As Double)
    Dim h As Double
    Dim i As Long
    'Функция табулируется на 10 отрезков.
    Const n = 10
    With eApp
        'Заголовки.
        .Evaluate("a1:b1") = .Evaluate("{""X"",""Y""}")
        'Определяем шаг табуляции.
        h = (b - a) / n
        'Заполняем данные по X (в столбце a) и Y (в столбце b).
        For i = 0 To n
            .Evaluate("a" & (i + 2)) = a + i * h
            .Evaluate("b" & (i + 2)) = .Evaluate(Replace(UCase(functionstring), "X", "a" & (i + 2)))
        Next i
    End With
End Sub
 
'Записанная макрорекордером и немного модифицированная процедура
'построения графика на основе диапазона с данными по координатам X и Y функции.
'Предполагается, что функция табулируется на 10 отрезков (т.е.
'диапазон данных занимает 2 столбца и 12 строк, включая заголовки).
Sub ExcelMacro1(ByVal eApp As Object)
    With eApp
        .ActiveSheet.Shapes.AddChart.Select
        .ActiveChart.SetSourceData Source:=.Range("Лист1!$B$1:$B$12")
        .ActiveChart.ChartType = xlLine
        .ActiveChart.SeriesCollection(1).XValues = "=Лист1!$A$2:$A$12"
        'Построенный график копируем в буфер обмена.
        .ActiveChart.ChartArea.Copy
    End With
End Sub
 
'Записанная макрорекордером и немного модифицированная процедура вставки графика.
Sub WordMacro1()
    Selection.TypeParagraph
    Selection.PasteAndFormat wdChartPicture
End Sub
 
'Процедура создания графика в Word на основе строки
'functionstring, задающей функцию, и данных о границах a и b.
Sub MakeChartInWord(ByVal functionstring As String, ByVal a As Double, ByVal b As Double)
    Dim eApp As Object
    Dim eWbk As Object
    'Данные для тестирования.
    'functionstring = "X^2 - 5*X + 7"
    'a = 2
    'b = 5
    On Error GoTo ErrHandler
    Set eApp = CreateObject("Excel.Application")
    Set eWbk = eApp.Workbooks.Add
    TabulateFunction eApp, functionstring, a, b
    ExcelMacro1 eApp
    WordMacro1
    eWbk.Close False
    Set eWbk = Nothing
    Set eApp = Nothing
    On Error GoTo 0
    Exit Sub
    
ErrHandler:
    eWbk.Close False
    Set eWbk = Nothing
    Set eApp = Nothing
    Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End Sub
Тогда получается, что событие нажатия кнопки cbOk в форме можно обработать следующим образом:
Visual Basic
1
2
3
4
5
6
7
8
9
10
Private Sub cbOk_Click()
    Dim functionstring As String
    Dim a As Double
    Dim b As Double
    functionstring = tbFormula.Text
    a = CDbl(Val(tbA.Text))
    b = CDbl(Val(tbB.Text))
    MakeChartInWord functionstring, a, b
    Unload Me
End Sub
Остается только написать код, который проверяет на корректность вводимые пользователем данные. Корректными являются, например, следующие данные: для поля tbFormula - строка наподобие "X^2 - 5*X + 7", для полей tbA и tbB - любые строки, которые можно преобразовать в числа a и b, такие, что a < b, например "2" и "5". Написание кода для контроля корректности вводимых данных оставляю топикстартеру в качестве домашнего задания .

С уважением,
Aksima
1
0 / 0 / 0
Регистрация: 21.09.2011
Сообщений: 21
19.01.2013, 22:44  [ТС]
здравствуйте! спасибо большое за код! вы не могли бы представить это в виде готовой программы?
0
6082 / 1327 / 195
Регистрация: 12.12.2012
Сообщений: 1,023
20.01.2013, 19:11
k.00741, прилагаю файл Word с макросами, код которых был приведен выше, и формой, вызываемой по нажатию на кнопку (кнопка находится прямо на странице).

С уважением,
Aksima
Вложения
Тип файла: rar PlottingGraphsInWordExample.rar (21.7 Кб, 115 просмотров)
2
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38166 / 21101 / 4307
Регистрация: 12.02.2012
Сообщений: 34,690
Записей в блоге: 14
20.01.2013, 22:21
Aksima, а если функция, которую задает пользователь, содержит, например, exp(x)? Твоя программа обработает ее нормально?
1
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
20.01.2013, 22:54
Catstail, ты всех тиранишь этим exp(x)

Программа должна уметь распознавать функции, записанные в TextBox
1
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38166 / 21101 / 4307
Регистрация: 12.02.2012
Сообщений: 34,690
Записей в блоге: 14
20.01.2013, 22:57
Цитата Сообщение от Казанский Посмотреть сообщение
Catstail, ты всех тиранишь этим exp(x)
- я указываю на ошибку. Этого делать не нужно? Не буду.
1
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
20.01.2013, 23:02
Нужно. Но поскольку есть и способы обхода этой ошибки, указывай и их.
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38166 / 21101 / 4307
Регистрация: 12.02.2012
Сообщений: 34,690
Записей в блоге: 14
20.01.2013, 23:26
Указываю. Текст формулы нужно разбить на лексемы, и при вычислении заменять значением аргумента только лексемы x. А для разбиения на лексемы нужно сканировать текст символ за символом и при встрече разделителя [( ) + - * / ,] сбрасывать накопленную строку в массив.
2
6082 / 1327 / 195
Регистрация: 12.12.2012
Сообщений: 1,023
21.01.2013, 11:26
Лучший ответ Сообщение было отмечено как решение

Решение

Catstail, спасибо вам большое за то, что помогаете искать ошибки в программе и тем самым принимаете участие в ее улучшении .
Цитата Сообщение от Catstail Посмотреть сообщение
если функция, которую задает пользователь, содержит, например, exp(x)? Твоя программа обработает ее нормально?
Действительно, тут моя программа не сработает как надо (график построится, но с нулевыми значениями по оси y).
Цитата Сообщение от Catstail Посмотреть сообщение
Текст формулы нужно разбить на лексемы, и при вычислении заменять значением аргумента только лексемы x.
Только вот разбивать строку на лексемы для последующего анализа мне почему-то лень . Вместо этого решил в процедуре табуляции функции использовать вместо стандартной функции замены замену с помощью регулярного выражения:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Sub TabulateFunction(ByVal eApp As Object, ByVal functionstring As String, ByVal a As Double, ByVal b As Double)
   Dim rgX As Object
   Dim h As Double
   Dim i As Long
   'Функция табулируется на 10 отрезков.
   Const n = 10
   'Настраиваем обработку регулярного выражения.
   Set rgX = CreateObject("VBScript.RegExp")
   With rgX
      .Global = True
      .IgnoreCase = True
      .Pattern = "([ ()+-/*^])x([ ()+-/*^])|^x([ ()+-/*^])|([ ()+-/*^])x$"
   End With
   With eApp
      'Заголовки.
      .Evaluate("a1:b1") = .Evaluate("{""X"",""Y""}")
      'Определяем шаг табуляции.
      h = (b - a) / n
      'Заполняем данные по X (в столбце a) и Y (в столбце b).
      For i = 0 To n
         .Evaluate("a" & (i + 2)) = a + i * h
         .Evaluate("b" & (i + 2)) = .Evaluate(rgX.Replace(functionstring, "$1$4" & "a" & (i + 2) & "$2$3"))
      Next i
   End With
End Sub
Как вам такое решение?

С уважением,
Aksima
1
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38166 / 21101 / 4307
Регистрация: 12.02.2012
Сообщений: 34,690
Записей в блоге: 14
21.01.2013, 13:42
Хорошее решение... Но, не обижайся, тоже ограниченное в возможностях. Если я захочу строить графики по формулам, содержащим произвольные именованные константы, то опять возникнет та же проблема... Если формулы содержат только числа, стандартные функции и переменную x, то решение хорошее.
0
6082 / 1327 / 195
Регистрация: 12.12.2012
Сообщений: 1,023
22.01.2013, 13:02
Цитата Сообщение от Catstail Посмотреть сообщение
...хочу строить графики по формулам, содержащим произвольные именованные константы
Мне пришлось изрядно попотеть над этой проблемой . Зато теперь построитель графиков полностью поддерживает именованные константы, в том числе для определения границ a и b, и свободен от некоторых других выявленных мной недостатков:

1) При формуле Y(x) = x, замена x на соответствующее значение на производилась.
2) Если часть области определения или вся область определения лежит в отрицательной плоскости, то при замене в выражениях типа Y(x) = -x появлялся двойной минус.

Надеюсь, теперь продукт моего труда удовлетворит даже самого взыскательного пользователя . Выкладываю его в приложении.

С уважением,
Aksima
Миниатюры
Построить график функции y(x), которую вводит пользователь   Построить график функции y(x), которую вводит пользователь  
Вложения
Тип файла: rar PlottingGraphsInWord_1.2.0.rar (32.2 Кб, 54 просмотров)
2
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
22.01.2013, 15:09
Цитата Сообщение от Aksima Посмотреть сообщение
Надеюсь, теперь продукт моего труда удовлетворит даже самого взыскательного пользователя
Это очень, очень классный продукт!
Однако, у меня он не заработал сразу. Причина - русский Офис и, соответственно, имя листа "Лист1" вместо "Sheet1".
Следует избежать обращения к листу по имени:
Visual Basic
1
2
3
4
5
'        .ActiveChart.SetSourceData Source:=.Range("Sheet1!$B$1:$B$" & ntabs + 2)
        .ActiveChart.SetSourceData Source:=.activesheet.Range("B1:B" & ntabs + 2)
        .ActiveChart.ChartType = xlLine
'        .ActiveChart.SeriesCollection(1).XValues = "=Sheet1!$A$2:$A$" & ntabs + 2
        .ActiveChart.SeriesCollection(1).XValues = .activesheet.Range("A1:A" & ntabs + 2)
2
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38166 / 21101 / 4307
Регистрация: 12.02.2012
Сообщений: 34,690
Записей в блоге: 14
22.01.2013, 15:45
Любопытно сравнить объем кода с таковым из моей давней поделки:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Sub DrawGraph()
 
Dim Lex(1 To 200) As String
    frmAskFormula.Tag = ""
    frmAskFormula.Show
    If frmAskFormula.Tag = "" Then Exit Sub
    Formula$ = frmAskFormula.TextBox1.Text
    Parse Formula$, Lex()
    For i% = 1 To 200
        If Lex(i%) = "" Then Exit For
        If UCase$(Lex(i%)) = "X" Then Lex(i%) = "AL1"
    Next i%
    Formula$ = "="
    For i% = 1 To 200
        If Lex(i%) = "" Then Exit For
        Formula$ = Formula$ + Lex$(i%)
    Next i%
    Sheets(1).Range("AM1").Formula = UCase$(Formula$)
    xMin# = Val(frmAskFormula.TextBox2.Text)
    xMax# = Val(frmAskFormula.TextBox3.Text)
    dx# = (xMax# - xMin#) / 100
    x# = xMin#
    For i% = 1 To 100
        Sheets(1).Range("AL1").Value = x#
        Sheets(1).Range("AO" + CStr(i%)).Value = x#
        Sheets(1).Range("AP" + CStr(i%)).Value = Sheets(1).Range("AM1").Value
        x# = x# + dx#
    Next i%
End Sub
 
Sub Parse(Frm As String, Lex() As String)
    For i% = 1 To UBound(Lex, 1)
        Lex(i%) = ""
    Next
    p% = 0
    Tmp$ = ""
    For i% = 1 To Len(Frm)
        s$ = Mid$(Frm, i%, 1)
        Select Case (s$)
               Case "+", "-", "*", "/", "^", "(", ")"
                    If Tmp$ <> "" Then
                       p% = p% + 1
                       Lex(p%) = Tmp$
                    End If
                    p% = p% + 1
                    Lex(p%) = s$
                    Tmp$ = ""
               Case " "
               Case Else
                    Tmp$ = Tmp$ + s$
          End Select
     Next i%
     If Tmp$ <> "" Then
        p% = p% + 1
        Lex(p%) = Tmp$
     End If
End Sub
 
Sub Clear()
    Columns("AM:AP").Select
    Selection.ClearContents
    Range("A1").Select
End Sub
Правда, это не в Word-е, а в Excel-е. Но оказывается, что "ручной парсинг" проще регулярных выражений...
0
6082 / 1327 / 195
Регистрация: 12.12.2012
Сообщений: 1,023
22.01.2013, 16:04
Казанский, а ведь и правда, надо было подумать о возможных проблемах из-за различий в языковой версии.
Спасибо за подсказку .

В приложении версия с исправлением данной ошибки.

Цитата Сообщение от Catstail Посмотреть сообщение
Но оказывается, что "ручной парсинг" проще регулярных выражений...
Вы очень хорошо оптимизировали ваш код и он, действительно, выглядит привлекательнее. Но по сложности, как мне кажется, и парсинг, и регулярные выражения - вещи примерно одного уровня.

С уважением,
Aksima
Вложения
Тип файла: rar PlottingGraphsInWord_1.2.1.rar (41.4 Кб, 32 просмотров)
1
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38166 / 21101 / 4307
Регистрация: 12.02.2012
Сообщений: 34,690
Записей в блоге: 14
22.01.2013, 16:10
Цитата Сообщение от Aksima Посмотреть сообщение
Вы очень хорошо оптимизировали ваш код
- честное слово: писал с ходу!
1
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
22.01.2013, 16:12
Лучший ответ Сообщение было отмечено как решение

Решение

Aksima,
... и еще. Я решил проверить - как программа будет обращаться с формулой, в которой аргумент встречается несколько раз.
x+sin(x)+cos(x) - сработало отлично, а вот x+x+x - нет.
(Я не написал это сразу, чтобы Вы не кинулись тут же исправлять код )
Хочу сказать, что коль скоро Вы используете метод Evaluate из Excel, разбирать формулы на части просто не нужно - Вы фактически приближаетесь к тому, чтобы продублировать Экселевский парсер выражений.
Можно создать в книге Excel имя "x", присваивать ему значения и применять Evaluate к исходной формуле:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'Процедура табуляции функции, заданной строкой functionstring,
'на отрезке от a до b.
Sub TabulateFunction(ByVal eApp As Object, ByVal functionstring As String, ByVal a As Double, ByVal b As Double)
   Dim rgX As Object
   Dim h As Double
   Dim i As Long, j As Long
   Dim s As String, pn As String
   Dim nx As Object 'excel.name
   With eApp.activesheet
      'Заголовки.
      .Range("a1:b1") = Split("X Y(x)")
      'Определяем шаг табуляции.
      h = (b - a) / ntabs
      'Заполняем данные по X (в столбце a) и Y (в столбце b).
      For i = 0 To ntabs
         .Names.Add "x", "=" & Str(a + i * h) 'существующее имя заменяется новым
         .Range("a" & (i + 2)) = a + i * h 'или .Evaluate("x")
         .Range("b" & (i + 2)) = .Evaluate(functionstring)
      Next i
   End With
End Sub
А как же константы?! Очень просто - таким же образом создать на листе имена с именами констант и соответствующими значениями.
Есть, правда, один нюанс: в Excel нельзя создать имена "c" и "r". Это зарезервированные имена, которые ссылаются на столбец и строку активной ячейки. Попробуйте ввести r в поле адреса (левой поле строки формул).
3
6082 / 1327 / 195
Регистрация: 12.12.2012
Сообщений: 1,023
22.01.2013, 16:25
Цитата Сообщение от Catstail Посмотреть сообщение
честное слово: писал с ходу!
Тогда остается лишь отдать должное вашему опыту и навыку программирования. Думаю, если я буду стараться, то со временем тоже научусь писать более красивые и компактные программы .

Добавлено через 6 минут
Цитата Сообщение от Казанский Посмотреть сообщение
Можно создать в книге Excel имя "x", присваивать ему значения и применять Evaluate к исходной формуле...
...А как же константы?! Очень просто - таким же образом создать на листе имена с именами констант и соответствующими значениями.
Все гениальное просто... Спасибо вам большое!
0
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
22.01.2013, 16:41
Можно еще углубиться в методы Excel VBA + формулы... и даже цикл не нужен
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'Процедура табуляции функции, заданной строкой functionstring,
'на отрезке от a до b.
Sub TabulateFunction(ByVal eApp As Object, ByVal functionstring As String, ByVal a As Double, ByVal b As Double)
   Dim rgX As Object
   Dim h As Double
   Dim i As Long, j As Long
   Dim s As String, pn As String
   Dim nx As Object 'excel.name
   With eApp.activesheet
      'Заголовки.
      .Range("a1:b1") = Split("X Y(x)")
      .Names.Add "x", "=RC[-1]" 'имя, которое ссылается на ячейку слева
      With .Range("a2").Resize(ntabs+1)
        .Cells(1) = a
        .Cells(ntabs+1) = b
        'заполняем диапазон Х инструментом "прогрессия"
        .DataSeries , -4132, , , , True '-4132=xlLinear, True - тренд
        'заполняем диапазон Y формулой
        .Offset(, 1).Formula = "=" & functionstring
      End With
   End With
End Sub
2
6082 / 1327 / 195
Регистрация: 12.12.2012
Сообщений: 1,023
23.01.2013, 17:02
Подведу некоторые итоги по данной теме:
  • Задачу построения графика функции в таких приложениях Microsoft Office, как Word или PowerPoint, можно свести к задаче построения графика функции в Excel.
  • Задача построения графика функции в Excel состоит из двух частей:
    1. Табулирование функции.
    2. Создание графика функции на основе таблицы значений функции.
  • В ходе обсуждения было установлено, что табулирование функции (т.е. составление таблицы значений функции при изменении аргумента от некоторого начального значения до некоторого конечного значения с определённым шагом) можно выполнить как минимум тремя способами:
    1. Провести анализ выражения с разбиением его на лексемы (парсинг). Пример такого анализа приводится в посте №14 данной темы.
    2. Заменить переменные и константы выражения их численными значениями, используя регулярные выражения, а затем использовать встроенный в Excel механизм расчета формул.
      Visual Basic
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      
      'Процедура получения данных об используемых константах из свойств документа.
      Sub DataFromDocProps(ByRef cnt As Long, ByRef propNames() As String, ByRef propValues() As Double)
          Dim i As Long
          With ThisDocument.CustomDocumentProperties
              cnt = .Count
              ReDim propNames(cnt - 1) As String
              ReDim propValues(cnt - 1) As Double
              For i = 1 To cnt
                  propNames(i - 1) = .Item(i).Name
                  propValues(i - 1) = .Item(i).Value
              Next i
          End With
      End Sub
      'Процедура замены в выражении sExpr лексемы с именем lexName на ее фактическое численное значение lexValue.
      Function Zamena(ByVal sExpr As String, ByVal lexName As String, ByVal lexValue As Double) As String
          With CreateObject("VBScript.RegExp")
              .Global = True
              .IgnoreCase = True
              .Pattern = "([ ()+-/*^])" & lexName & "([ ()+-/*^])|^" & lexName & "([ ()+-/*^])|([ ()+-/*^])" & lexName & "$|^" & lexName & "$"
              sExpr = .Replace(.Replace(sExpr, "$1$4" & lexValue & "$2$3"), "$1$4" & lexValue & "$2$3")
          End With
          Zamena = Replace(Replace(Replace(Replace(Replace(sExpr, ",", "."), "--", "+"), "+-", "-"), "*-", "*(-1)*"), "/-", "*(-1)/")
      End Function
      'Процедура табуляции функции.
      Sub TabulateFunction(ByVal eApp As Object, ByVal sFunc As String, ByVal sBoundA As String, ByVal sBoundB As String, ByVal nTabs As Long)
          Dim eCell As Object
          Dim ns() As String
          Dim vs() As Double
          Dim i As Long, n As Long
          Dim x As Double, a As Double, b As Double, h As Double
          DataFromDocProps n, ns(), vs()
          For i = 0 To n - 1
              sFunc = Zamena(sFunc, ns(i), vs(i))
              sBoundA = Zamena(sBoundA, ns(i), vs(i))
              sBoundB = Zamena(sBoundB, ns(i), vs(i))
          Next i
          With eApp
              a = CDbl(.Evaluate(sBoundA))
              b = CDbl(.Evaluate(sBoundB))
              h = (b - a) / nTabs
              .ActiveSheet.Range("A1:B1") = Array("X", "Y(x)")
              For i = 0 To nTabs
                  x = a + i * h
                  If (Abs(x - Round(x, 3)) < 0.000001) Then x = Round(x, 3)
                  .ActiveSheet.Range("A" & i + 2) = x
                  .ActiveSheet.Range("B" & i + 2) = .Evaluate(Zamena(sFunc, "x", x))
              Next i
          End With
      End Sub
      Как вы видите, после оптимизации объем и сложность кода с использованием регулярных выражений уже меньше, чем у оптимизированного кода с ручным парсингом. Обратите особое внимание на функцию Zamena - вместе с функцией Evaluate именно она выполняет основную работу в этом коде. Если необходимо вычислить значение выражения sExpr через x без констант и в определенной точке x0 - то равных этой парочке нету. Достаточно написать всего одну строку:
      Visual Basic
      1
      
      Evaluate(Zamena(sExpr, "x", x0))
      Например, в Excel в окне Immediate ?Evaluate(Zamena("x+x+x", "x", -3)) дает -9. ?Evaluate(Zamena("x+x*x", "x", -3)) дает 6. Вы можете поэксперементировать сами.
    3. Поставить в соответствие переменной x и константам некоторые именованные диапазоны на листе, а затем использовать встроенный в Excel механизм расчета формул.
      Visual Basic
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      
      'Процедура получения данных об используемых константах из свойств документа.
      Sub DataFromDocProps(ByRef cnt As Long, ByRef propNames() As String, ByRef propValues() As Double)
          Dim i As Long
          With ThisDocument.CustomDocumentProperties
              cnt = .Count
              ReDim propNames(cnt - 1) As String
              ReDim propValues(cnt - 1) As Double
              For i = 1 To cnt
                  propNames(i - 1) = .Item(i).Name
                  propValues(i - 1) = .Item(i).Value
              Next i
          End With
      End Sub
      'Процедура табуляции функции.
      Sub TabulateFunction(ByVal eApp As Object, ByVal sFunc As String, ByVal sBoundA As String, ByVal sBoundB As String, ByVal nTabs As Long)
          Dim ns() As String
          Dim vs() As Double
          Dim i As Long, n As Long
          Dim x As Double, a As Double, b As Double, h As Double
          DataFromDocProps n, ns(), vs()
          With eApp.ActiveSheet
              .Names.Add "x", "=RC[-1]"
              For i = 1 To n
                  .Range("D" & i) = vs(i - 1)
                  .Names.Add ns(i - 1), "=R" & i & "C4"
              Next i
              .Range("A1:B1") = Array("X", "Y(x)")
              .Range("E1").Formula = "=" & sBoundA
              .Range("E2").Formula = "=" & sBoundB
              a = CDbl(.Range("E1"))
              b = CDbl(.Range("E2"))
              With .Range("A2").Resize(nTabs + 1)
                  .Cells(1) = a
                  .Cells(nTabs + 1) = b
                  .DataSeries , -4132, , , , True
                  .Offset(, 1).Formula = "=" & sFunc
              End With
          End With
      End Sub
      Третий способ дает наименьший объем кода и сложность, и, следовательно, для данной конкретной задачи является наиболее оптимальным.
  • Для создания графика функции на основе построенной таблицы значений функции можно использовать макрорекордер. Затем с помощью буфера обмена полученный график можно перенести в другое приложение Microsoft Office.
  • Документ, выполняющий все необходимые действия и основанный на третьем варианте табуляции (от Казанского), вы можете найти в приложении.
Вложения
Тип файла: rar PlottingGraphsInWord_1.3.0.rar (35.3 Кб, 57 просмотров)
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.01.2013, 17:02
Помогаю со студенческими работами здесь

Построить график функции
Помогите пожалуйста!!))) Нужно составить программу в среде Turbo Basic.И построить график....

Построить график функции SIN
Построить график функции SIN на форме

Построить график функции
Помогите построить график функции z=f(y) (0&lt;=x&lt;=4П) y=5 sin 0.1x - cos 5x z=11 cos 0.2x - 5 sin...

Построить график функции COS на объекте PICTURE
24. Построить график функции COS на объекте PICTURE

построить график функции
построить график функции z=f(y) (0≤x≤4п) y=sin0.5+5sinx z=cos0.2x*5sin0.5x Добавлено через 1...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru