Процедуры и функции
Принцип модульного программирования очень облегчает программирование и отладку. Модульное программирование - означает разделение кода программы на отдельные куски, каждый из которых выполняет чётко определённую задачу. Это особенно важно для сложных программ.
Давайте оформим некоторые части кода в виде процедур и функций. Например, напишем функцию для вычисления дискриминанта. И напишем процедуру, которая будет выводить полученные значения в метки. Почему именно процедуру? Потому что процедуры пишутся для выполнения некоторой последовательности действий, где не требуется возвращать какое-либо значение. Давайте ещё раз посмотрим на ту часть кода, где происходит проверка значения дискриминанта и вычисление корней уравнения:
If D > 0 Then x1 = (paramB + Sqr(D)) / (2 * paramA) x2 = (paramB - Sqr(D)) / (2 * paramA) lblD.Caption = "Дискременант: " & D lblX1.Caption = "Корень №1: " & x1 ' <- здесь lblX2.Caption = "Корень №2: " & x2 ElseIf D = 0 Then x1 = paramB / (2 * paramA) x2 = x1 lblD.Caption = "Дискременант: " & D lblX1.Caption = "Корень №1: " & x1 ' <- и здесь lblX2.Caption = "Корень №2 = Корню №1" ElseIf D < 0 Then lblD.Caption = "Дискременант: " & D lblX1.Caption = "Корней нет!" ' <- и здесь, тоже lblX2.Caption = "" MsgBox "Дискременант меньше нуля! Корней нет!", vbCritical End If
Заметьте, что в каждом из ветвей оператора If наблюдается присвоения свойству Caption 3-х меток (lblD, lblX1, lblX2). Поэтому логично этот участок оформить в виде процедуры, параметрами которой будут значения для меток.
Ну, что ж, приступим?
Сначала напишем функцию для вычисления дискриминанта. Чтобы вычислить дискриминант необходимо знать 3 параметра - коэффициенты a, b и с. Функция будет возвращать значение - дискриминант. Чтобы самому не писать заготовку для этой функции, Visual Basic предоставляет возможность для автоматического создания такой заготовки. Для этого выберите в главном меню VB: Tools->Add Procedure. (Insert->Procedure).. Появится окно, в котором вас попросят указать вид добавляемой процедуры. Отметьте радиокнопку Function. В поле "Name:", укажите имя добавляемой функции. Давайте назовём её, например, как CalcDiscremenant. Не бойтесь давать длинные названия процедурам и функциям! Всё равно, когда вы захотите использовать эту процедуру в коде, вам не придётся полностью набивать на клавиатуре её имя. Но об этом чуть ниже.
Итак, нажмите OK и Visual Basic создаст для вас следующую заготовку:
Public Function CalcDiscremenant()
End Function
Теперь модифицируем её так, чтобы функция принимала 3 аргумента (параметра) типа Double, и возвращала значение, которое тоже будет иметь тип Double:
Public Function CalcDiscremenant(a As Double, _ b As Double, c As Double) As Double
End Function
Осталось добавить код в нашу заготовку. Сделать это не трудно:
Public Function CalcDiscremenant(a As Double, _ b As Double, c As Double) As Double CalcDiscremenant = (b * b) - (4 * a * c) End Function
Необходимо подчеркнуть, что в Visual Basic параметры можно передавать двумя способами: по значению и по ссылке. Первый способ передает в процедуру (или функцию) только значение передаваемой переменной. Внутри функции изменить значение такой переменной будет нельзя. Второй способ передаёт в функцию ссылку на передаваемую переменную, и её значение легко может быть изменено в теле функции. По умолчанию, Visual Basic всегда передает параметры по ссылке. В нашем случае параметры a, b и c не изменяются внутри функции. Поэтому можно сделать так, чтобы параметры передавались по значению. Для этого перед именем переменной необходимо поставить ключевое слово ByVal (By Value), вот так:
Public Function CalcDiscremenant(ByVal a As Double, _ ByVal b As Double, ByVal c As Double) As Double
В принципе, делать это не обязательно, но всё же желательно. Это повышает наглядность. Теперь, любой, кто воспользуется нашей функцией сразу будет знать, что значения передаваемых переменных внутри функции меняться не будут (да и не могут).
Теперь у нас есть функция, которая будет принимать 3 коэффициента a, b, c и вычислять дискриминант. Давайте опробуем её в действии. Для этого замените в нашей программе строчку, где вычислялся дискриминант:
D = (paramB * paramB) - (4 * paramA * paramC)
на строчку:
D = CalcDiscremenant(paramA, paramB, paramC)
Осталось написать процедуру для вывода результатов в метки. Добавим затоговку так же, как и в предыдущем случае (Tools->Add Procedure). Только на этот раз не будем отмечать радиокнопку Function, а оставим всё как есть (Sub). В качестве имени процедуры можно ввести, ну, скажем WriteResultsInLabels. Чем длиннее название, тем понятнее, чем занимается данная процедура или функция. Нажмём ОК:
Public Sub WriteResultsInLabels() End Sub
Сделаем так, чтобы наша процедура принимала 3 параметра - значения, которые необходимо вывести в соответствующие метки:
Public Sub WriteResultsInLabels (lblDCapt As String, _ lblX1Capt As String, lblX2Capt As String) End Sub
Входные параметры имеют тип String, т.к. передавать в процедуру мы будем именно строки.
Для того, чтобы процедура работала, необходимо добавить в неё код:
Public Sub WriteResultsInLabels (lblDCapt As String, _ lblX1Capt As String, lblX2Capt As String) lblD.Caption = lblDCapt lblX1.Caption = lblX1Capt lblX2.Caption = lblX2Capt End Sub
Готово. Можно использовать процедуру. Давайте заменим каждые 3 строчки, где мы выводили значения в метки. Получится нечто подобное:
If D > 0 Then x1 = (paramB + Sqr(D)) / (2 * paramA) x2 = (paramB - Sqr(D)) / (2 * paramA) WriteResultsInLabels "Дискриминант: " & D, _ "Корень №1: " & x1, "Корень №2: " & x2 ElseIf D = 0 Then x1 = paramB / (2 * paramA) x2 = x1 WriteResultsInLabels "Дискриминант: " & D, _ "Корень №1: " & x1, "Корень №2 = Корню №1" ElseIf D < 0 Then WriteResultsInLabels "Дискриминант: " & D, _ "Корней нет!", "" MsgBox "Дискриминант меньше нуля! Корней нет!", vbCritical End If
Программа готова.
Private Sub cmdCalculate_Click()
Dim paramA As Double
Dim paramB As Double
Dim paramC As Double
Dim x1 As Double
Dim x2 As Double
Dim D As Double
paramA = txtParamA.Text
paramB = txtParamB.Text
paramC = txtParamC.Text
If paramA = 0 Or paramB = 0 Or paramC = 0 Then
MsgBox "Нули в качестве коэффициентов не допускаются!", _
vbCritical
Exit Sub
End If
D = CalcDiscremenant(paramA, paramB, paramC)
If D > 0 Then
x1 = (paramB + Sqr(D)) / (2 * paramA)
x2 = (paramB - Sqr(D)) / (2 * paramA)
WriteResultsInLabels "Дискременант: " & D, _
"Корень №1: " & x1, "Корень №2: " & x2
ElseIf D = 0 Then
x1 = paramB / (2 * paramA)
x2 = x1
WriteResultsInLabels "Дискриминант: " & D, _
"Корень №1: " & x1, "Корень №2 = Корню №1"
ElseIf D < 0 Then
WriteResultsInLabels "Дискриминант: " & D, _
"Корней нет!", ""
MsgBox "Дискриминант меньше нуля! Корней нет!", vbCritical
End If
End Sub
Private Sub txtParamA_Change()
End Sub
Private Sub UserForm_Click()
End Sub
Public Function CalcDiscremenant(ByVal a As Double, ByVal b As Double, ByVal c As Double) As Double
End Function
Public Sub WriteResultsInLabels(lblDCapt As String, _
lblX1Capt As String, lblX2Capt As String)
lblD.Caption = lblDCapt
lblX1.Caption = lblX1Capt
lblX2.Caption = lblX2Capt
End Sub