Реферат: Калькулятор на VB - это легко!

(автор: Есин  И. В., email: tofriend@list.ru)

 

О чём ...

 

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

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

 

 

Первый шаг или интерфейс пользователя

 

          Здесь особо ничего фантазировать не надо, а просто вспомнить,как выглядит обычный калькулятор, какие кнопки у него и каково их назначение. У меня получилось так:

/>

ИнструментCommandButtonсодержиттакие интересующие нас свойство и событие, которые дают нам полную ясность еговыбора.  Аналогичное можно сказать и про инструмент Label. Декоративный инструмент Line необязателен.

Дляпонимания моего программного кода вам надо будет согласиться со следующимиименами представленных объектов и их свойствами:

·          Форме присвоим имя Calculator.

·          Кнопки с цифрами образуют массивкнопок Knopkiиндексы,которых совпадают с их надписями.

·          Кнопка точка — это объект с именемTochka, a кнопкаизменения знака числа [+/-] — Plusmin.

·          Кнопки арифметических операцийимеют общее имя Operacia, но проиндексированы.  Причём кнопка с надписью + имеет индекс 4, кнопка со знаком минус — индекс 2,кнопка «разделить» — 0, а кнопка соответствующая умножению — 5.

·          Кнопка «сброс» [С] — Sbros.

·          Кнопка «очистить» [CE] — Ochistka.

·          Кнопка «удалить» [<-]  Udalit.

·          Кнопка «равно» [=] — Ravno.

·          Единственная метка называется Tablo (и далее — индикатор отображения вычислений будем называть«табло»).

Всоответствие с рисунком измените свойство Caption всех объектов. Так, например,для объекта Tabloегозначением будет 0.и свойство Font: FontSize= 14.  Для всех кнопок свойство Styleимеет значение 1-Graphical.  Свойство TabStopвсехобъектов – False.

Свойствоформы KeyPreview обязаноиметь значение True.  Ведь надо жепользователю предоставить возможность вычислять с клавиатуры!

А BorderStyle-1-FixedSingle.

          Немалая частьпроекта уже завершена ...  Продолжим работу!

          Второй шаг или«как заставить эту штуковину работать?!!»

 

          Прежде чем писать обработчики событий для данныхэлементов управления «возьмём в руки» обычный калькулятор и выясним«механизм» его работы.  И сразу же можем сказать, что у него трисостояния: включён, выключен и первоначальная готовность.  Все эти состояниясчитайте уже написаны (они обеспечиваются открытием и закрытием окна приложенияи значением свойства Caption меткиTablo)!

          Далее,выясним какие действия может осуществлять пользователь над кнопками нашейвещицы и что же при этом происходит на табло?

а) Нажатие на одну из цифр — на табло справа к уже имеющемуся числу прибавляетсянажатая цифра.  Однако если данное число ноль, его заменяет введённая цифра.

б) Нажатие точки — изменений на табло нет.

в) Нажатие плюс/минус — на табло слева к уже имеющемуся числу прибавляется минусили убирается.

г) Выбор одной из арифметических операций — возможное вычисление значенияпредыдущей операции с отображением его на табло.

д) Вычислить (кнопка равно) — на табло может отобразиться результат заданнойоперации.

е) Удаление «последней» цифры числа — на табло удаляется«последняя» цифра.

ж) Очистить (кнопка CE) — на табло «исчезает» набранное число и«превращается» в ноль!

з) Сброс — на табло ноль.

          Асвязаны ли как-то между собой эти действия или с какими-нибудь состояниями?  И...  когда возможно данное действие, а когда нет?  Ответим в той жепоследовательности.

а) Если была нажата точка, то набирается дробное число.  Очевидно, мы не можемввести число, которое не умещается в табло.  И нам надо учитывать, что число необязано быть целым (то есть не всегда число оканчивается точкой).

б) Нет согласованных действий.  Нельзя поставить точку, если число уже дробное.

в) Нет согласованных действий.  Действие можно выполнить всегда!

г) Вычисление значения заданной операции.  Действие можно выполнить всегда.

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

е) Нет согласованных.  Нельзя выполнить, если на табло ноль.

ж) Нет согласованных.  Действие выполнимо всегда!

з) Состояние первоначальной готовности.  Действие выполнимо всегда!

          Заметимтакже, что включение совпадает с первоначальным состоянием нашей счётноймашинки.

          Итак...  определили не только какие действия может выполнить пользователькалькулятора и что при этом отобразится на табло, но и выявили некоторуювзаимосвязь между действиями и даже одним состоянием.  Остаётся«рассказать» про это всё компьютеру.  Но каким образом?  В нашемраспоряжении VB!

Третий шаг или приближение к программному коду!

 

          «Увидим»же программный код!  При определении чего нам надо, будем исходить только изтого какие элементы управления у пользователя «в руках», зачем емунужен калькулятор и тех выкладок, которые мы с лёгкостью проделали в предыдущемшаге!  А потребуется нам из того богатого ассортимента возможностей, которыйпредоставляет VB всего-то несколько операторов, функций, свойств исобытий известных объектов да понять какие управляющие переменные создать,каков их тип.

          Каккалькулятор поймет, что его только-что включили или был произведён сброс впервоначальное состояние? (з)  И как он узнает какое действие ему задалпользователь? (г)  Понятно, что без переменной здесь не обойтись!  Поэтому в перменнойmode типа String, будем хранить данные режимавычислений.

          Акаким образом калькулятор «запомнит» слагаемое, множитель, делимое,вычитаемое (то есть «первое» число операции)?  Для этого можнообъявить глобальную перменную pervoe.

          Навопрос нужны ли ещё переменные отвечать пока воздержимся.

Вначале была точка.

          Посколькупредставление целого числа на табло оканчивается точкой, то будем «еёставить» в процедуре обработке события (далее — процедуре) Changeметки Tablo:

PrivateSub Tablo_Change()

Dim z AsByte, t As Byte

    z = InStr(1, Tablo.Caption,",")  ' если результат — дробное число ищем позицию запятой

    t = InStr(1, Tablo.Caption, ".")  ' определяем позицию точки

  If t = 0  Then

    ' если точка ненайдётся, то ставим её в конце:

    Tablo.Caption = Tablo.Caption& "."

  ElseIf z<> 0 Then

    ' если событие наступает, в результате«выброса» на табло значения операции, которое является дробнымчислом, то запятую меняем на точку:

    Tablo.Caption = Mid(Tablo.Caption,1, z — 1) & "." & Mid(Tablo.Caption, z + 1,Len(Tablo.Caption) — z — 1)

End If

Здесь,как видите, учитывается тот случай, когда результатом операции является дробноечисло или уже имеется дробное число.

Учимся писать ...   числа.

Теперьнаступило время «набрать» нашему пользователю число!  Позволим емусделать это ...   но пока с помощью мыши.  При этом предусмотрим следующее:  1)он вводит цифру, когда на табло ноль.

2)он не знает (или может забыть) сколько цифр может поместиться в табло.

3)он вводит «второе» число операции, либо число после нажатия кнопкиравно.  4) он вводит цифру, после того как щёлкнул по «точке».

Рассмотрениепервой и второй особенности не представляет особого интереса, поскольку этонетрудно проверяется, сравнивая значение табло  с «нулём» иколичеством допустимых символов соответственно.

Второе число вводится после указания желаемойарифметической операции, где в соответствующей процедуре укажем значение«внутренней» переменной Tagкнопки Ravno значение «второе».  И как только введенапервая цифра «второго» числа, данная переменная становится пустымсимволом.

Дляреализации режима ввода дробного числа воспользуемся также свойством Tag,но уже объекта Tablo, так что если его значение равно «нецелое», то слева от введённой цифры будет ноль.

Данныевыкладки можно реализовать в виде такого программного кода:

PrivateSub knopka_Click(Index As Integer)

  ' если были выбраны равно или операция — вводнового числа:

  If Ravno.Tag = «второе» Then Tablo.Caption = «0»:Ravno.Tag = ""

  If Len(Tablo.Caption) < 16 Then

    ' если длина непревышает допустимой длины числа:

    If Tablo.Caption = «0.»And Tablo.Tag = "" Then

      '  если на табло ноль и нет режима началаввода дробного числа — заменяем цифрой c точкой:

      Tablo.Caption = Index &"."

    Else

      IfMid(Tablo.Caption, Len(Tablo.Caption), 1) = "." And Tablo.Tag<> «не целое» Then

        ' на табло целое число и нет режима вводадробного числа — добавляем цифру и ставим точку в конце:

        Tablo.Caption = Mid(Tablo.Caption,1, Len(Tablo.Caption) — 1) & Index

      Else

        '  на таблодробное число или режим ввода дробного числа — добавляем цифру надписи табло

        Tablo.Caption = Tablo.Caption& Index

 

      EndIf

    EndIf

  End If

 Tablo.Tag = ""    ' возможен (...) вводдробного числа

End Sub

Однакоэтого кода достаточно чтобы обеспечить ввод целых положительных чисел.  Добавимещё две относительно простые по пониманию процедуры.  Первая — изменение знакачисла:

PrivateSub Plusmin_Click()

  SelectCase Val(Tablo.Caption)

    ' меньше нуля — «удаляем» минус:

    Case Is < 0

     Tablo.Caption = Mid(Tablo.Caption, 2, Len(Tablo.Caption))

    ' больше нуля — «прибавляем» минус:

    Case Is > 0

     Tablo.Caption = "-" & Tablo.Caption

  End Select

End Sub

Другая — возможность вводадробного числа:

Private SubTochka_Click()

  ' если числоцелое, то разрешаем ввести дробное число:

  If Fix(Val(Tablo.Caption)) =Val(Tablo.Caption) Or Ravno.Tag = «второе» Then Tablo.Tag = «нецелое»

  ' к тому же… если вводить дробное числопосле указания операции, то целая его часть — ноль:

  If Ravno.Tag = «второе» Then Tablo.Caption = «0»

End Sub

Исправление ошибок ...

Позволимтакже стирать набранное число и удалять последнюю цифру числа на табло, чтообеспечит следующий фрагмент программного кода:

Private Sub ochistka_Click()

  ' щелчёк по кнопкеCE «превращает» число на табло вноль:

  Tablo.Caption =«0»

  Tablo.Tag =""     ' вводим целое число

End Sub

PrivateSub udalit_Click()

   umnaya.SetFocus

    ' является ли число целым?

    If Fix(Val(Tablo.Caption)) = Val(Tablo.Caption)Then

      ' если целое — удалим последнюю цифру

      Tablo.Caption = Mid(Tablo.Caption,1, Len(Tablo.Caption) — 2)

      ' а если число было нулём — то так и оставим- «ноль»:

      If Tablo.Caption = "."Then Tablo.Caption = «0»

    Else

      ' если натабло число не целое, то просто удалим последнюю цифру надписи

     Tablo.Caption = Mid(Tablo.Caption, 1, Len(Tablo.Caption) — 1)

    End If

End Sub

Считать, считать и ещё раз считать!

Далеепользователь, скорее всего, захочет указать одно из арифметических действий:сложить, вычесть, умножить, разделить заданное число с каким-то другим. Предоставим ему такую возможность!

Здесьнеобходимо предусмотреть следующее: 1) пользователь может изменить выбраннуюоперацию (не изменив до этого числа на табло),  2) если пользователь ужевыбирал до этого какую-то операцию, не вычислял её значение с помощью клавиширавно или не задавал состояние первоначальной готовности, то вычисляетсярезультат этой операции.

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

Перваяособенность выбора арифметического действия частично рассмотрена.  Вспомним,что при указании пользователем операции программа запишет в переменную Ravno.Tagзначение«второе».  Таким образом, при вхождении в процедуру обработки событиящелчка мыши по одной из кнопок Operacia условный оператор программного кода с помощью даннойпеременной проверит: «А не изменяет ли пользователь выбранную операцию?!». При отрицательном ответе с помощью переменной deystvieбудетрешать надо ли передавать управление процедуре вычисления значения резултата Rezultat().  В любыхслучаях, переменная deystvieприметзначение соответствующее выбранному арифметическому действию.  При этом ужезнакомая нам переменная pervoe примет значение числа табло, а  Ravno.Tagбудетсообщать процедуре ввода числа, что вводится новое число и предоставлятьвозможность изменить операцию.  Всё это находим в следующей процедуре:

Private Sub Operacia_Click(IndexAs Integer)

  If Ravno.Tag ="" Then  ' нет изменения выбора операции?

    '  если операциябыла задана — вычисляем её значение:

    Ifdeystvie <> «нет» Then vtoroe = Val(Tablo.Caption):rezultat

  End If

  SelectCase Index  ' запишем выбранное действие

    Case0

     deystvie = «разделить»

    Case2

     deystvie = «вычесть»

    Case4

     deystvie = «сложить»

    Case5

     deystvie = «умножить»

  End Select

    pervoe =Val(Tablo.Caption)     ' первое число операции — то что на табло при выбореоперации

    Ravno.Tag =«второе»            ' режим ввода второго числа

End Sub

Несложнодогадаться, что процедура вычисления результата будет вызываться также изпроцедуры обработки нажатия кнопки «равно».  И прежде чем рассматриватьпервую, напишем программный код для второй.

Сделаемтак, что если: 1) второе число не введено и кнопка «равно» нажимаетсяодин раз, то значение не вычисляется, 2) если кнопка нажимается два разаподряд, то в качестве второго числа операции выбирается текущее число табло ирезультат вычисляется.

Вовсех случаях нам будет способствовать переменная Ravno.Tag. Если она равна «второе», то это удовлетворяет первому условию. Однако чтобы реализовать второе назначим данной переменной пустой символ.  Иуже здесь вследствие условия положим значение переменной vtoroeчисло,«которое на табло» и запустим процедуру Rezultat(), затем зададим калькулятору подобие начальногосостояния (без отображения на табло нуля).  Можно написать так:

Private Sub Ravno_Click()

  If Ravno.Tag<> «второе» Then

    vtoroe = Val(Tablo.Caption)

  Callrezultat

    Ravno.Tag = «второе»           'режим ввода «второго» числа

    Tablo.Tag =""                 ' две переменные ука-

    deystvie =«нет»               ' зывают начальное состояние

  Else

 

    Ravno.Tag =""                 ' можем в «следующий раз» считать первымчислом текущее число табло

  End If

End Sub

 

 

 

«Ноль», «нельзя» и «делить»

 

Авот и процедура обработки результата (понимание которой у вас, я думаю, несоставит труда):

PrivateSub rezultat()

  SelectCase deystvie

    Case«сложить»

     Tablo.Caption = pervoe + vtoroe

    Case«вычесть»

     Tablo.Caption = pervoe — vtoroe

    Case«разделить»

      Ifvtoroe <> 0 Then

       Tablo.Caption = pervoe / vtoroe

      Else ' на ноль действительно нельзя делить!

       Tablo.Caption = «на ноль не делят!»

      End If

    Case«умножить»

     Tablo.Caption = pervoe * vtoroe

  End Select

End Sub

 

В ней, как видите, результатсразу «выбрасывается» на табло.

О пользе клавиатуры.

Ипрежде чем подготовиться к последнему желанию пользователя — иметь возможностьпроизводить вычисления с клавиатуры, добавим к уже имеющейся части программногокода процедуру обработки нажатия кнопки [С] (сброс в первоначальную)готовность:

Private SubSbros_Click()

    deystvie =«нет»    ' стираем, возможно, указанное действие

  Tablo.Caption =«0»   ' на табло — ноль

  Tablo.Tag =""        ' по умолчанию — вводится целое число

End Sub

Пользовательбудет вводить число с клавиатуры используя клавиши с цифрами, клавиши с точкой,а для перемены знака числа клавишу +/=.  Редактировать число с помощью клавиш Backspace и Пробел. Данные действия оперделим в коде процедуры Form_KeyPress(),используя замечательный аргумент этой процедуры — KeyAscii.

Поэтомуесли знать (или узнать) Ascii-коды клавиш, то понимание этой процедуры не займётмного времени:

PrivateSub Form_KeyPress(KeyAscii As Integer)

  SelectCase KeyAscii

    Case8

     udalit_Click

    Case 42, 43, 45, 47  ' теперь стало ясным почемуиндексы

      Operacia_Click (47 — KeyAscii) ' следуют не по порядку?

   

    Case 61 ' меняем знак

     Plusmin_Click

    CaseIs > 47 ' вводим цифры

      IfKeyAscii < 58 Then knopka_Click (KeyAscii — 48)

    Case 32 ' а здесь пробелом «чистим»табло

      ochistka_Click

  EndSelect

End Sub

Даннаяпроцедура не позволяет отлавливать нажатие «точки», так как Ascii-коды«точки» на малой цифровой клавиатуре отличны при разных раскладках.  Напишемсоответствующий код в следующей процедуре.

Исход будет!

Однакомы до сих пор не указали заменители кнопок «сброса в первоначальноесостояние» и «равно».  Для первого случая сложность заключаетсяв придумывании клавиши, а для другого — способа «отлавливания»нажатия клавиши (я думаю ни у кого не возникнет сомнения в том, что нажатиеклавиши Enter будетсоответствовать щелчку по кнопке равно).

Сбрасываем в начальноесостояние клавишей Delete:

PrivateSub Form_KeyDown(KeyCode As Integer, Shift As Integer)

  If KeyCode= 46 Then sbros_Click

  ' посколькузначения «точки» малой цифровой клавиатуры у KeyAsciiне одинаковые

  ' при различныхраскладках, то «ловим» её с помощью KeyCode

  IfKeyCode = 110 Then tochka_Click

End Sub

Пойматьнажатие клавиши Enter накнопке можно следующим образом.  Для этого вначале бросим на форму текстбокс. И спрячем его под границу будущего окна приложения (вначале увеличим высоту,затем поместим «туда» текстбокс и зададим высоту формы до еёизменения).  Изменим лишь свойства TabIndexна 1 и Nameна Umno.  Как вы уже скорее всего догадались нажатие по этомуобъекту будет выявлять нажатие клавиши Enter.  Поэтому имеем такую процедуру:

PrivateSub Umno_KeyPress(KeyAscii As Integer)

  IfKeyAscii = 13 Then Ravno_Click

End Sub

Однако,это сработает тогда, когда объект Umnoимеет фокус.  А что, если щёлкнуть по какой-то изкнопок?  Тогда фокус переходит этой кнопке.  И значит, нам надо вначале всехпроцедур обработки щелчков кнопок написать:

  Umno.SetFocus

и тогда фокус будет всегдавозвращаться на нужное нам место!

И,наконец, завершим наш проект, возвратясь почти к самому началу ...

«Покрасим»элементы управления!

Дляэтого процедуру Form_Loadможнонаписать так:

PrivateSub Form_Load()

 Me.BackColor = RGB(50, 150, 250)

 Sbros.BackColor = RGB(250, 50, 0)

 Ochistka.BackColor = RGB(250, 75, 0)

 Udalit.BackColor = RGB(250, 100, 0)

 Ravno.BackColor = RGB(250, 125, 0)

 

 Operacia(4).BackColor = RGB(150, 250, 250)

 Operacia(2).BackColor = RGB(150, 250, 250)

 Operacia(0).BackColor = RGB(150, 250, 250)

 Operacia(5).BackColor = RGB(150, 250, 250)

End Sub

 

Четвёртый шаг или «делу время, а потехе – час!»

 

          F5 — для проверки!

еще рефераты
Еще работы по информатике, программированию