Выбрать главу

В нашем случае для создания такого типа достаточно записать выше процедур конструкцию:

Private Enum типРежим_работы_секундомера

считает

пауза

в_нуле

End Enum

Это не процедура, хоть и похожа. Слово Enum означает, что тип — перечислимый. Это означает, что мы обязаны были придумать и в этой конструкции перечислить имена всех возможных значений переменной этого типа, что мы и сделали. Поскольку каждый тип должен иметь свое имя (Integer, String…), нам тоже пришлось придумать имя новому типу (типРежим_работы_секундомера) и указать его в заголовке.

Теперь, когда новый тип определен, можно любую переменную объявить этим типом, что мы и делаем:

Dim Режим_работы_секундомера As типРежим_работы_секундомера

Замечание для новичков: Новички с трудом воспринимают смысл строк со стоящими рядом похожими именами, таких, например, как только что написанная. Новичку кажется, что эти имена означают одно и то же. Должен сказать, что профессиональные программисты специально обозначают близкие вещи похожими именами, им так больше нравится (можете себе вообразить?!). Например, у них может встретиться кнопка с именем сmdПодать_сюда_Ляпкина_Тяпкина и в этом же проекте переменная с именем strПодать_сюда_Ляпкина_Тяпкина. Для того, чтобы отличать одно от другого, они начинают каждое имя с префикса, который говорит программисту (не компьютеру!) о том, кому принадлежит имя (кнопке (префикс cmd), строковой переменной (префикс str) или кому-нибудь другому). Со временем вы поймете неизбежность такого подхода, а пока вам придется быть внимательным и не путать близкие имена.

Делаем секундомер

Поместим на форму элементы управления и дадим им имена:

Таймер_секундомера Циферблат_секундомера Кнопка_пуска_паузы_секундомера Кнопка_обнуления_секундомера а также не забудем метку и рамочку.

Будем использовать следующие переменные:

Dim Режим_работы_секундомера As типРежим_работы_секундомера

Dim Время_на_секундомере As Single

Dim Время_запуска_секундомера As Single

Dim Время_на_паузе_секундомера As Single

Dim Цифра_десятых As Long

Обратите внимание, что все переменные времени объявлены, как дробные числовые, а не как Date. Сейчас вам станет ясно, почему.

Давайте по порядку. Таймер нужен секундомеру для того же, для чего и часам, а именно — чтобы вовремя менялись цифры на циферблате, а собственный таймер нужен для того, чтобы не зависеть от часов. Поскольку нам нужно отслеживать десятые доли секунды, установим ему интервал поменьше, например 10 или 5 — не играет роли. Когда секундомер считает, таймер секундомера должен работать: Таймер_секундомера. Enabled = True

а когда он в паузе или в нуле, таймер должен стоять Таймер_секундомера. Enabled = False

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

Засечем в момент пуска секундомера значение функции Timer оператором Время_запуска_секундомера = Timer

Тогда в каждый момент времени после запуска секундомера выражение (Timer — Время_запуска_секундомера) как раз и будет равняться числу секунд, прошедших с момента запуска секундомера. А если нам удастся правильно засечь Время_на_паузе_секундомера (выраженное в секундах, прошедших с момента пуска), то дело решит оператор

Время_на_секундомере = (Timer — Время_запуска_секундомера) + Время_на_паузе_секундомера

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

Теперь займемся внешним видом показаний секундомера. Время_на_секундомере — это дробное число — количество секунд. Например, такое — 67,2. А нам хотелось бы получить его в таком виде — 00:01:07.2. Для этого нам нужно как-то преобразовать число секунд в стандартный формат времени. Дело решает оператор:

Циферблат_секундомера.Text = DateAdd ("s", Время_на_секундомере, #12:00:00 AM#)

Здесь время #12:00:00 AM# обозначает, как ни странно, полночь по-американски. Задача решена.

Но функция DateAdd оставляет за бортом десятые доли секунды. Попробуем выделить их из числа Время_на_секундомере. Для этого мысленно проведем такую цепочку операций с использованием функции Int: