Выпадающий календарь для ввода дат в Word. Часть 1: Простой календарь
Материал из Календарь событий
Из этой статьи вы узнаете, как создать выпадающий календарь в Word с помощью Visual Basic for Application (VBA). Календарь будет создаваться в Word 2007, но вы можете использовать и другие версии.
Откройте пустой документ Word. Далее откройте окно редактора Visual Basic, нажав на клавиши ALT+F11, либо выбрав пункт меню "Visual Basic" на вкладке "Разработчик" (по умолчанию эта вкладка скрыта от пользователей; чтобы отобразить её, в главном меню выберите "Параметры Word"->"Основные" и поставьте галочку у пункта Показывать вкладку "Разработчик" на ленте).
В окне Project (обычно располагается в левом верхнем углу) выберите документ, в котором вы будете строить календарь.
Вы можете создать календарь в глобальном шаблоне Normal.dot. Он загружается каждый раз, когда вы открываете Word, а, следовательно, календарь всегда будет доступен для вас. Если вы планируете распространять календарь среди других пользователей, лучше создать его в новом, пустом документе, который может быть позже сохранен как шаблон.
Вам необходимо вставить форму, на которой будет располагаться календарь. Для этого в меню "Insert" выберите пункт "UserForm". Перед вами появится пустая форма.
Окно Properties (как правило, оно располагается в левом нижнем углу; если его нет, отобразите его через пункт меню "View"->"Properties Window") предназначено для отображения свойств выделенных объектов. Как видите, окно состоит из двух колонок: в первой располагаются названия свойств, а во второй их значения. Для того чтобы изменить свойство нужно нажать на его название/значение, а потом:
- Ввести новое значение вручную
- Выбрать из списка
- Нажать на кнопку […] и изменять значения в появившемся дополнительном окне.
Для отображения свойств формы, необходимо выделить её (например, щёлкнув по ней мышкой).
Изменим следующие свойства нашей формы:
Name: frmCalendar (задаёт имя формы, через которое мы будет обращаться к ней посредством VBA)
Caption: Выберите дату (задаёт название в шапке формы)
Добавим теперь на нашу форму календарь. Отобразите панель инструментов через пункт меню "View"->"Toolbox". На панели инструментов располагаются элементы, которые вы можете разместить на вашей форме. Как правило, по умолчанию, на панели инструментов отсутствует элемент для создания календаря. Если это так, выберите пункт меню "Tools"->"Additional Controls" и поставьте галочку у элемента "Календарь 12.0" ("Calendar Control 12.0"; для разных версий Word версия календаря может отличаться).
Теперь, когда календарь появился на панели инструментов, выберите его и нажмите на форме.
Изменим внешний вид добавленного календаря. Для этого выделим его и в окне Properties вначале нажмём на поле Custom, а затем на кнопку […], тем самым открыв дополнительное окно. В нём уберём галочку со свойства "заголовок месяца и года", а первым днём недели поставим понедельник (вы можете изменять свойства календаря по вашему желанию).
Аналогичным образом изменим другие свойства календаря:
DayFont: Размер: 8; Начертание: Обычный
GridFont: Размер: 8
Сделаем календарь и форму более компактными, изменив их размер (потянув за белые маркеры, появляющиеся при выделении календаря и формы).
Посмотреть на то, как работает ваш календарь, вы можете, нажав клавишу F5. Но на данный момент, он ещё ничего не умеет делать. Сделаем для начала так, чтобы пользователь мог закрыть календарь, нажав на клавишу Esc. Выберите элемент CommandButton на панели инструментов и поместите его на форме, после чего установите следующие свойства:
Name: cmdClose
Cancel: True (если данное свойство установить в true, нажатие клавиши Esc будет эквивалентно нажатию на саму кнопку)
Дважды щелкните по вашей кнопке (или нажмите клавишу "F7") и между появившихся строк добавьте Unload Me. В итоге у вас должно получиться:
Private Sub cmdClose_Click() Unload Me End Sub
Рассмотрим этот код подробнее: мы добавили процедуру, которая будет вызываться при нажатии мышкой на кнопку (фактически же, так как кнопка спрятана за календарём и свойство Cancel имеет значение true, вызов будет происходить при нажатии клавиши Esc). В теле процедуры команда Unload Me приводит к закрытию нашей формы с календарём. Можете протестировать календарь и убедиться, что всё работает. Теперь сделаем так, чтобы при выборе даты в календаре она добавлялась в документ. Выделите календарь, выбрав его на форме, либо через выпадающий список в окне Properties, после чего щёлкните по нему два раза, тем самым создав процедуру Calendar1_Click.
Впишите в неё следующий код
Selection.Text = Format(Calendar1.Value, "dd mmmm yyyy")
Selection.MoveRight Unit:=wdCharacter, Count:=1
Unload MeУ вас должно получиться:
Private Sub Calendar1_Click() Selection.Text = Format(Calendar1.Value, "dd mmmm yyyy") Selection.MoveRight Unit:=wdCharacter, Count:=1 Unload Me End Sub
Через Calendar1.Value мы получаем выбранную дату, после чего преобразуем её в формат "dd mmmm yyyy" (например, "15 июля 2010"). Полученное значение вставляется в документ через свойство Text объекта Selection (если перед вставкой даты был выделен текст, то она заменит его, иначе дата будет вставлена на место курсора). Строка Selection.MoveRight Unit:=wdCharacter, Count:=1 снимает выделение с вставленной даты и перемещает курсор в её конец. После вставки даты окно закрывается. Можете протестировать ваш календарь.
Сделаем так, что если перед запуском календаря, в нашем тексте была выделена дата, то она будет автоматически установлена в качестве текущей даты календаря. Следовательно, нам необходимо добавить процедуру, которая бы выполнялась каждый раз при запуске календаря. Перейдите в окно с кодом и в левом верхнем списке выберите UserForm, а в правом Initialize (тем самым вы добавите новую процедуру UserForm_Initialize)
Напишите в процедуре следующий код:
Private Sub UserForm_Initialize() If IsDate(Selection.Text) Then Calendar1.Value = DateValue(Selection.Text) Else Calendar1.Value = Date End If End Sub
Данная процедура будет вызываться при каждом запуске календаря. В ней проверяется, является ли выделенный фрагмент датой. В случае положительного результата эта дата устанавливается текущей в календаре. В обратном случае берётся текущая дата. Сейчас наш календарь мы можем запускать только из редактора Visual Basic. Сделаем так, чтобы он был доступен в любом документе, созданном на основе нашего шаблона. Для этого необходимо добавить в наш проект модуль через пункт меню "Insert"->"Module". Щёлкните два раза по созданному модулю в окне Project и в появившемся окне кода напишите следующее:
Sub OpenCalendar() frmCalendar.Show End Sub
Теперь вы можете запускать ваш календарь прямо из Word (не забудьте сохранить его через "File"->"Save (имя документа)"). Для этого во время работы с документом нажмите клавиши Alt+F8, либо выберите пункт меню "Макросы" на вкладке "Разработчик". Выбрав ваш макрос (OpenCalendar), нажмите "Выполнить". Если календарь работает, значит, вы всё сделали правильно.
Содержание |
Добавление дополнительных возможностей
1) Назначение горячих клавиш.
Щелкните два раза в окне Project на ThisDocument вашего документа. В открывшемся окне кода выберите в левом списке Document, а в правом Open, после чего добавьте в процедуру Document_Open следующий код:
CustomizationContext = NormalTemplate
KeyBindings.Add KeyCode:=BuildKeyCode(wdKeyControl, _
wdKeyShift, wdKeyC), KeyCategory:=wdKeyCategoryMacro, _
Command:=" OpenCalendar"Примечание: Знак подчёркивания используется для разбиения слишком длинной строки.
С помощью этого кода мы сделали возможным запускать наш календарь по нажатию на клавиши Ctrl+Shift+C. Эти клавиши задаются строкой BuildKeyCode(wdKeyControl, wdKeyShift, wdKeyC).
| Полный список клавиш | ||
|---|---|---|
| Ключевое слово | Клавиша | Код клавиши |
| wdKey0 | 0 | 48 |
| wdKey1 | 1 | 49 |
| wdKey2 | 2 | 50 |
| wdKey3 | 3 | 51 |
| wdKey4 | 4 | 52 |
| wdKey5 | 5 | 53 |
| wdKey6 | 6 | 54 |
| wdKey7 | 7 | 55 |
| wdKey8 | 8 | 56 |
| wdKey9 | 9 | 57 |
| wdKeyA | A | 65 |
| wdKeyAlt | Alt | 1024 |
| wdKeyB | B | 66 |
| wdKeyBackSingleQuote | ` | 192 |
| wdKeyBackSlash | \ | 220 |
| wdKeyBackspace | Backspace | 8 |
| wdKeyC | C | 67 |
| wdKeyCategoryAutoText | 4 | |
| wdKeyCategoryCommand | 1 | |
| wdKeyCategoryDisable | 0 | |
| wdKeyCategoryFont | 3 | |
| wdKeyCategoryMacro | 2 | |
| wdKeyCategoryNil | ||
| wdKeyCategoryPrefix | 7 | |
| wdKeyCategoryStyle | 5 | |
| wdKeyCategorySymbol | 6 | |
| wdKeyCloseSquareBrace | ] | 221 |
| wdKeyComma | , | 188 |
| wdKeyCommand | ⌘ | 512 |
| wdKeyControl | Ctrl | 512 |
| wdKeyD | D | 68 |
| wdKeyDelete | Delete | 46 |
| wdKeyE | E | 69 |
| wdKeyEnd | End | 35 |
| wdKeyEquals | = | 187 |
| wdKeyEsc | Esc | 27 |
| wdKeyF | F | 70 |
| wdKeyF1 | F1 | 112 |
| wdKeyF10 | F10 | 121 |
| wdKeyF11 | F11 | 122 |
| wdKeyF12 | F12 | 123 |
| wdKeyF13 | F13 | 124 |
| wdKeyF14 | F14 | 125 |
| wdKeyF15 | F15 | 126 |
| wdKeyF16 | F16 | 127 |
| wdKeyF2 | F2 | 113 |
| wdKeyF3 | F3 | 114 |
| wdKeyF4 | F4 | 115 |
| wdKeyF5 | F5 | 116 |
| wdKeyF6 | F6 | 117 |
| wdKeyF7 | F7 | 118 |
| wdKeyF8 | F8 | 119 |
| wdKeyF9 | F9 | 120 |
| wdKeyG | G | 71 |
| wdKeyH | H | 72 |
| wdKeyHome | Home | 36 |
| wdKeyHyphen | - | 189 |
| wdKeyI | I | 73 |
| wdKeyInsert | Insert | 45 |
| wdKeyJ | J | 74 |
| wdKeyK | K | 75 |
| wdKeyL | L | 76 |
| wdKeyM | M | 77 |
| wdKeyN | N | 78 |
| wdKeyNumeric0 | 0 (на цифровой клавиатуре) | 96 |
| wdKeyNumeric1 | 1 (на цифровой клавиатуре) | 97 |
| wdKeyNumeric2 | 2 (на цифровой клавиатуре) | 98 |
| wdKeyNumeric3 | 3 (на цифровой клавиатуре) | 99 |
| wdKeyNumeric4 | 4 (на цифровой клавиатуре) | 100 |
| wdKeyNumeric5 | 5 (на цифровой клавиатуре) | 101 |
| wdKeyNumeric5Special | 5 (на цифровой клавиатуре с выключенным NumLock) | 12 |
| wdKeyNumeric6 | 6 (на цифровой клавиатуре) | 102 |
| wdKeyNumeric7 | 7 (на цифровой клавиатуре) | 103 |
| wdKeyNumeric8 | 8 (на цифровой клавиатуре) | 104 |
| wdKeyNumeric9 | 9 (на цифровой клавиатуре) | 105 |
| wdKeyNumericAdd | + (на цифровой клавиатуре) | 107 |
| wdKeyNumericDecimal | . (на цифровой клавиатуре) | 110 |
| wdKeyNumericDivide | / (на цифровой клавиатуре) | 111 |
| wdKeyNumericMultiply | * (на цифровой клавиатуре) | 106 |
| wdKeyNumericSubtract | - (на цифровой клавиатуре) | 109 |
| wdKeyO | O | 79 |
| wdKeyOpenSquareBrace | [ | 219 |
| wdKeyOption | option | 1024 |
| wdKeyP | P | 80 |
| wdKeyPageDown | PageDown | 34 |
| wdKeyPageUp | PageUp | 33 |
| wdKeyPause | Pause | 19 |
| wdKeyPeriod | . | 190 |
| wdKeyQ | Q | 81 |
| wdKeyR | R | 82 |
| wdKeyReturn | Enter | 13 |
| wdKeyS | S | 83 |
| wdKeyScrollLock | ScrollLock | 145 |
| wdKeySemiColon | ; | 186 |
| wdKeyShift | Shift | 256 |
| wdKeySingleQuote | ’ | 222 |
| wdKeySlash | / | 191 |
| wdKeySpacebar | Пробел | 32 |
| wdKeyT | T | 84 |
| wdKeyTab | Tab | 9 |
| wdKeyU | U | 85 |
| wdKeyV | V | 86 |
| wdKeyW | W | 87 |
| wdKeyX | X | 88 |
| wdKeyY | Y | 89 |
| wdKeyZ | Z | 90 |
Было бы логичным удалять действие клавиш при закрытии программы. Для этого создадим в ThisDocument процедуру Document_Close и запишем в неё следующий код:
CustomizationContext = NormalTemplate
KeyBindings.Key(KeyCode:=BuildKeyCode(wdKeyControl, _
wdKeyShift, wdKeyC)).Clear
2) Добавление элемента в контекстное меню (по нажатию правой кнопки мыши)
Для того, чтобы реализовать это, добавим в уже созданную функцию Document_Open следующий код:
Dim NewControl As CommandBarControl Set NewControl = Application.CommandBars("Text").Controls.Add With NewControl .Caption = "Вставить дату" .OnAction = "OpenCalendar" .BeginGroup = True End With
Здесь мы добавляем новый пункт в контекстное меню и устанавливаем его свойства (Caption - название меню; OnAction - процедура, которая будет выполнятся при выборе меню; BeginGroup - отделение пункта меню от остальных разделительной линией).
Таким образом у нас получится:
Private Sub Document_Open() CustomizationContext = NormalTemplate KeyBindings.Add KeyCode:=BuildKeyCode(wdKeyControl, _ wdKeyShift, wdKeyC), KeyCategory:=wdKeyCategoryMacro, _ Command:="OpenCalendar" Dim NewControl As CommandBarControl Set NewControl = Application.CommandBars("Text").Controls.Add With NewControl .Caption = "Вставить дату" .OnAction = "OpenCalendar" .BeginGroup = True End With End Sub
Для удаления элемента, перед закрытием документа, добавим в процедуру Document_Close код:
Application.CommandBars("Text").Controls("Вставить дату").Delete
В итоге получим:
Private Sub Document_Close() CustomizationContext = NormalTemplate KeyBindings.Key(KeyCode:=BuildKeyCode(wdKeyControl, _ wdKeyShift, wdKeyC)).Clear Application.CommandBars("Text").Controls("Вставить дату").Delete End Sub
В случае, если у вас появилось много одинаковых пунктов меню, значит ваш код работает не правильно. Как правило, это происходит из-за того, что вы забыли добавить удаление пункта меню или указали неправильное имя, или просто сделали опечатку. В этом нет ничего страшного. Просто откройте в редакторе Visual Basic окно Immediate Window (через меню "View" или с помощью клавиш Ctrl + G).
Immediate Window имеет множество применений, одним из которых является возможность выполнить строку кода, просто набрав его в окне и нажав клавишу ввода. Введите в Immediate Window строку:
Application.CommandBars("Text").Controls("Вставить дату").Delete
а затем нажмите клавишу Enter. Одна копия пункта меню должна была после этого исчезнуть. Повторите эту процедуру столько раз, сколько необходимо, чтобы удалить все нежелательные экземпляры. После чего найдите ошибку в вашем коде и исправьте её.
Установка календаря
После того как мы сделали шаблон, было бы не плохо, чтобы Word автоматически загружал его (если вы создавали календарь в глобальном шаблоне Normal, он будет загружаться в любом случае). По умолчанию, Word при запуске загружает все шаблоны из папки STARTUP. Посмотреть, где находится эта папка (а также изменить её), можно через главное меню, выбрав пункт "Параметры Word"->"Дополнительно"->"Общие"->"Расположение файлов". Для того чтобы ваш календарь был доступен при открытии документа, вам необходимо просто скопировать ваш шаблон в эту папку. Стоит упомянуть о том, что редактировать шаблон, используя VBA, в этой папке невозможно.
Файлы
Выпадающий календарь для Word 97: WordPopupCalendar_v97.zip
Выпадающий календарь для Word 2000: WordPopupCalendar_v2000.zip
Выпадающий календарь для Word 2002: WordPopupCalendar_v2002.zip
Выпадающий календарь для Word 2007: WordPopupCalendar_v2007.zip










