Top > Programmingとか > Office > タブと闘う

06 キーボードからの終了と表示位置の保存

検証環境 SONY VAIO PCG-U1(Crusoe860MHz/240MB)
WinXPHomeSP1/IE6.0SP1/MSExcel2002SP2

さて。今までの機能とは直接関係ないんですけど。

実際にこのFormでWorkBookやSheetをだばだば切り替えながら作業していると、ちょっとしたところでめんどくさいんですね。



まず、Formのクローズ。

Form右上の[×]ボタンを押せばいいだけなんですけど、けっこうめんどくさいのこれ。
せっかくですから、[ESC]キーでもクローズできるようにしましょう。

話は簡単。
Formに[ESC]ボタンを追加して、CancelプロパティをTrueにするだけです。
コードの中身は、単純なUnloadで。

040208-01.gif
'******************
' UserFormのUnload
'******************
Private Sub cmdESC_Click()
Unload Me
End Sub

次。表示位置の保存と復元。

この機能を使っての作業の眼目は、Excelのシートを渡り歩いて参照とかをしたい、ってとこにあったわけです。
ので、Excelのど真ん中()に表示されたり、デスクトップ左上()に表示されるのはいかにも具合が悪いんですね。
どちらの領域も、データが書き込まれている可能性の高いところなんですよ。できれば右下あたりに表示されたいもんです。
ってのは私の好みでして、他の方は別の位置に表示させたかったりするかもしれません。

やっぱここはひとつ、表示位置を保存→次回起動時に表示位置を復元、って機能をつけておきたいですね。

まぁそれ自体は簡単なんですけど、気にしたいのは、取得した表示座標の保存先。
VBだとINIファイルやらレジストリやらに記録しておくところなんですけど、せっかくExcelなんですから、Excelの中で完結させられないかなーと。

で、ぼーっとExcel VB Editerを眺めていたら。
Personal.xlsの中にも非表示ながらSheetがあるじゃあないですか。

040208-02.gif

ここに格納できれば、Excelの中だけで完結するなぁ。
どうせなら、Sheet1じゃなくて、この機能専用にひとつSheetがあれば、他の機能があってもぶつからないよなぁ。
でもって、これを手動で作るのは操作がめんどくさいから、初回起動時に自動で作れればいいなぁ。

てことで、作ってみました。

まず、表示座標を記録する専用のSheetを追加するコードから。

どっちみちこのForm、マクロからShowしなきゃいけないわけですので、それ用のマクロをひとつ作りましょう。
専用のモジュールmodTatakauを用意して、そこに関数を記入。

'**************************
' タブ選択ダイアログの表示
'**************************
Sub ShowTatakau()
Dim strRet As String
Dim i As Long
'*** 初回起動時、ツールバーへのボタン登録を確認する
'パラメータ用Sheetの存在確認
strRet = "forTatakauなし"
For i = 1 To Workbooks("PERSONAL.XLS").Worksheets.Count
If Workbooks("PERSONAL.XLS").Worksheets(i).Name = "forTatakau" Then
strRet = "forTatakauあり"
Exit For
End If
Next
'*** パラメータ用Sheetが存在していなければ初回起動と見なす
If (strRet = "forTatakauなし") Then
'パラメータ用Sheetがなければ生成
Workbooks("PERSONAL.XLS").Worksheets.Add.Name = "forTatakau"
End If
'*** タブ選択ダイアログの表示
frmTatakau.Show
End Sub
ちょっと悩んだのが、「Workbooks("PERSONAL.XLS").Worksheets.Add.Name」の部分。

「Add」って、メソッドなんですよ。なのに、さらに「Name」プロパティを書き足してるんですね。
な、納得いかん。

でも、ヘルプを読むと、「Add」メソッドにはBefore、After、Count、Typeの4つの引数しかないことになっていますし。の割には、あちこちのExcel VBAサイトではさらりと「Add.Name」の例とかさらりと記述されてたりするんですよ。

Microsoftからの公式資料(Excelのヘルプとかmsdnとか)だけではわからない、書籍を買ったり講習を受けたりしなければわからないような事柄なんでしょうか。
なんかおもしろくないなぁ。

などと思っていたら、わかりました。Excel2000のヘルプには書いてあったんです。

Add メソッド (Worksheets コレクション)

オブジェクトを返すメソッドです。新しいワークシートを作成します。新しいワークシートがアクティブ シートになります。ワークシート (Worksheet オブジェクト) を返します。

ちくしょうAddメソッドには返値があるのか。しかも値じゃなくて、Worksheetオブジェクトを返すのか。
確かにWorksheetオブジェクトにはNameプロパティがあるけど、まさかAddメソッドをそのままWorksheetオブジェクトとしてNameプロパティへの値の代入まで一気にできるとは思いつくもんじゃないぞっ。

てことで、これは本来こう書くべきなんでしょう。

Dim wstWk   As Worksheet
Set wstWk = Workbooks("PERSONAL.XLS").Worksheets.Add
wstWk.Name = "forTatakau"
まぁこれを本来書くべきコードとして、「Add.Name」はその省略形として考えるんであれば納得はいきます。
新しく生成したシートに複数のプロパティをセットした場合には、本来コードで書くしかないわけですしね。

となると、なぜExcelXPのヘルプにはこの記述がないのか。

実は、ExcelXPのヘルプではいろんなオブジェクトのAddメソッドの説明を1ヶ所にまとめてあるんです。
どうもOfficeXPヘルプの特長のひとつに、ページ内で説明を折りたたむ(クリックすると一部が開く)といぅワザを多用するってのがあるみたいで。
この折りたたみ機能を採用するのに、Addメソッドの説明と使用例をまとめちゃったんですが、その際に「Addメソッドはオブジェクトを返す」って一文を削除しちゃったみたいなんですね。

おかげで、ExcelXPの中だけで一所懸命考えてても、Addメソッドの一般的なしくみがわからないような状態になってしまった、と。

Microsoft Officeのヘルプは、実は2000の頃からおかしくなってきてまして。
どうもヘルプを機能ごとにいくつかのファイルに分けているみたいで、F1でヘルプを表示する際にどんな単語の上にカーソルが置かれているかでロードされるファイルの組み合わせが違ってくるんですよね。
おかげでヘルプを丸ごと読んで全体像を把握する、って学習法がとれないんです。

しかも「検索」機能がなくなってしまって。
文章で質問する、って変な機能が代わりについたんですけど、全然知りたいものはヒットしませんし。
キーワードも、基本的な単語さえヒットしない有様。

なんだか実にツカえない代物になってしまっています。…頭にくるなぁ。



すいません、話を戻して。

これで表示座標の格納先は確保できたわけですから、後は、UserFormのUnload時に表示座標を格納し、Load時に取得してその座標位置にUserFormを移動させるコードを書けばいいわけです。

VBを使い慣れてるとちょっととまどいますが、UserFormのLoad時に走るイベントはInitialize(今までにもう使っていますが)、Unload直前に走るイベントはQueryCloseです。
VBAに詳しい方には当たり前のことかもしれませんが、VBから始めた私にはちょっとびっくりな出来事でした。

'****************
' UserForm起動時
'****************
Private Sub UserForm_Initialize()
Dim lngX As Long
Dim lngY As Long
'*** Formパラメータの取得
lngX = Workbooks("PERSONAL.XLS").Worksheets("forTatakau").Cells(1, 1).Value
lngY = Workbooks("PERSONAL.XLS").Worksheets("forTatakau").Cells(1, 2).Value
Me.Move lngX, lngY
'*** 現在のBook/Sheet状況を取得→表示
Call sGetAllBooks 'Book情報の取得と表示
Call sGetSheets(ActiveWorkbook) 'Sheet情報の取得と表示
End Sub
'****************
' UserForm終了時
'****************
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'*** Formパラメータの格納
Workbooks("PERSONAL.XLS").Worksheets("forTatakau").Cells(1, 1).Value = Me.Left
Workbooks("PERSONAL.XLS").Worksheets("forTatakau").Cells(1, 2).Value = Me.Top
Workbooks("PERSONAL.XLS").Save
End Sub
UserForm_QueryCloseイベントの最後に「Save」を入れているのは、座標を格納したPersonal.xlsをディスクに書き出しておきたいからです。
これをやっておかないと、Excelの終了時に「個人用マクロブックを保存しますか?」って聞いてきちゃうので。


さて、これでそこそこ使いやすくなったよぅな気が。
ここまでできると、この機能を公開して、皆さんにも使っていただきたいよぅな気が。

ので、次回は公開用にもぅ少し手を加えてみることにします。

トラックバック

このエントリーのトラックバックURL:
http://salv.miscnotes.com/mt/mt-tb.cgi/338

コメントを投稿