Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

VBA. Практическое программирование

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
666 Кб
Скачать

Моделирование физического процесса

стенками объема, где движутся шарики равно 10 метрам, и, кроме того, шар 1 располагается левее шара 2, поэтому мы предлагаем выбрать значение начальных координат соответственно 2 и 6. В ячейке G2 находим разность координат второго и первого, и следим за тем, чтобы она была больше единицы. Мы закончили создание области ввода и ввели исходные данные. Эту область можно «украсить» различными методами форматирования, снабдить примечаниями и т. д.

Под вычисления займем область — A5:D5. Вписываем формулы — в A5 пишем =mmm1, в C5 — =mmm2. В 4 строке поместим комментарии — «1 шар», «2 шар». В ячейках B5 и D5 в дальнейшем будут отображаться координаты движущихся шариков. Пока туда можно записать те же значения, что содержатся в E2 и F2. Теперь все готово для построения диаграммы.

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

Диаграмму будем строить таким образом, чтобы получить на ней изображение обоих шариков, положение которых будет зависеть от координат X, находящихся в ячейках B5 и D5; Y, равных 2, а размеры от массы (A5 и C5). В этом случае необходимо выбрать пузырьковую диаграмму, содержащую два ряда. Используя возможности контекстного меню для диаграмм (области диаграммы, области построения, и так далее) создаем внешний вид диаграммы по своему вкусу, но обязательно нужно для оси Х минимальное и максимальное значение шкалы установить соответственно 0 и 10, отказавшись от режима «Авто» для этих параметров. Кроме того, необходимо убрать легенду и ось Y. Также можно на диаграмму поместить объект «Надпись» с соответствующим текстом. Другими словами, на данном этапе мы имеем богатые возможности для графического оформления задуманного проекта.

Теперь нужно написать программу, для того чтобы заставить шарики двигаться. Уже сейчас, меняя вручную значения координат шариков или их массы в расчетном блоке (строка 5 таблицы), можно заставить шарики перемещаться по диаграмме или графику или рисунку... (все зависит от оформления).

Шарики должны двигаться

Код будем писать под событие Click. Создаем управляющую (командную) кнопку. Заменим стандартное CommanButton1 íà

111

3. Проекты на VBA

Рис. 3.1. Фрагмент оформления таблицы

слово «Старт», также можно изменить стиль и цвет фона (BackStyle и BackColor), тип, размеры и цвет шрифта (Font и ForeColor).

При написании кода в первую очередь позаботимся о том, чтобы данные из ячеек ЭТ попали в переменные программы. Нам нужны начальные координаты шариков. Это ячейки E2 и F2 (строка 2, столбцы 5 и 6), поэтому две первые строчки будут выглядеть так

xxn1 = Cells(2, 5) xxn2 = Cells(2, 6)

Теперь определимся со скоростями. Начальные скорости расположены в ячейках B2 и D2. В программе мы их обозначим через переменные dx1 è dx2. Координату шарика через промежуток времени t мы будем вычислять в соответствии с известной формулой физики X=Xo+V*t. Полагаем t=1/10, и тогда dx = V/10. Получаем следующие две строчки

dx1 = Cells(2, 2) / 10 dx2 = Cells(2, 4) / 10

Очередные две строчки — это передача начальных координат в текущие координаты —переменные x1 è x2, которые будут использованы в цикле. Возможен вариант и более короткого кода, но мы для доступности сокращать не будем.

112

Моделирование физического процесса

x1 = xxn1

x2 = xxn2

Также нам в программе понадобятся и массы. Они располагаются в ячейках A2 и C2, поэтому

m1 = Cells(2, 1)

m2 = Cells(2, 3)

Теперь начинаем расчет в цикле до 100 раз. Принимаем, что увеличение счетчика на 1 — это увеличение времени на 1/10 с, то есть наблюдаем в течение 10 условных секунд, и при выбранных скоростях и расстояниях такое значение можно считать оптимальным.

For i = 1 To 100

Позаботимся, чтобы шарики не вылетали за стенки. Первый шарик не должен улететь налево и если он приблизился к левой стенке (ее координата равна 0), то его скорость должна поменяться по знаку. Кроме того, чтобы зрительно шарик не «влипал» в стенку, запретим ему приближаться к ней ближе, чем на 0,5. Поэтому

If x1 <= 0.5 Then dx1 = Abs(dx1)

Для второго шарика «опасна» правая стенка с координатой 10 и с учетом «влипания» получаем 9,5

If x2 >= 9.5 Then dx2 = –1 * Abs(dx2)

Следующий шаг — процесс соударения. Это когда первый шарик (левый) приблизился ко второму менее чем на 1(размеры шариков), то скорости шариков меняются в соответствии с формулами (1) и (2). Попутно заметим, что если мы работаем в системе метры — секунды, то шарики у нас — метровые гиганты. Такой вот бильярд или боулинг!!!

If x1 >= x2 – 1 Then

a = dx1 ' — это скорость V1 перед ударом,

dx1 = (dx1 * (m1 – m2) + 2 * dx2 * m2) / (m1 + m2) ' — ýòî óæå U1 dx2 = a + dx1 – dx2 ' — à ýòî óæå U2

End If

Итак, значения скорости тел в случае соударении со стенками или друг с другом определены, теперь находим новые координаты,

113

3. Проекты на VBA

а если таких событий не было, то тем более пора определить, где же будут шарики через очередные 1/10 с.

x1 = x1 + dx1

x2 = x2 + dx2

Теперь эти значения отправим в ЭТ, чтобы диаграмму изменить. А положение шариков в диаграмме определяется ячейками B и D в пятой строке.

Cells(5, 2) = x1

Cells(5, 4) = x2

Следующая строка кода очень важна. Эта строка дает возможность электронной таблице произвести перерасчет в соответствии с новыми данными, а также перестроить диаграмму (перевод команды — «делай события»)

DoEvents

Завершем цикл

Next i

И вообще

End Sub.

Полностью код выглядит следующим образом Private Sub CommandButton1_Click()

xxn1 = Cells(2, 5) xxn2 = Cells(2, 6) dx1 = Cells(2, 2) / 10 dx2 = Cells(2, 4) / 10 x1 = xxn1

x2 = xxn2

m1 = Cells(2, 1)

m2 = Cells(2, 3)

For i = 1 To 100

If x1 <= 0.5 Then dx1 = Abs(dx1)

If x2 >= 9.5 Then dx2 = –1 * Abs(dx2) If x1 >= x2 – 1# Then

a = dx1

dx1 = (dx1 * (m1 – m2) + 2 * dx2 * m2) / (m1 + m2) dx2 = a + dx1 – dx2

End If

114

Создание оригинальных тестов

x1 = x1 + dx1

x2 = x2 + dx2 Cells(5, 2) = x1 Cells(5, 4) = x2 DoEvents Next i

End Sub

Проверка программы

Проверить работу программы мы можем следующим образом — если массы тел равны, а скорости равны и противоположны по направлению, то получится симметричная картинка. Задаем нача- льные значения — массы по 5, скорости 5 и –5, начальные значе- ния — 2,5 и 7,5. Получаем достаточно знакомую картину соударения двух одинаковых шаров с одинаковыми скоростями.

Кроме того, во время работы программы можно заметить, что в ячейках пятой строки меняются значения. Это изменяются координаты шариков. Также можно вывести в какие-нибудь ячейки и значения скоростей. Таким образом, ячейки таблицы играют роль ячеек памяти и можно наблюдать за изменением значений переменных, что полезно для анализа работы программ или ее отладки.

Создание оригинальных тестов

Цель проекта

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

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

115

3. Проекты на VBA

слов не используется. В качестве предложения берем строку из одной песни, а проект так и назовем «Любимая песня»

План проекта

В нашем проекте будем использовать два рабочих листа — на одном будет происходить тестирование, работа, а другой лист — «Для служебного пользования», поэтому и дадим этим листам имена Worka и DSPA. На втором листе расположим сам вопрос, нужные и «мешающие» слова, вспомогательные сведения, иначе говоря, то, что нужно нам, но не пользователю.

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

Если каждое из предлагаемых слов размещать в каком-нибудь элементе управления, то тогда придется создавать достаточно большое, и к тому же еще заведомо неопределенное количество этих элементов, мало того, каждому элементу нужно свое имя и, следовательно, придется это разнообразие имен учитывать при написании кодов.

Лучше всего, если слова будут размещены в ячейках, а действия с этими словами будут производиться, если пользователь просто щелкнет по нему. Например, при щелчке по «правильному» слову, оно попадет в предложение, а если «кликнули» по «неправильному» слову, то в предложении появляются знаки вопросов. Для реализации подобного сценария необходимо использовать процедуру для события рабочего листа Private Sub Worksheet_ Selection Change(ByVal Target As Range), которая запускается, если пользователь изменил выделенную область ячеек. И оказывается, что эта процедура предполагает использовать переменную с именем Target, причем под этим именем как раз и будет прятаться выделенный диапазон ячеек

Работаем с ячейками

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

116

Создание оригинальных тестов

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

Эти два условия, первое из которых более значимо и проверяется отдельно в коде, записаны следующим образом

If Target.Count = 1 And flag Then

If Not Target = Empty Then

Напомним, что вместо привычного Range или Cells мы можем писать Target, потому что это и есть имя выделенного диапазона ячеек. По поводу переменной flag мы поговорим позже.

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

И чтобы окончательно разобраться с рабочим листом DSPA, там же напечатаем сам вопрос и текст небольшой справки.

Особенности программы

Еще одна задача, требующая решения — при нажатии на кнопку «Старт» разместить слова случайным образом в ячейках листа Worka. Тогда мы организуем цикл, в котором поочередно берется слово со служебного листа и помещается в ячейку, расположенную в y строке и x колонке. Значения x è y выбираются случайным образом, но так, чтобы они попали в заранее определенную нами область рабочего листа (a6:k17). Но такое размещение возможно, если эта ячейка не занята ранее, поэтому в коде должны быть строки, проверяющие занятость ячейки (If Cells(y, x) = Empty Then...). Если ячейка оказалась занятой, то размещения очередного слова не происходит, а счетчик цикла уменьшается на единицу, и мы опять ищем свободную ячейку для этого же слова.

После размещения слова в ячейке в код добавлено несколько строчек для украшения этой ячейки, и кроме того, в ячейке, рас-

117

3. Проекты на VBA

положенной на 100 строчек ниже размещаем порядковый номер этого слова (это необходимо для проверки ответа).

После размещения всех слов необходимо позаботиться о том, чтобы длинные слова, случайно оказавшиеся в соседних по горизонтали ячейках не наезжали друг на друга. С этой целью используется метод автовыравнивания столбцов — Columns(«a:k»).AutoFit.

Итак, тест начался. Человек нажал на кнопку «Старт», вопрос появился в одном месте экрана, другая область чиста, там со временем появится предложение. Выбрали нужное слово и щелкнули по нему. Процедура ...SelectionChange... проверила и убедилась, что выделена одна не пустая ячейка. В таком случае переменная list1 (порядковый номер слова в предложении) увеличивается на единицу и сравнивается с номером выбранного слова. Если выбор неверен, то в предложение добавляются знаки вопроса, а list1 уменьшается на единицу. В случае правильного выбора очередное слово добавляется к предложению и производится проверка на длину предложения. Если предложение завершено, то логическая переменная flag принимает значение false, а так как эта переменная проверяется в начале процедуры на истинность, то теперь указанная процедура работать не будет.

Если человек не понял, что надо делать, то достаточно нажать на кнопку в правой части листа и получить небольшую справку.

Полный код программы выглядит так

Public list1 As Integer, flag As

Объявление переменных

Boolean

 

 

 

Public a As String

 

 

 

Private Sub

 

CommandButton1_Click()

 

 

 

Range("a6:k17").Clear

Очищаем области от данных

 

 

Range("a99:k117").Clear

 

 

 

Lblvop.Caption =

Помещаем вопрос в Lblvop

Worksheets("dspa").Cells(1, 6)

 

 

 

list1 = 0

Подготовка переменных

 

 

flag = True

 

 

 

a = ""

 

 

 

 

 

118

 

Создание оригинальных тестов

 

 

 

 

Lblotv.Caption = ""

Готовим элемент управления для

 

ввода предложения

Lblotv.BorderColor = 0

 

DoEvents

Реализуем события рабочего листа

 

 

psl = Worksheets("dspa").Cells(1, 3)

Считываем количество слов

 

в предложении

For i = 1 To psl

Начинаем цикл для заполнения

 

рабочего листа словами

 

 

x = Int(Rnd * 10) + 1

Выбираем случайную ячейку

y = Int(Rnd * 10) + 7

 

If Cells(y, x) = Empty Then

Если она пуста

 

 

Cells(y, x) =

То помещаем туда очередное слово,

Worksheets("dspa").Cells(i, 2)

меняем шрифт, цвет фона

Cells(y, x).Interior.Color = vbYellow

и границы

 

 

 

Cells(y, x).Font.Size = 12

 

 

 

Cells(y, x).Font.Bold = True

 

Cells(y, x).Borders.Color = vbRed

 

 

 

Cells(y + 100, x) = i

Порядковый номер слова прячем

 

на100 строчек ниже

Else

А если ячейка не пуста

 

 

i = I — 1

Счетчик уменьшим на 1 и опяь

 

ищем ячейку

End If

 

Next

Переход к очередному слову

 

 

Columns("a:k").AutoFit

Автоподбор ширины столбца

End Sub

 

 

 

Private Sub

Процедура для вывод справки —

CommandButton2_Click()

сообщения

 

 

MsgBox

 

(Worksheets("dspa").Cells(3, 6))

 

 

 

End Sub

 

 

 

 

 

Private Sub

Процедура, запускаемая при

Worksheet_SelectionChange(ByVal

изменении выделенной области

Target As Range)

на рабочем листе

 

 

 

 

119

3. Проекты на VBA

If Target.Count = 1 And flag Then

Должна быть выделена только одна

If Not Target = Empty Then

и не пустая ячейка (при этом

flag=true)

 

list1 = list1 + 1

Порядковый номер слова в

 

предложении возрос на 1

x = Target.Column

Адрес выбранной ячейки в формате

y = Target.Row

строка—столбец

 

nom = Cells(y + 100, x)

Считывается номер выбранного

 

слова

If list1 nom Then

Если номера не совпадают

a = a + " " + "???"

То в предложение добавляем

 

вопросы

list1 = list1 — 1

И возвращаемся на исходные

 

позиции

Else

Иначе

a = a + " " + Target

В предложение добавляем

 

угаданное слово

Target = ""

Выделенную ячейку делаем пустой

If list1 = Worksheets("dspa").Cells(1,

И проверяем: не достигнут ли

4) Then

конец предложения

flag = False

Åñëè "äà" òî flag = False

Lblotv.BorderColor = vbBlue

Завершенное предложение

 

помещается в рамку

Range("a6:k17").Clear

А все лишние слова удаляются

End If

 

End If

 

Lblotv.Caption = a

В элемент Надпись помещается

 

предложение

End If

 

End If

 

End Sub

 

 

 

Развитие проекта

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

120