Paul Cornell and Frank C. Rice
Microsoft Corporation
February 2003
対象 :
MicrosoftR Office XP
概要 : いくつかの Office アプリケーションのヒントを学び、サンプル コードを使用します。これらのヒントによって、生産性が向上し、また独自のツール、ユーティリティ、および技法を開発する第一歩となります。
目次
タイトル バーで Word 文書の統計情報を更新する
プログラムで Outlook のルールを作成する
Word 文書の至るところで繰り返される文字列を削除する
1 つ以上の Excel スプレッドシートのセルの値に基づいてマクロを実行する
ユーザーが入力コントロールをクリックした後に PowerPoint スライドの関連コントロールを無効にする
ユーザーが Office ドキュメントを開くときに注意情報を表示する
Access メイン フォームとサブフォームを相互に同期する
ワークシートの変更を XML ファイルにログ記録する
複数の Outlook 電子メール メッセージからの本文の文字列を 1 つの Word 文書にマージする
ユーザー入力の表示と取得に代替策として Office アシスタントを使用する
タイトル バーで Word 文書の統計情報を更新する
実行している文書の合計統計数を MicrosoftR Word のタイトル バーに表示できます。 これにより、[ツール] メニューの [文字カウント] をクリックするより簡単に、結果をより明確に表示できます。
ドキュメントの合計統計数をタイトル バーに表示するには、以下の手順に従います。
作業中の文書の ThisDocument プロジェクトに新しいクラス モジュールを作成し、clsWordApp という名前を付けます。
以下のコードを
clsWordAppクラス モジュールに挿入します。Public WithEvents appWord As Word.Application Private Sub appWord_WindowSelectionChange(ByVal Sel As Selection) Application.ActiveWindow.Caption = _ "単語数 : " & Application.ActiveDocument.Words.Count & _ " / 文字数 : " & Application.ActiveDocument.Characters.Count End Sub以下のコードを作業中の文書の ThisDocument プロジェクトに挿入します。
Dim woApp As New clsWordApp Private Sub Document_Open() Set woApp.appWord = Word.Application End Subドキュメントを閉じて、再度開きます。
現在の選択部分を変更します。このコード例を使用すると、 文書の単語数と文字数が、タイトル バーで更新されます。
.gif)
図 1. Word 文書のタイトル バーに表示された単語数と文字数
プログラムで Outlook のルールを作成する
Microsoft OutlookR の [受信トレイ] で新しい電子メール メッセージを受信すると必ず、 自動的に Application_NewMail イベントが発生します。 新しい電子メール メッセージに対して自動的なアクションを作成するには、 [自動仕訳ウィザード] ([ツール] メニュー) を使用できます。 Outlook が [自動仕訳ウィザード] よりも複雑なアクションを実行するように設定するには、 Outlook オブジェクト モデルに基づいたコードを使用してアクションを作成し、 VbaProject.OTM プロジェクトの ThisOutlookSession モジュールの Application_NewMail イベントに、 作成したコードを配置します。
簡単な例として、以下のコードを使用すると、"XXX" という文字列を件名行に含むすべての電子メール メッセージを、[削除済みアイテム] フォルダに送信します。
' 目的 : 件名行に "XXX" という文字列を含む電子メール メッセージを
' [削除済みアイテム] フォルダに直接送信します。
Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace
Dim olFld As Outlook.MAPIFolder
Dim oMail As Outlook.MailItem
Set olApp = Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
Set olFld = olNS.GetDefaultFolder(olFolderInbox)
olFld.Items.Sort "Received", False
Set oMail = olFld.Items.GetFirst
If InStr(1, LCase(oMail.Subject), "xxx") > 0 Then
oMail.Delete
End If
Set oMail = Nothing
Set oFld = Nothing
Set oNS = Nothing
Set olApp = Nothing
上記のコードを Outlook プロジェクトに追加するには、以下の手順に従います。
- Outlook を起動します。
- [ツール] メニューの [マクロ] をクリックし、[Visual Basic Editor] をクリックします。
- プロジェクト エクスプローラで、[ThisOutlookSession] をダブルクリックします。
- コード ウィンドウをクリックし、[オブジェクト] ボックスで [Application] をクリックし、[プロシージャ] ボックスで [NewMail] をクリックします。
Application_NewMailイベント プロシージャに、上記のコードをコピーして貼り付けます。- [Visual Basic Editor] を閉じます。
- この手順を確認するには、 自分自身に件名に "XXX" という文字列を含むメッセージを送信するか、 他の人に送信してもらいます。 メッセージを受信した後は、[削除済みアイテム] フォルダにメッセージが削除されていることを確認します。
Word 文書の至るところで繰り返される文字列を削除する
場合によっては、文書の至るところに表示される文字列を削除できる機能があると便利です。 たとえば、製品をベータ版のテストからリリース版に移行する場合、 おそらく販売文書から "ベータ版" という文字列をすべて削除することになるでしょう。 この作業を 1 つのボタンをクリックして行うことができれば、 さらに便利になるでしょう。 以下のプロシージャを使用すると、これらの両方の作業を Word 内で行うことが可能になります。 1 つ目のルーチンでは、クリックするツール バーとボタンを作成し、2 つ目のプロシージャを呼び出します。 2 つ目のプロシージャは、Word 文書の至るところで繰り返される文字列を、[検索と置換] ダイアログ ボックスを使用しないで削除します。 この機能は、複数の文書で文字列を削除する場合に、 各文書で [検索と置換] ダイアログ ボックスを設定する必要がないので便利です。
Private Sub Document_Open()
' 目的 : 文字列を削除するツールバーを作成します。
Dim objCommandBar As Office.CommandBar
Dim objCommandBarButton As Office.CommandBarButton
For Each objCommandBar In Application.CommandBars
If objCommandBar.Name = "Remove Repeating Text" Then
objCommandBar.Delete
End If
Next objCommandBar
Set objCommandBar = Application.CommandBars.Add _
("Remove Repeating Text")
' このツールバーを削除するには、次のアプリケーションを呼び出します。
' Application.CommandBars("Remove Repeating Text").Delete
' コマンド ボタン コントロールをこのツールバーに追加します。
With objCommandBar.Controls
Set objCommandBarButton = .Add(msoControlButton)
With objCommandBarButton
.Caption = "&Zap Repeating Text"
.FaceId = 59
.Style = msoButtonIconAndCaption
.TooltipText = _
"指定した繰り返し文字列を削除します。"
.OnAction = "RemoveText"
End With
End With
objCommandBar.Visible = True
End Sub
Private Sub RemoveText()
' 目的 : Word 文書内で繰り返される文字列を削除します。
Dim strTextToFind As String
strTextToFind = Trim(InputBox("削除する文字列を入力してください。" & _
"単独の文字列のみ削除されます。"))
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = strTextToFind
.Replacement.Text = ""
.Wrap = wdFindContinue
.Format = False
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
MsgBox "文字列" & _
strTextToFind & "はすべて削除されました。"
End Sub
1 つ以上の Excel スプレッドシートのセルの値に基づいてマクロを実行する
以下のマクロは、Excel スプレッドシートの 1 つ以上のセルの値に基づいて他のマクロを実行します。 セル値の評価結果が True の場合、 指定したマクロを実行します。 セル値の評価結果が False の場合、 他のマクロを実行します。 これを確認するには、 以下のコードを Excel ブックの ThisWorkbook プロジェクトに挿入し、 1 つ以上のセルを選択して、[ツール] メニューの [マクロ] をポイントして [マクロ] をクリックすることで RunConditionalMacros サブルーチンを実行します。 [マクロ] ダイアログ ボックスで、[ThisWorkbook.RunConditionalMacros] をクリックし、 [実行] をクリックします。
Public Sub RunConditionalMacros()
' 目的 : 条件付きマクロの実行を例示します。
' 注意 : このマクロを実行する前にセル範囲を選択してください。
Dim oCells As Excel.Range
Dim oCell As Excel.Range
' 独自の値を挿入するか、
' InputBox 関数を使用してユーザーに問い合わせます。
Const TARGET_VALUE As String = "10"
Set oCells = Application.Selection
For Each oCell In oCells
MsgBox IIf(oCell.Value = TARGET_VALUE, _
DisplayTrue, DisplayFalse)
Next oCell
End Sub\
Private Function DisplayTrue() As String
' 条件が True の場合に何らかのアクションを実行します。
DisplayTrue = "True 条件に到達しました。"
End Function
Private Function DisplayFalse() As String
' 条件が False の場合に何らかのアクションを実行します。
DisplayFalse = "False 条件に到達しました。"
End Function
ユーザーが入力コントロールをクリックした後に PowerPoint スライドの関連コントロールを無効にする
Microsoft PowerPointR はオンライン調査、アンケート、クイズなどの作成に優れたツールです。 以下は対話式のクイズを作成する場合のアプローチの一例です。
新しい PowerPoint プレゼンテーションを作成します。
[表示] メニューで [ツールバー] をポイントし、[コントロール ツールボックス] をクリックします。
以下のプロパティを持つコントロールを 1 つ目のスライドに追加します。
コントロール プロパティ 値 Label (Name) lblQuestion Caption 太陽から地球の距離は何マイルですか ? OptionButton (Name) optA Caption 1000 万マイル OptionButton (Name) optB Caption 9300 万マイル OptionButton (Name) optC Caption 10 億マイル TextBox (Name) txtAnswer CommandButton (Name) btnAgain Caption 再挑戦 以下の VBA コードをフォームに挿入します。
Private Const CORRECT_ANSWER As String = "正解! すばらしい!" Private Const INCORRECT_ANSWER As String = "不正解。再挑戦してください。" Private Sub btnAgain_Click() optA.Value = False optB.Value = False optC.Value = False optA.Enabled = True optB.Enabled = True optC.Enabled = True txtAnswer.Text = "" End Sub Private Sub optA_Click() optB.Enabled = False optC.Enabled = False txtAnswer.Text = INCORRECT_ANSWER End Sub Private Sub optB_Click() optA.Enabled = False optC.Enabled = False txtAnswer.Text = CORRECT_ANSWER End Sub Private Sub optC_Click() optA.Enabled = False optB.Enabled = False txtAnswer.Text = INCORRECT_ANSWER End SubVisual Basic Editor を閉じてプレゼンテーションに戻ります。
[表示] メニューの [スライド ショー] をクリックします。
不正解の答え (1000 万マイルまたは 10 億マイル) をクリックし、[再挑戦] をクリックします。
正解の答え (9300 万マイル) をクリックします。
.gif)
図 2. PowerPoint での簡単なクイズ
ユーザーが Office ドキュメントを開くときに注意情報を表示する
ユーザーに注意を促す情報を表示することが役立つ場合がよくあります。 通常 Office ドキュメントを開いている場合は、メッセージ ボックスの形式で表示します。 これを行うには、以下の手順に従います。
Word では、注意を促すコードを文書の Document_Open イベントに配置します。
例 :
Private Sub Document_Open() ' 独自の注意を促す文字列を挿入します。 Msgbox "必ず早目にこまめに保存すること !" End SubExcel では、注意を促すコードをブックの Workbook_Open イベントに配置します。
PowerPoint では、注意を促すコードをアプリケーションの Application_PresentationOpen イベントに配置します。
Outlook では、注意を促すコードを ThisOutlookSession モジュールの Application_Startup イベントに配置します。
Microsoft Access では、注意を促すフォームを作成します。 [ツール] メニューの [起動時の設定] をクリックし、注意を促すフォームを [フォーム/ページの表示] ボックスの一覧から選択してクリックします。
Access メイン フォームとサブフォームを相互に同期する
VBA コードに数行を追加するだけで、Access メイン フォームとサブフォームを同期できます。 これにより、1 つのフォーム内でレコードをスクロールするたびに、 もう 1 つのフォームが自動的に対応レコードに移動します。 以下の手順にあるコードを使用すると、 メイン フォームまたはサブフォームのどちらをスクロールしても、 フォームの同期を維持します。 以下の手順を実行して、単純なメイン フォームとサブフォームを作成し、 その後両方のフォームの [レコード移動時] イベントにコードを追加してそれらを同期します。
Access を起動して新しいデータベースを作成します。
新しいテーブルを作成し、以下のフィールドまたはレコードを追加します。
EmployeeID FirstName LastName Phone 1 Nancy Davolio (206) 555-9857 2 Andrew Fuller (206) 555-9482 3 Janet Leverling (206) 555-3412 4 Margaret Peacock (206) 555-8122 テーブルに Employees という名前を付けて保存し、テーブルを閉じます。
メイン フォームを作成するには、[データベース] ウィンドウで [オブジェクト] の [フォーム] をクリックします。
[データベース] ウィンドウのツールバーの [新規作成] をクリックします。
[フォームの新規作成] ダイアログ ボックスで、フォームのデータ ソースとして [Employees] テーブルをクリックします。
その後、[オートフォーム: 表形式] ウィザードをクリックし、[OK] をクリックします。
[表示] メニューの [デザイン ビュー] をクリックします。
[表示] メニューの [プロパティ] をクリックします。
[イベント] タブをクリックし、[レコード移動時] イベントをクリックして省略記号 (...) をクリックします。 [ビルダの選択] ダイアログ ボックスで、[コード ビルダ] をクリックし、[OK] をクリックします。
以下のコードをイベント プロシージャに挿入します。
Employees.Form.RecordsetClone.FindFirst "EmployeeID = " & Me.EmployeeID Employees.Form.Bookmark = Employees.Form.RecordsetClone.Bookmarkフォームに Mainfrm という名前を付けて保存し、フォームを閉じます。
サブフォームを作成するには、データベース ウィンドウのツールバーで [新規作成] ボタンをクリックします。
[フォームの新規作成] ダイアログ ボックスで、フォームのデータ ソースとして [Employees] をクリックします。
その後、[オートフォーム: データシート] ウィザードをクリックし、[OK] をクリックします。
[表示] メニューの [デザイン ビュー] をクリックします。
[表示] メニューの [プロパティ] をクリックします。
[すべて] タブで、[既定のビュー] が [データシート] に設定されていることを確認します。
[イベント] タブで、[レコード移動時] イベントをクリックし、省略記号 (...) をクリックします。 [ビルダの選択] ダイアログ ボックスで、[コード ビルダ] をクリックし、[OK] をクリックします。
以下のコードをイベント プロシージャに挿入します。
If Me.EmployeeID <> Me.Parent.EmployeeID Then ' フォームは同期されていません。. Me.Parent.RecordsetClone.FindFirst "EmployeeID = " & Me.EmployeeID Me.Parent.Bookmark = Me.Parent.RecordsetClone.Bookmark End Ifフォームに Subfrm という名前を付けて保存し、フォームを閉じます。
[デザイン ビュー] で [Mainfrm] フォームを開きます。
[Subfrm] フォームを [データベース] ウィンドウから [Mainfrm] フォームにドラッグします。
メイン フォームで [Subfrm] サブフォームが強調表示された状態で、[表示] メニューの [プロパティ] をクリックします。
[サブフォーム/サブレポート: Employees] プロパティ シートの [リンク子フィールド] チェック ボックスおよび [リンク親フィールド] チェック ボックスをオフにします。
プロパティ シートを閉じます。必要に応じてサブフォームのサイズを変更し、メイン フォームに合わせます。
フォーム ビューで Mainfrm を開きます。移動ボタンを最初にメイン フォーム、次にサブフォームで使用し、 レコード全体をスクロールします。 メイン フォームでレコードを移動すると、 自動的にサブフォームの同じレコードに移動し、 逆にサブフォームでレコードをスクロールしてもメイン フォームのレコードに移動します。
.gif)
図 3. Access メイン フォームとサブフォームの同期
ワークシートの変更を XML ファイルにログ記録する
ワークシートに行った変更を記録しておくことが重要になることがよくあります。 たとえば、変更を記録しておくことにより、 1 日に行った作業を他の日の作業と比較できます。 このセクションの手順では、変更を記録する方法を説明します。 セルのアドレスおよび日付と時刻をもう 1 つの "log" スプレッドシートにコピーし、 その記録を Extensible Markup Language (XML) ファイルに記録するコードを提供します。 XML ファイルを使用すると、ファイル データを多くのアプリケーションで読み込むことができます。
はじめに、Excel を起動して、ログ記録する作業のデータを含むワークシートを持つブックを開きます。
[挿入] メニューの [ワークシート] をクリックして、ログ ワークシートをブックに追加します。
挿入したワークシートのタブを右クリックして、Log にシート名を変更します。
記録するデータを含むワークシートのタブを右クリックし、[コードの表示] をクリックします。
[オブジェクト] ボックス (左側) で、[Worksheet] をクリックします。
[プロシージャ] ボックスで、[Change] をクリックします。
On Change イベント プロシージャで、生成されたコードを以下のコードに置き換え、Visual Basic Editor を閉じます。
Public intRowNum As Integer Private Sub Worksheet_Change(ByVal Target As Range) Dim wks1 As Worksheet Dim wks2 As Worksheet Set wks1 = ActiveWorkbook.Worksheets("Datasht") Set wks2 = ActiveWorkbook.Worksheets("Log") ' グローバル行数加算カウンタを初期化します。 If intRowNum <= 0 Or intRowNum = Null Then intRowNum = 1 Else intRowNum = intRowNum + 1 End If ' 特定のセルが変更されているかどうかを確認します。 If Target.Address = "$C$3" Then MsgBox Target.Address & " は変更されています" End If ' 変更されているかどうかにかかわらず、変更を Log に記録します。 wks2.Cells(intRowNum, 1).Value = Target.Address wks2.Cells(intRowNum, 2).Value = Now End Sub
この手順は、セルが変更されるたびにセルのアドレスおよび日付と時刻を Log ワークシートに記録します。 また、特定のセルが変更されるたびにメッセージ ボックスを表示するコードも含まれています。 この処理を変更し、 電子メールを使用して、警告メッセージを XML Web サービスまたは他の通知方法に送信することもできます。 ブックを閉じる直前に以下のコードを挿入し、Log ワークシートを XML ファイルに保存します。
再度、ブック内のワークシートの任意のタブを右クリックし、[コードの表示] をクリックします。
プロジェクト エクスプローラで、[ThisWorkbook] をダブルクリックします。
[オブジェクト] ボックスで、[Worksheet] をクリックします。
[プロシージャ] ボックスで、[BeforeClose] をクリックします。
BeforeClose イベント プロシージャで、生成されたコードを以下のコードに置き換え、Visual Basic Editor を閉じます。
Private Sub Workbook_BeforeClose(Cancel As Boolean) Dim wks As Worksheet Set wks = ActiveWorkbook.Worksheets("Log") wks.SaveAs Filename:="C:\TheDailyLog.xml", FileFormat:=xlXMLSpreadsheet End Sub
これで、ブックを閉じるたびに Log ワークシートが XML ファイルに保存されます。
複数の Outlook 電子メール メッセージからの本文の文字列を 1 つの Word 文書にマージする
複数の Outlook アイテムの本文の文字列を、1 つの Word 文書にマージする必要がある場合があります。 たとえば、関連するメッセージの文字列をレポートにマージします。 このような作業は、常に、ツール バー ボタンから実行するのが簡単です。 以下の手順を使用してコードを Outlook に貼り付け、VBA を使用しないツール バー ボタンを作成できます。
Outlook を起動します。
[ツール] メニューで [マクロ] をポイントし、[Visual Basic Editor] をクリックします。
Visual Basic Editor で、[挿入] メニューの [モジュール] をクリックします。
プロジェクト エクスプローラで、挿入したモジュールをダブルクリックします。
以下のサブルーチンをコード ウィンドウに挿入します。
Public Sub MergeEMailsToWordDocument() ' 目的 : 選択した Microsoft Outlook アイテムの本文の文字列を ' 1 つの Microsoft Word 文書にマージします。 ' 注意 : 少なくとも 1 つのアイテムを選択する必要があります。 ' 特別な参照 : ' Microsoft Word 10.0 オブジェクト ライブラリ (MSWORD.OLB) Dim olApp As Outlook.Application Dim oSel As Outlook.Selection Dim oObj As Object Dim sText As String Dim wdApp As Word.Application Dim oDoc As Word.Document Set olApp = Outlook.Application Set oSel = olApp.ActiveExplorer.Selection For Each oObj In oSel sText = sText & oObj.Body & vbCrLf & vbCrLf Next oObj Set wdApp = New Word.Application wdApp.Visible = True Set oDoc = wdApp.Documents.Add oDoc.Range = sText Set oDoc = Nothing Set wdApp = Nothing Set oObj = Nothing Set oSel = Nothing Set olApp = Nothing End SubVisual Basic Editor を閉じます。
[標準] ツール バーにボタンを作成してプロシージャを実行するには、 [表示] メニューの [ツールバー] をポイントして [ユーザー設定] をクリックします。
[コマンド] タブの [分類] 一覧で、[マクロ] をクリックします。 マクロが [Project1.MergeEMailsToWordDocument] という名前で表示されます。
マクロ名をクリックしてツール バーの位置にドラッグします。
ツール バー ボタンを選択した状態で、[選択したボタンの編集] をクリックし、 ボタンの名前を [Merge To Word] に変更します。
ボタンの表示に関する任意の必要な変更を追加し、[閉じる] をクリックします。
確認を行うには、1 つ以上のメッセージを Outlook エクスプローラでクリックして [Merge To Word] をクリックします。 Word が起動し、選択したメッセージの本文の文字列が文書内にマージして表示されます。
ユーザー入力の表示と取得に代替策として Office アシスタントを使用する
Office アシスタント ("クリッパー" としても知られています) は、 ユーザー入力を表示または取得する優れた代替策として使用できます。 以下の手順を実行する前に、Office アシスタントが非表示になっている場合は、 有効にする必要があります。 手順を実行するときに Office アシスタントが表示されていない場合は、 [ヘルプ] メニューの [Office アシスタントの表示] をクリックします ([ヘルプ] メニューに表示されているオプションが [Office アシスタントを隠す] の場合、Office アシスタントは既に有効になっています)。 独自のアプリケーションで Office アシスタントを使用して作業するには、以下のようなコードを使用します。
Private Sub AssistantMsgBox()
' 目的 : Office アシスタントを VBA MsgBox 関数の
' 代替策として使用する方法を説明します。
' 特別な参照 :
' Microsoft Office 10.0 オブジェクト ライブラリ (MSO.DLL)
Dim oApp As Application
Dim oAst As Office.Assistant
Dim oBal As Office.Balloon
' 特定の文字列サブルーチン
Const MSG_TEXT As String = "ここをクリックしてください。"
Set oApp = Application
Set oAst = oApp.Assistant
Set oBal = oAst.NewBalloon
oAst.Visible = True
oBal.Text = MSG_TEXT
oBal.Show
Set oBal = Nothing
Set oAst = Nothing
Set oApp = Nothing
End Sub
アシスタントがユーザー入力を取得できるように設定するには、 以下のようなコードを使用します。
Private Sub AssistantInputBox()
' 目的 : Office アシスタントを使用して
' ユーザー入力を取得する方法を説明します。
' 特別な参照 :
' Microsoft Office 10.0 オブジェクト ライブラリ (MSO.DLL)
Dim oApp As Application
Dim oAst As Office.Assistant
Dim oBal As Office.Balloon
Dim oLbls As Office.BalloonLabels
Dim iResp As Integer
Dim sResp As String
' 特定の文字列サブルーチン
Const MSG_TEXT As String = "学校で好きな授業は何ですか?"
Const TEXT_1 As String = "数学"
Const TEXT_2 As String = "歴史"
Const TEXT_3 As String = "どちらでもない"
Set oApp = Application
Set oAst = oApp.Assistant
Set oBal = oAst.NewBalloon
Set oLbls = oBal.Labels
oLbls.Item(1).Text = TEXT_1
oLbls.Item(2).Text = TEXT_2
oLbls.Item(3).Text = TEXT_3
oAst.Visible = True
oBal.Text = MSG_TEXT
Do
iResp = oBal.Show
Loop While iResp = -1
sResp = oBal.Labels(iResp).Text
Set oBal = Nothing
Set oBal = oAst.NewBalloon
oBal.Text = "'" & sResp & "' をクリックしました。"
oBal.Show
Set oBal = Nothing
Set oAst = Nothing
Set oApp = Nothing
End Sub