Excel. Трюки и эффекты Гладкий Алексей
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
' Верхние границы
With Selection.Borders(xlEdgeTop)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
' Нижние границы
With Selection.Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
' Вертикальные границы между ячейками
With Selection.Borders(xlInsideVertical)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
' Горизонтальные границы между ячейками
With Selection.Borders(xlInsideHorizontal)
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = xlAutomatic
End With
End Sub
Sub DisplayGrid()
' Включение сетки на листе
ActiveWindow.DisplayGridlines = True
End Sub
Sub HideGrid()
' Выключение сетки на листе
ActiveWindow.DisplayGridlines = False
End Sub
Sub AutoNumber()
' Нумерация клеток, являющихся началом слов
Dim intRow As Integer ' Текущая строка
Dim intCol As Integer ' Текущий ряд
Dim cell As Range ' Текущая ячейка (с координатами _
(intRow, intCol))
Dim fTop As Boolean ' = True, если cell имеет соседей сверху
Dim fBottom As Boolean ' = True, если cell имеет соседей снизу
Dim fLeft As Boolean ' = True, если cell имеет соседей слева
Dim fRight As Boolean ' = True, если cell имеет соседей справа
Dim intDigit As Integer ' Текущий номер слова в кроссворде
intDigit = 1 ' Нумерация слов с 1
' Проходим по всем клеткам диапазона, используемого _
для кроссворда, сверху вниз слева направо и анализируем _
каждую угловую и крайнюю (левую и верхнюю) ячейки
For intRow = dhcMinRow To dhcMaxRow
For intCol = dhcMinCol To dhcMaxCol
' Текущая ячейка
Set cell = Cells(intRow, intCol)
' Проверка, входит ли ячейка в кроссворд (по ее цвету)
If cell.Interior.ColorIndex = 35 Then
fLeft = False
fRight = False
fTop = False
fBottom = False
On Error Resume Next
' Определение наличия соседей у ячейки...
' сверху
fTop = cell.Offset(-1, 0).Interior.ColorIndex = 35
' снизу
fBottom = cell.Offset(1, 0).Interior.ColorIndex = 35
' слева
fLeft = cell.Offset(0, -1).Interior.ColorIndex = 35
' справа
fRight = cell.Offset(0, 1).Interior.ColorIndex = 35
On Error GoTo 0
' Анализ положения ячейки
If (Not fTop And Not fLeft) Or _
(Not fBottom And Not fLeft And fRight) Or _
(Not fLeft And fRight) Or _
(Not fTop And fBottom) Then
' Ячейка подходит для начала слова
SetDigit intDigit, cell
intDigit = intDigit + 1
End If
End If
Next intCol
Next intRow
End Sub
Sub SetDigit(intDigit As Integer, cell As Range)
' Вставка цифры intDigit в ячейку, заданную параметром cell
cell.Value = intDigit
' Изменение настроек шрифта так, чтобы было похоже _
на настоящий кроссворд
' Маленький размер шрифта
cell.Font.Size = 6
' Выравнивание текста по левому верхнему углу ячейки
cell.HorizontalAlignment = xlLeft
cell.VerticalAlignment = xlTop
End Sub
Sub ToPrint()
' Удаление цветовой подсветки кроссворда
Cells.Interior.ColorIndex = xlNone
End Sub
Sub ToNumber()
' Закрытие первой формы и переход ко второй
UserForm1.Hide
UserForm2.Show
End Sub
Листинг 5.1 состоит из девяти макросов (семь первых можно запускать вручную):
• DrowCrosswordGrid – рисует сетку кроссворда для выделенных ячеек;
• Clear – удаляет кроссворд с рабочего листа;
• Clear Grid – удаляет рамку кроссворда в выделенных ячейках;
• AutoNumber – записывает номера в ячейки кроссворда;
• DisplayGrid – показывает сетку рабочего листа;
• Hide Grid – убирает сетку рабочего листа;
• ToPrint – удаляет цветовую подсветку ячеек кроссворда;
• SetDigit – помещает нужное число в указанную ячейку (этот макрос используется макросом AutoNumber для записи номеров в ячейки);
• ToNumber – переход от основной формы ко второй форме (см. ниже).
Вызывать все эти макросы вручную довольно неудобно. Их можно запускать посредством элементов управления, которые можно поместить прямо на рабочий лист или на пользовательскую форму. О создании пользовательской формы рассказывается в следующем подразделе.
Создание пользовательских форм
Для создания основной формы программы необходимо воспользоваться вкладкой Разработчик, отображение которой включается в настройках программы в разделе Основные с помощью флажка Показывать вкладку «Разработчик» на ленте. На данной вкладке нужно по обычным правилам создать форму, изображенную на рис. 5.1.
Рис. 5.1. Первая форма программы
К элементам формы привяжем макросы (все привязываемые макросы входят в состав кода, который приведен выше, и доступны в окне выбора макросов):
• переключатель Сетка присутствует– макрос DisplayGrid;
• переключатель Сетка на поле отсутствует – макрос HideGrid;
• кнопка Новый кроссворд – макрос Clear;
• кнопка Нарисовать рамку – макрос DrawCrasswordGrid;
• кнопка Стереть рамку – макрос ClearGrid;
• кнопка Дальше – макрос ToNumber.
Теперь аналогичным образом (с помощью вкладки Разработчик) создадим еще одну форму, которая показана на рис. 5.2.
К элементам данной формы привяжем следующие макросы (они также присутствуют в коде и доступны в окне выбора макросов):
• кнопка Автонумерация – макрос AutoNumber;
• кнопка Очистить все – макрос Clear;
• кнопка Вывести на печать – макрос ToPrint.
Следует отметить, что можно не создавать пользовательские формы, а размещать все элементы управления прямо на рабочем листе. Если так поступить, то кнопка Далее в первой (главной) форме становится ненужной.
Рис. 5.2. Вторая форма программы
Итак, у нас все готово для составления кроссвордов. О порядке использования программы рассказывается в следующем подразделе.
Порядок использования программы
С помощью созданной программы можно быстро составлять и нумеровать сетку кроссворда. Рассмотрим конкретный пример.
На листе создадим несколько выделенных областей, соединив их между собой (рис. 5.3).
Рис. 5.3. Выделение нескольких областей
Теперь нажмем кнопку Нарисовать рамку – результат представлен на рис. 5.4.
Рис. 5.4. Рамка кроссворда
Нажимаем кнопку Дальше – будет отображена вторая форма программы (см. рис. 5.2). В этой форме следует нажать кнопку Автонумерация – в результате сетка кроссворда будет быстро пронумерована (рис. 5.5).
Теперь нажимаем кнопку Вывести на печать – и на листе отобразится готовая сетка кроссворда (рис. 5.6).
С помощью кнопки Очистить все с листа удаляется рамка кроссворда.
Рис. 5.5. Нумерация сетки кроссворда
Кнопка Стереть рамку, которая находится на главной форме, позволяет удалить всю рамку (для этого ее нужно выделить) либо ее выделенный фрагмент.
При нажатии кнопки Новый кроссворд удаляется все содержимое документа, после чего можно приступать к составлению нового кроссворда.
Рис. 5.6. Готовая сетка кроссворда
Игра «Минное поле»
Пользователям Windows известно, что в комплект поставки операционной системы входит несколько игр, в том числе Сапер. Однако не многие знают, что подобную игру можно создать самостоятельно в Excel, используя механизм макросов.
Игра «Минное поле», о которой рассказывается в данном разделе, во многом аналогична стандартной игре Сапер. Для создания игры необходимо написать несколько макросов, объединенных в два кода: первый код должен быть помещен в модуль того рабочего листа, на котором предполагается разместить игру, а второй – в стандартный модуль.
В модуль рабочего листа необходимо поместить такой код (листинг 5.2).
Листинг 5.2. Код в модуле рабочего листа
Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim intCol As Integer, intRow As Integer
Dim intMinesAround As Integer
Dim fInGameField As Boolean
' Определим, попадает ли в игровое поле выделенная ячейка
fInGameField = (Target.Row >= 2) And (Target.Row <= 7) _
And (Target.Column >= 2) And (Target.Column <= 7)
' Обрабатываем выделение ячейки
If Target.Value = "*" And fInGameField Then
' Пользователь выделил ячейку с миной – покажем мину
Target.Font.Color = RGB(0, 0, 0)
Target.Interior.Color = RGB(255, 0, 0)
' Пользователь проиграл!
EndGame
ElseIf fInGameField Then
' Пользователь выделил пустую ячейку. Оформим эту ячейку
Target.Interior.Color = RGB(0, 0, 255)
Target.Font.Color = RGB(0, 255, 0)
Target.Font.Size = 16
' Подсчитаем количество мин рядом с ячейкой (вокруг ячейки)
For intCol = Target.Column – 1 To Target.Column + 1
For intRow = Target.Row – 1 To Target.Row + 1
If Target.Worksheet.Cells(intRow, intCol).Value =
"*" _
Then
' Нашли очередную мину
intMinesAround = intMinesAround + 1
End If
Next
Next
' Отображение количества мин
Target.Value = intMinesAround
End If
End Sub
Код, который должен находиться в стандартном модуле, выглядит следующим образом (листинг 5.3).
Листинг 5.3. Код в стандартном модуле
Sub NewGame()
' Начало новой игры
' Подготовим поле для игры
InitGame
Dim intRow As Integer, intCol As Integer
Dim intMinesCount As Integer ' Количество мин
' Расставляем мины (то есть в случайные ячейки помещаем _
значения "*" и делаем цвет шрифта таким же, как цвет _
фона этих ячеек)
For intMinesCount = 1 To 10
' Строка для мины (от 2 до 7)
intRow = Int((6 * Rnd) + 1) + 1
' Столбец для мины (от 2 до 7)
