Урок 5

 

Тема: Решение уравнения, зависящего от параметра. Построение диаграммы

 

Цель урока

 

В уроке разрабатывается приложение, позволяющее находить корни уравнения в зависимости от параметра, а также строить диаграмму, демонстрирующую зависимость корня от параметра. Конструируя данное приложение вы научитесь:

 

1 Вводить формулы при помощи элемента управления RefEdit

2 Находить методом GoalSeek корни уравнения, зависящего от параметра

3 Устанавливать параметры метода GoalSeek

4 Создавать прогрессию на рабочем листе при помощи метода DataSeries

5 Программировать протаскивание маркера заполнения выделенного диапазона на рабочем листе при помощи метода AutoFill

6 Строить диаграммы

Теория

 

В этом разделе решается уравнение

 

х3 - х - b = 0

 

при различных величинах параметра b, изменяющихся от начального до конечного значения с указанным шагом. При каждом конкретном значении параметра корень уравнения находится методом GoalSeek. Для нахождения корней уравнения при различных значениях параметра, эти значения вводятся в диапазон ячеек рабочего листа, формулы левых частей уравнении - в другой диапазон, третий диапазон отводится под неизвестную. В диапазон с неизвестными вводятся начальные приближения корня, а потом последовательно перебирая соответствующие ячейки из этих трех диапазонов методом GoalSeek находятся соответствующие корни.

 

 

Практика

 

Для решения задачи нахождения корней уравнения, зависящего от параметра, и построения диаграммы зависимости корней от параметра с помощью редактора пользовательских форм создадим диалоговое окно нелинейное

уравнение с параметром (рис. У5.1).

 


Рис. У5.1. Диалоговое окно Нелинейное уравнение с параметром

 

О решаемом уравнении предполагается, что оно преобразовано к виду, когда только левая часть зависит от неизвестной и параметра. Правая же частьпостоянна. При вводе левой части уравнения в поле ввода элемента управления RefEdit вместо переменной х надо давать ссылку на ячейку в2, а вместо параметра А2. Кроме того, формула должна быть составлена по тем же правилам, по которым пишутся формулы рабочего листа. Например, для упомянутого выше уравнения в поле надо ввести:

 

=B2^3-B2-A2

 

либо эквивалентную формулу с абсолютными ссылками на ячейки.

 

Обсудим, как приведенная ниже программа решает перечисленные задачи и что происходит в программе

 

 UserForm Initialize

1.

Активизирует диалоговое окно.

 

 

2.

Назначает клавише <Esc> функцию кноп-

 

 

 

 

ки Отмена, а клавише <Enter> вычис-

 

 

 

 

лить.

Нажатие кнопки вычис

3.

При выполнении щелчка в соответст-

лить запускает на выпол-

 

 

вующей ячейке в поле элемента управле-

нение процедуру

 

 

ния RefEdit вводится абсолютная ссылка

CommandButton1 Click

 

 

на эту ячейку. При выделении ячейки

 

 

 

 

формулой и протаскивании ее маркера

 

 

 

 

заполнения вниз вдоль столбца для полу-

 

 

 

 

чения корректного результата нужна

 

 

 

 

абсолютная, а относительная ссылка.

 

 

 

 

 

 

С этой целью из строки с формулой,

присвоенной строковой переменной Формула,

 

 

 

 

 

 

удаляются все знаки $, тем самым

превращая все абсолютные ссылки в от- носительные.

 

 

4.

Удаляются с рабочего листа ранее введенные

 

 

 

 

данные и создаются заголовки полей отчета.

 

 

5.

Устанавливаются предельное число итераций

 

 

 

 

и относительная погрешность метода

 

 

 

 

GoalSeek.

 

 

 

6.

 

 

Методом DataSeries в диапазоне создается

арифметическая прогрессия изменения

 

 

 

 

значений параметра от начального до

 

 

 

 

конечного значения с указанным шагом.

 

 

7.

Вводится начальное приближение в диапазон.

 

 

8.

Вводится в диапазон левая часть уравнения

 

 

 

 

при различных значениях параметра.

 

 

9.

Последовательно для каждой ячейки,

 

 

 

 

имеющей формулу с левой частью урав-

 

 

 

 

нения, методом GoalSeek, находится корень

 

 

 

 

уравнения.

 

 

10.

Вызывается процедура ПостроениеГрафика

 

 

 

 

для построения графика (рис. У5.2).

Нажатие кнопки отмена

11.

Закрывает диалоговое окно.

запускает на выполнение

 

 

 

 

процедуру

 

 

 

 

ConimandButton2 Click

 

 

 

 

Процедура

12.

Строит график.

ПостроениеГрафика

 

 

 

 

 

Рис. У5.2. Отчет, выводимый на рабочем листе программой решения уравнения с параметром

 

 

Private Sub ConmiandButton1_Click ()

 

' Процедура нахождения корней уравнения с параметром

 

Dim ПараметрНач As Double

Dim ПараметрКон As Double

Dim ПараметрШаг As Double

Dim НачПрибл As Double

Dim ПраваяЧасть As Double

Dim Формула As String

 

' ПараметрНач - начальное значение параметра

' ПараметрКон - конечное значение параметра

' ПараметрШаг - шаг изменения параметра

' НачПрибл - начальное приближение корня, общее для всех

' значений параметра

' ПраваяЧасть - правая часть уравнения

' Формула - левая часть уравнения. Уравнение записывается так,

' что неизвестная входит только в левую часть,

а ' правая часть постоянна

 

Dim i As Integer

Dim Длина As Integer

Dim n As Integer

 

' i, n. Длина - вспомогательные переменные

 

' Ввод исходных данных из диалогового окна

 

With UserForm1

ПараметрНач = CDb1(.TextBox1.Text)

ПараметрКон = CDb1(.TextBox2.Text)

ПараметрШаг = CDb1(.TextBox3.Text)

НачПрибл = CDb1(.TextBox4.Text)

Формула = Trim(CStr(.RefEdit1.Text))

ПраваяЧасть = CDb1(.TextBox5.Text)

End With

 

' Элемент управления RefEdit при вводе в него ссылок на ячейки

' щелчком в соответствующей ячейке возвращает абсолютные ссылки на

' эти ячейки.

' При протаскивании маркера заполнения выделенной ячейки,

' содержащей формулу левой части уравнения, вниз по столбцу

' для получения корректного результата необходима не абсолютная, а

' относительная ссылка. Для преобразования абсолютной ссылки в

' относительную ниже в операторе цикла Do-Loop из строки с формулой,

' присвоенной строковой переменной Формула, удаляются все знаки

' абсолютной ссылки $

 

i = 1

Do

If Mid(Фopмyлa, i, 1) = "$" Then

Длина = Len(Формула)

Формула = Left(Формула, i - 1) + Right(Формула, Длина - i)

Else

i = i + 1

End If

Loop While i <= Len(Формула)

 

' Очистка трех первых столбцов рабочего листа

 

Range("А:С").Clear

 

' Форматирование заголовка отчетной таблицы.

' Установка:

'   ширины первых трех столбцов

'    высоты первой строки

'    выравнивание

 

Range("A:A").ColumnWidth = 12

Range("B:B").ColumnWidth = 14

Range("С:С").ColumnWidth = 17

Range("A1:C1").Select

With Selection

.RowHeight = 37

.HorizontalAlignment = x1General

.VerticalAlignment = x1Top

.WrapText = True

.Font.Bold = True

.Font.Size = 11

End With

 

' Ввод заголовков трех первых столбцов рабочего листа

 

Range("A1").Value = "Параметр"

Range("B1").Value = "Переменная"

Range("C1").Value = "Левая часть уравнения"

 

' Установка параметров метода Подбор параметра

 

With Application

.MaxIterations = 1000

.MaxChange = 0.0001

End With

 

' Ввод в столбец А значений параметра

 

Range("A2").Value = ПараметрНач

Range("A2").Select

Selection. DataSeries Rowco1:=x1Columns, _

Type:=x1Linear, Step:=пapaмeтpШar, Stop:=ПараметрКон

 

' Определение числа заполненных строк

 

n = Range("A2").CurrentRegion.Rows.Count

 

' Ввод в диапазон столбца В начального приближения

 

Range(Cells(2, 2), Cells(n, 2)).Value = НачПрибл

 

' Ввод в диапазон столбца С левой части уравнения

 

Range ("C2").Formula = Формула

Range ("С2").AutoFill

Destination:=Range(Cells(2, 3), Cells(n, 3)), _

Type:=x1FillDefault

 

' Последовательное решение уравнений с помощью команды Подбор параметра

 

For i = 2 То n

Cells(i, 3).GoalSeek Соа1:=ПраваяЧасть,

ChangingCell:=Cells(i, 2)

Next i

 

' Вызов процедуры для построения графика

 

ПостроениеГрафика

 

End Sub

 

 

Private Sub ConroandButton2_Click()

 

' Процедура закрытия диалогового окна

 

Usertorm1 .Hide

End Sub

 

 

Private Sub UserFom Initialize()

 

' Процедура активизации диалогового окна

' Клавише <Enter> назначена функция кнопки Вычислить.

' Клавише <Еsс> назначена функция кнопки Отмена.

 

CommandButton1.Default = True

CoininandButton2 . Cancel = True

UserForm1.Show

End Sub

 

 

Sub Построение Графика ()

 

' Процедура построения графика

 

Dim n As Integer

 

' n - число строк диапазона, по которому строится график

 

Dim Диапазон Оси Y As Object

Dim Диапазон Оси  Х As Object

Dim Имя Диаграммы As String

Dim Диапазон Y As String

Dim Диапазон Х As String

Dim Имя Листа As String

 

n = ActiveSheet. Cells(1, 1).CurrentRegion. Rows.Count

 

Имя Листа = ActiveSheet. Name

 

' Удаление всех ранее построенных диаграмм с рабочего листа

 

ActiveSheet. ChartObjects. Delete

 

' Создание новой диаграммы и установка ее типа

 

Charts.Add

ActiveChart.ChartType = x1LineMarkers

 

' Определение диапазона, отводимого под значения функции

 

Диапазону = "В2:В" & LTrimCStr (n) )

Set Диапазон ОсиY = Sheets(Имя Листа).Range(Диапазон Y)

 

' Определение диапазона, отводимого под значения аргумента

 

Диапазон Х = "А2:А" & LTrim(CStr (n) )

 

Set Диапазон Оси Х = Sheets(Имя Листа).Range(Диапазон Х)

 

' Построение графика

 

ActiveChart.SetSourceData Source:=Диапаэон Оси Y, PlotBy:=x1Column

ActiveChart.SenesCoilection(1).XValues Диапазон Оси Х

ActiveChart.Location Where:=x1LocationAsObject, Name:=Имя Листа

With ActiveChart

.HasTitle = True

.ChartTitle.Characters.Text = "Зависимость корня от параметра"

.Axes (x1Category, x1Primary) .HasTitle = True

.Axes(x1Category, x1Primary).AxisTitle.Characters.Text = "Параметр"

.Axes(x1Value, x1Primary).HasTitle = True

.Axes(x1Vaiue, x1Primary).AxisTitle.Characters.Text - "Корень"

End With

ActiveChart.HasLegend = False

Имя Диаграммы = ActiveSheet .ChartObjects (1).Name

 

' Перемещение диаграммы и изменение ее размеров

 

ActiveSheet.Shapes(Имя Диаграммы).ScaleHeight 1.17, msoFalse,

msoScalcEromBottomRight

ActiveSheet.Shapes(Имя Диаграммы).IncrementLeft 124.5

ActiveSheet.Shapes(Имя Диаграммы).IncrementTop -25.5

 

End Sub

 

Процедура построениеГрафика выглядит довольно громоздкой. При ее написании лучше всего воспользоваться MacroRecorder, который переведет производимые пользователем вручную действия по построению диаграммы на язык VBA. Итак, для активизации MacroRecorder выберите команду Сервис, Макрос, Начать запись (Tools, Macro, Record New Macro) и запустите MacroRecorder на запись. После задания всех параметров в появившемся диалоговом окне Запись макроса (Record Macro) и нажатия кнопки ОК появится плавающая панель инструментов с кнопкой Остановить запись (Stop Recording). Теперь все производимые действия будут записываться до тех пор, пока не будет нажата эта кнопка. Постройте диаграмму по следующему алгоритму:

 

1. Нажмите кнопку Мастер диаграмм (Chart Wizard) панели инструментов Стандартная (Standard).

2. В появившемся окне первого шага мастера диаграмм на вкладке Стандартные (Standard Types) в списке Тип (Chart type) выберите График (Line), а в группе Вид (Chart sub-type) — четвертый элемент. Нажмите кнопку Далее > (Next >).

3. В появившемся окне второго шага мастера диаграмм на вкладке Диапазон данных (Data Range) выберите переключатель Ряды в столбцах (Series in Columns) и в поле Диапазон (Data range) введите ссылку на диапазон =лист1! $в$2:$в$12, отводимый под значения функции, график которой строится. В поле Подписи оси Х (Category (X) axis labels) вкладки Ряд (Series) введите ссылку на диапазон =Лист1! $А$2:$А$12, отводимый под значения аргумента. Нажмите кнопку Далее > (Next >).

4. В появившемся окне третьего шага мастера диаграмм на вкладке Заголовки (Titles) в поле Название диаграммы (Chart title) введите Зависимость корня от параметра, в поле Ось Х (категорий) (Category (X) axis) Параметр, в поле Ось Y (значений) (Category (Y) axis) — Корень. На вкладке Легенда (Legent) снимите флажок Добавить легенду (Show Legent). Нажмите кнопку Далее > (Next >).

5. В появившемся окне четвертого шага мастера диаграмм в группе Поместить диаграмму на листе (Place chart) выберите переключатель имеющемся (As object in). Нажмите кнопку Готово (Finish).

6. В построенной диаграмме ухватитесь за маркер изменения размера и увеличьте размер диаграммы. После этого, ухватившись за маркер переноса, переместите диаграмму в требуемое место на рабочем листе.

Перечисленные выше действия будут переведены MacroRecorder в следующий макрос.

 

Sub Макрос1()

 

' Макрос1 Макрос

 

' Макрос записан 27.04.99 (Андрей)

 

Charts.Add

ActiveChart.ChartType = x1LineMarkers

ActiveChart.SetSourceData

Source:=Sheets("Лист1").Range("B2:B12"), _

PlotBy: =x1Columns

ActiveChart.SeriesCollection(1).XValues = "=Лист1!R2C1:R12C1"

ActiveChart.Location Where:=x1LocationAsObject, Namе:="Лист1"

With ActiveChart

.HasTitle = False

.Axes(x1Category, x1Primary).HasTitle = False

.Axes(x1Value, x1Primary).HasTitle = False

End With

With ActiveChart

.HasTitle = True

.ChartTitle.Characters.Text = "Зависимость корня от параметра"

.Axes(x1Category, x1Primary).HasTitle = True

.Axes(x1Category, x1Primary).AxisTitle.Characters.Text --= "Параметр"

.Axes(xlValue, x1Primary).HasTitle = True

.Axes(xlValue, x1Primary).AxisTitle.Characters.Text = "Корень"

End With

ActiveSheet.ChartObjects("Диагр. 14").Activate

ActiveChart.ChartArea.Select

ActiveSheet.Shapes("Диагр. 14").ScaleHeight 1.17, msoFalse, _

msoScaleFromBottomRight

ActiveSheet.Shapes("Диагр. 14").IncrementLeft 124.5

ActiveSheet.Shapes("Диагр. 14").IncrementTop -25.5

End Sub

 

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

 

Процесс создания процедур для построения графиков с использованием MacroRecorder, особенно для избавления процедуры от привязки к конкретному диапазону данных, рабочему листу и имени диаграммы, кому-то может показаться излишне искусственным. Им советуем для построения графиков использовать метод ChartWizard, дающий более быстрый путь к цели. Ниже приведены необходимые изменения в процедуре Построение-Графика для метода ChartWizard. Уже поверхностное сравнение старой и новой версий процедуры Построение Графика показывает, что благодаря методу СhartWizard процедура стала компактнее. Кроме того, теперь она использует меньше вспомогательных переменных, необходимых при построении диаграммы.

 

Sub Построение Графика() I

 

' Процедура построения графика

 

Dim n As Integer

 

' n - число строк диапазона, по которому строится график

 

n = ActiveSheet.Cells(1, 1).CurrentRegion.Rows.Count

 

' Удаление всех ранее построенных диаграмм с рабочего листа

 

ActiveSheet.ChartObjects.Delete

 

'(195, 30, 200, 190) - координаты области, где строится диаграмма

 

ActiveSheet.ChartObjects.Add(195, 30, 200, 190).Select

 

' Построение диаграммы

 

ActiveChart ChartWizard Source:=

Range(Cells(2, 1), Cells(n, 2)), _

Gallery.=x1Line, Format:=4, PlotBy:=x1Columns, _

CategoryLabels:=1, SeriesLabels ."0, HasLegend-=False,

Title:="Зависимость корня от параметра",

CategoryTitle:="Параметр",

ValueTitle:="Корень", ExtraTitle:=""

End Sub

 

 

Самостоятельное задание

 

Разработать приложение с диалоговым окном Уравнение с двумя параметрами (рис. У5.3), которое позволит:

 

1. Находить при всех возможных комбинациях значений параметров a и b корни уравнения с одной неизвестной, зависящего от этих двух параметров. Например,

2. х3 - ax2 + b = 0.

3. Строить график, показывающий зависимость корня от значений параметров а и b.