Занятие 16 «Процедуры и функции в Visual Basic» В настоящем занятии возможности использования процедур и функций в своих проектах такие как передача параметров процедурам и функциям, именованные аргументы процедур и функций, необязательные аргументы в процедурах и функциях, обсуждаются вопросы грамотной документации процедур и функций и многократного использования процедур и функций в нескольких проектах. 1. Передача параметров процедурам и функциям Возможности процедур и функций можно расширить, передавая им значения с помощью параметров (аргументов). В процедурах событий набор параметров зависит от события и не может быть изменен разработчиком. Например: Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer) End Sub Как вы видите, в заголовке процедуры может указываться тип данных для параметра. В общих процедурах количество и порядок используемых аргументов определяется разработчиком. Очень важно, чтобы передаваемые значения соответствовали типам данных аргументов и их порядку. Если вы написали процедуру, которая имеет три аргумента типа Integer, необходимо передать процедуре при ее вызове три целых значения. Если вы передали, например, два целых и одно строковое значение, появится сообщение об ошибке. Если, например, функция Find( ) объявлена оператором: Public Function Find( aNum As Integer, bNum As Integer ) а вызывается эта функция с помощью оператора: MyRes = Find(11, “Natalia”) вы получите сообщение об ошибке. “Natalia” имеет тип String. Обратите внимание, аргументы указываются в скобках. Не менее важную роль играет количество аргументов. Если процедуру объявили с помощью оператора: Public Sub Few (i As Integer, dNum As Double, strN As String) а вызываете эту процедуру строкой кода: Call Few 6,7 такой вызов приведет к ошибке. Процедура ожидает трех значений, а вы передаете только два. Обратите внимание, при вызове процедуры аргументы не берутся в скобки. 1 2. Модификация проекта нахождения наибольшего из двух чисел Давайте модифицируем проект нахождения наибольшего из двух натуральных чисел таким образом, чтобы сравнение чисел и выбор наибольшего из них производились в отдельной функции, а распечатывались – в отдельной общей процедуре. Сделаем графический интерфейс. На форму поместим два текстовых окна. Первое текстовое окно txtFirst - чтобы пользователь мог ввести первое число, второе txtSecond – для второго числа. На форму также поместим командные кнопки cmdEnter и cmdExit и оставим место для того, чтобы распечатать результат сравнения. Форма может выглядеть приблизительно вот так: Составим сначала код функции MaxFromTwo, в которой два числа, введенных пользователем, сравниваются и производится выбор наибольшего из них. Постараемся сделать функцию инкапсулированной, т. е. не зависящей от других частей кода и конкретных объектов. Пусть у нашей функции будет два параметра: numOne – с помощью него в функцию будет передаваться первое число; numTwo – для второго числа. Тогда функция MaxFromTwo будет иметь вид: Private Function MaxFromTwo (numOne As Integer,numTwo As_ Integer) As Integer If numOne > numTwo Then MaxFromTwo = numOne ElseIf numOne = numTwo Then MaxFromTwo = numOne Else MaxFromTwo = numTwo End If End Function Функция MaxFromTwo не зависит от конкретных объектов или формы. Вы можете вызывать ее в различных частях кода своего проекта. В функцию передаются два аргумента: первое и второе число. Сделаем теперь код процедуры для распечатывания результатов сравнения. Назовем эту процедуру Printed и будем передавать ей с помощью параметра одно значение – наибольшее число (параметр max%). Процедура будет иметь вид: 2 Private Sub Printed(max%) Dim i As Integer Cls For i = 1 To 10 Print Next i FontSize = 14 Print "Из двух чисел наибольшее - ";max% End Sub Эта процедура привязана к нашей форме, поэтому она плохо инкапсулирована. В ней учитывается, что вверху формы размещено четыре объекта: два текстовых окна и две командные кнопки, а результаты сравнения двух чисел должны печататься ниже этих объектов, на пустом месте формы. Нам осталось составить код кнопки cmdEnter, в котором содержимое текстовых окон должно менять тип и присваиваться переменным, и в котором должны вызываться функция MaxFromTwo и процедура Printed. Private Sub cmdEnter_Click( ) Dim i%, j%, retVal% Cls i% = CInt(txtFirst.Text) j% = CInt(txtSecond.Text) retVal% = MaxFromTwo(i%, j%) Call Printed(retVal%) End Sub И последний код для кнопки cmdExit_Click( ): Private Sub cmdExit_Click( ) Cls End End Sub Попробуйте работу проекта на компьютере, проанализируйте результаты, сделайте дополнения, какие сочтете уместными. 3. Проект вычисления корней квадратного уравнения Самостоятельно сделайте проект, в котором после введения пользователем конкретных значений коэффициентов a, b и с, вычислялись бы корни квадратного уравнения: a x2 b x c Пусть в функции общего назначения вычисляется дискриминант, в процедуре общего назначения анализируется дискриминант и находятся корни уравнения, и еще в одной процедуре общего назначения результаты распечатываются на форме или на каких-либо элементах управления формы. 3 4. Именованные аргументы Обычно аргументы передаются в последовательности, указанной в заголовке процедуры. В Visual Basic можно использовать так называемые именованные аргументы, с помощью которых часть или все аргументы можно передавать в любом порядке. Для этого при вызове процедуры имя аргумента и его значение разделяются специальным знаком – двоеточием со знаком равенства (:=). Например,MyArgument :=”SomeValue”. Аргументы разделяются запятыми, и порядок их следования не имеет значения. Private Sub cmdEnter_Click( ) MyProcedure numOne:=1, numThree:=3, numTwo:=2 End Sub Sub MyProcedure (numOne, numTwo, numThree) Print numOne, numTwo, numThree End Sub В этом примере при вызове процедуры аргументы указаны в другой последовательности, чем в заголовке процедуры, однако, благодаря именованию, каждой переменной присваивается соответствующее значение и распечатается: 1 2 3. При вызове процедур можно передавать именованные и неименованные аргументы комбинированно. Однако, как только в списке передачи появляется именованный аргумент, все последующие аргументы должны передаваться именованными. Рассмотрим пример: Private Sub Command1_Click( ) MyProcedure 1, numTwo:=2, numThree:=3 End Sub Sub MyProcedure (numOne, numTwo, numThree) . . . End Sub Первый аргумент определяется своей позицией, два других (второй и третий) передаются как именованные. Использование именованных аргументов имеет два преимущества: вопервых, имя аргумента разъясняет его назначение, поэтому не нужны дополнительные комментарии; во-вторых, это может предотвратить ошибочное присваивание значений не тем аргументам. 5. Многократное использование процедур Возможности многократного использования хорошо инкапсулированной процедуры или функции ограничены, если эта процедура или функция находится в коде формы. Если вы захотите использовать процедуру или функцию в другом проекте, вам придется добавить в проект всю форму. При этом придется переносить в новый проект всю ненужную графику и коды процедур. 4 Процедуру, допускающую многократное использование, лучше всего создавать внутри модуля. Если эта процедура не зависит от каких-либо элементов управления, хорошо инкапсулирована, помещение ее в модуль обеспечит вам возможности для ее многократного использования. Со временем у вас накопится целая библиотека модулей, содержащая процедуры, постоянно используемые вами в своей программистской деятельности. Если вам в дальнейшем понадобится эта процедура или функция еще в каком-нибудь проекте, выберите Add File (добавить файл) из меню Project (проект), а затем добавьте модуль в свой новый проект. Когда вы это сделаете, функцию или процедуру можно будет вызывать точно так же, как и любую другую в проекте. 6. Модификация проекта prjMaxFromThree Мы сделали хорошо инкапсулированную функцию MaxFromTwo. Попробуем использовать ее для проекта prjMaxFromThree, в котором из трех введенных пользователем натуральных чисел должно выбираться наибольшее. Создадим модуль MyModule и перенесем в него код функции MaxFromTwo. (Не забудьте объявить функцию как общую – Public). Теперь мы сможем вызывать ее из любой части кода проекта. Создадим графический интерфейс пользователя на форме frmMaxFromThree. Поместим на нее три текстовых окна: txtFirst, txtSecond, txtThird для того, чтобы пользователь мог вводить три числа, и две командные кнопки: cmdEnter, в коде которой будут производиться основные действия проекта, и cmdExit для выхода из проекта. Нижнюю треть формы оставим свободной для распечатывания на ней результата. Форма будет иметь приблизительно следующий вид: Составьте код cmdExit_Click( ) в коде формы frmMaxFromThree. Private Sub cmdExit_Click( ) End Sub Составьте код общей процедуры Printed( ), с помощью которой на форме будет распечатываться результат расчетов. Процедура будет с параметром, с помощью которого в нее передается наибольшее из трех чисел. Эта процедура 5 ориентирована на конкретную форму с ее конкретным расположением элементов управления, поэтому она не инкапсулирована и нет смысла помещать ее в модуль. Private Sub Printed ( max%) End Sub Осталось составить код для кнопки cmdEnter формы frmMaxFromThree. В ней необходимо объявить четыре целочисленных переменных: три для хранения чисел, введенных пользователем в текстовые окна, четвертую для хранения результата – выбранного из них наибольшего числа. Необходимо присвоить каждой переменной значение соответствующего текстового окна с преобразованием типа, выполнить функцию MaxFromTwo сначала для первых двух чисел, потом для выбранного из них наибольшего числа и третьего числа. После этого нужно вызвать процедуру Printed( ). Во все процедуры и функции аргументы передавайте именованными. Допишите процедуру. Private Sub cmdEnter_Click( ) Dim k%, l%, m%, retval% k% = CInt ( txtFirst.Text) retval% = maxFromTwo ( numOne:=k%, numTwo%:=l%) End Sub Опробуйте проект на компьютере. 7. Необязательные функциях аргументы в процедурах и Если при вызове процедуры указать не все аргументы, то последует сообщение об ошибке. Однако в процессе описания процедуры можно определить, что не все аргументы указываются при вызове. Такие аргументы называются необязательными. Для того, чтобы аргумент был необязательным, перед именем аргумента необходимо поставить слово Optional. После первого необязательного аргумента все последующие должны быть необязательными. Sub MyProc(nOne As Double, Optional nTwo As Integer,C As Integer) Print nOne, nTwo, C End Sub Вызвать процедуру можно, передавая ей обязательный первый параметр, например, так: Call MyProc 10 Процедура распечатает: 10. 6 Можно вызвать процедуру, передавая ей значения двух параметров: обязательного первого и необязательного второго, например, так: Call MyProc 1,2 Процедура распечатает: 1 2. Можно вызвать процедуру, передав ей значения всех трех параметров: Call MyProc 1,2,3 Процедура распечатает: 1 2 3. Можно аргументы сделать именованными, например, MyProc nOne:=1, C:=3, nTwo:=2 Процедура распечатает: 1 2 3. Для необязательных аргументов можно задавать все типы данных, кроме пользовательских. 8. Документация процедур и функций Если другой программист захочет использовать процедуру или функцию, созданную вами, она должна быть хорошо документирована. Все процедуры и функции должны иметь раздел заголовка (header). Раздел заголовка – это раздел, состоящий из комментариев, расположенных в начале блока кода. Обычно в разделе заголовка приводится краткое описание процедуры, включающее имя процедуры, описание ее параметров, возвращаемое значение, если такое имеется, некоторые замечания по поводу использования этой процедуры, а также указывается, кто и когда ее создал. Если в дальнейшем в код вносятся какие-либо изменения, описание этих изменений и информация о дате их внесения тоже добавляются в раздел заголовка. И наконец, в раздел заголовка помещается информация об авторских правах. Нужно комментировать и отдельные задачи в рамках процедуры. Это позволит сохранить время тем, кто будет поддерживать ваш код. Приведем код созданной нами и правильно документированной функции MaxFromTwo: Public Function MaxFromTwo (numOne As Integer, numTwo As_ Integer) As Integer ‘* * * * * ‘Функция: MaxFromTwo для нахождения наибольшего ‘из двух натуральных чисел ‘Аргументы: numOne – первое натуральное число ‘numTwo – второе натуральное число ‘Возвращаемое значение: наибольшее из двух ‘натуральных чисел тоже натуральное ‘число ‘Разработчик: Истомина Татьяна Львовна ‘Создана: 20.05.2000 ‘* * * * * . . . End Sub Документируйте свою функцию. 7 9. Задания Доделайте проект prjMaxFromThree с использованием функции MaxFromThree, описанный в пункте 6, документируйте функцию MaxFromThree, как описано в пункте 8. 8