Top > Programmingとか > Office > OfficeXPをまさぐる

2002年08月19日

07 ドッカブれません(T-T)

さてExcelにおいて、UserFormの代わりにCommandBarを何とか使うことはできないかと先日来じったばたこいておったわけですが。

まずは、作業ウィンドウツールバーで何とかできないかとの試み。

よーくヘルプをひっくり返して読んでみると、

Application.CommandBars("作業ウィンドウ")
をCommandBar型変数にSetすれば作業ウィンドウツールバーはVBAのコントロール配下に置けることまではわかりました。

…でもね。そんだけなの。

別にAddできるわけではなく、今ある作業ウィンドウツールバーをSetするだけなの。

でもって、作業ウィンドウツールバーってがっちがちの参照専用に抑え込まれちゃっているので、Setしたからって、そのCommandBarオブジェクトにControlをAddできるわけでもないし、ましてや中にはめ込まらさっているbosa_sdm_XL9ウィンドウをいじくれるわけではないの。

\(T-T)/

じゃぁ別の方法はないもんか、ってんでしつこくあちこち探してみたんですが。

こんなんありました。

簡単に言うとこれ、ツールバーで電卓を作る方法なんですが。

Windowsのアクセサリにあるのになぜわざわざ電卓なのか、とか
UserFormでも作れるのになぜわざわざツールバーで作るのか、とか
ツールバーで作ってるもんだから、次回起動しても前回の計算結果が残ってるぞ、とか
動作がむちゃくちゃ遅いぞ、とか
Excel97では表示はできるがまともに動作しないぞ、とか
各種つっこみ禁止

でもツールバーにコントロールをばりばり突っ込んでUserFormのように使っちゃおぅって発想はちょっと目からうろこでしたよ。

さっそくこれを本歌取りに、ComboBoxとListBoxをひとつずつ並べたツールバーを自作してみたんですが。

…だめですこれ。

フロートしている時や上下にドッキングしている時には希望通りに表示されるんですけど、

左右にドッキングした途端に ComboBoxもListBoxも非表示になっちゃう。

ツールバーの幅を変えてみたりもしてみましたが全然反映されません。
もしや、と思って標準で持っている書式設定ツールバーを右にドッキングさせてみたら、やっぱりComboBoxが非表示になってしまいました。(文字表示のCommandButtonは90°回転して表示されるんですけどね。)

フロート状態でなら何とかなるんですけど、シートの上に乗っかっちゃうんならUserFormで作ったって大差ないしなぁ…元々がシートの作業領域の邪魔をしないようにドッカブルにしたかったわけですから。

開き直ってUserFormで作っといて、UserFormの幅分のダミーツールバーを右にドッキングさせてその上にカブす、って手も考えてみたんですけど、実際によく使うツールバーを右にドッキングさせて使用している方にとっては明らかに邪魔邪魔な状態になってしまうだけですし。

\(T-T)/\(T-T)/

てことで、現時点ではドッカブルな機能提供はさわやかにあきらめることにしたですよ。

ツールバー上に表示/非表示を切り替えるトグルボタンでも用意して、簡単にOn/Offできるようにすることでなるべくお邪魔にならない実装を考えるしかないっぽいです、今の私のスキルでは。

2002年08月07日

06 作業ウィンドウのひみちゅを探れ

作業ウィンドウってやつをご存知でしょうか。

素でExcelXPなんかを起動すると、時々頼みもしないのにウィンドウ右側に出てくる内部組み込みウィンドウなんですが。

020811-01.gif

先日までさみだれに説明してきたシートタブの一覧を、「この作業ウィンドウの中に追加したら操作上すっきりするんではないか?」などと思ってしまったのが運のつき。この作業ウィンドウの正体を知りたくってうずうずしてきてしまったんです。

で、とりあえずこんな時にはお世話になりますspy++。でチェックしてみると、キャプションが"作業ウィンドウ"のMsoCommandBarクラスでした。…MsoCommandBar?
って、ツールバーとかメニューバーのクラスじゃないですか。ってことは、作業ウィンドウってツールバー?ふつーのツールバーの扱いとして表示/非表示がかかるってこと?

で、メニューから[ツール]-[ユーザー設定]と選択して表示されるユーザー設定ダイアログの[ツールバー]タブをチェック。

020811-02.gif

…あるじゃん作業ウィンドウ。試しにOffにしたらちゃんと消えるし。

じゃあ。この作業ウィンドウツールバーの内部に表示されているブックを開くとかの機能は何?作業ウィンドウ右上の[▼]を押すとクリップボードとか検索とかも出てくるんですけど。ふつーにツールバーにこんな操作可能なオブジェクトが組み込めるなんて、私知らないんですけど。

じゃあこの作業ウィンドウツールバーの内部には何が組み込まれているかをspy++で見てみると、キャプションが"新規作成"のbosa_sdm_XL9

bosa_sdm_XL9クラスってなんだ。

MSDN…日本のサイトも本家アメリカのサイトもサーチしてみたけど何にも出てきません。Googleでもアウト。
Altavistaでサーチしてみると…3件だけヒットしました。
無駄にヒットしまくるAltavistaでこれかい。心細いなぁ。しかもそのうち一ヶ所はデンマークのサイトみたいだし読めません



えーと。ここでいちいちヒットしたサイトのURLは書きませんので。興味のある方はご自分でサーチしてみてください。

まず一ヶ所目。
Centre a excel dialog box in a 32 bit systemが目的なんだそうで、FindWindow32 APIのクラス名引数にbosa_sdm_XLを使っていました。でフックしたウィンドウを画面中央に持ってくるロジックですね。ってこれ、単純なダイアログボックス扱いです。しかも16ビット版(Win3.1ですね)用と32ビット用のVBAコードが記載されています。
二ヶ所目も同様。

三ヶ所目は、Word用にダイアログボックスのキャプションをむりやり差し替えるVBA コードでした。しかもWord97/2000用。

ってことは、bosa_sdmってOfficeのダイアログボックスなのかなぁ。しかも16ビット版の頃から一般的に使用されていたクラスっぽいっす。

spy++で確認してみると、確かに上述のユーザー設定ダイアログも、名前をつけて保存ダイアログもbosa_sdm_XL9クラス。
対して自作UserFormのクラス名はThunderDFrame。…これはちょっと無理かしら。



悔しいのでもぅちょい頑張ってみることにします。
今度はオブジェクトの状態をチェック

てことで、まずは作業ウィンドウのオブジェクト名を知ることにします。
チェックに使ったコードはこちら。

Sub sFindCommandBar01()

Dim objCBar As CommandBar

For Each objCBar In CommandBars
Debug.Print objCBar.Name & " - ";
Debug.Print objCBar.NameLocal
Next

End Sub
これでCommandBar(ツールバーとかメニューバーとか)の内部オブジェクト名と和名が一覧で表示されます。目的の作業ウィンドウの内部オブジェクト名はTask Paneだといぅことがわかりました。

ほんと?ちょっと確認。

Sub sFindCommandbar02()

Dim objCBar As CommandBar

Set objCBar = CommandBars("Task Pane")

Debug.Print objCBar.Name & " - ";
Debug.Print objCBar.NameLocal

End Sub
OKOK。ちゃんとこの指定で、objCBarにオブジェクトハンドルが格納されてますね。

さて、なんで内部オブジェクト名なんかわかりたかったかっていぅと。
こんなことができるんです。

Sub sFindCommandbar03()

Dim objCBar As CommandBar
Dim objCCtrl As CommandBarControl

Set objCBar = CommandBars("Standard")

For Each objCCtrl In objCBar.Controls
Debug.Print objCCtrl.Type & " - ";
Debug.Print objCCtrl.Caption
Next

End Sub
上述のコードはStandard(標準)ツールバーに対してその構成要素のタイプとキャプションを列挙するコードです。その実行結果は

1 -新規作成(&N)
1 -開く
1 -上書き保存(&S)
1 -メールの宛先(&M)
1 -検索(&H)...
1 -印刷 (RICOH NX-110 RPDL)
1 -印刷プレビュー(&V)
1 -スペル チェック(&S)...
1 -切り取り(&T)
1 -コピー(&C)
13 -貼り付け(&P)
1 -書式のコピー/貼り付け(&F)
6 -元に戻す(&U)
6 -やり直し(&R)
1 -ハイパーリンク(&I)...
13 -オート SUM(&A)
1 -昇順で並べ替え(&A)
1 -降順で並べ替え(&C)
1 -グラフ ウィザード(&C)
1 -図形描画(&D)
4 -ズーム(&Z)
1 -Microsoft Excel ヘルプ(&H)

って感じになります。

Typeプロパティがむき出しの数値で表示されますが、自分でプログラミングする時には、ふつーOfficeライブラリの中で提供されているMsoControlTypeクラスで提供されている定数で指定します。
で、MsoControlTypeクラスで提供されている定数と数値の相関は、

0msoControlCustom
1msoControlButton
2msoControlEdit
3msoControlDropdown
4msoControlComboBox
5msoControlButtonDropdown
6msoControlSplitDropdown
7msoControlOCXDropdown
8msoControlGenericDropdown
9msoControlGraphicDropdown
10msoControlPopup
11msoControlGraphicPopup
12msoControlButtonPopup
13msoControlSplitButtonPopup
14msoControlSplitButtonMRUPopup
15msoControlLabel
16msoControlExpandingGrid
17msoControlSplitExpandingGrid
18msoControlGrid
19msoControlGauge
20msoControlGraphicCombo
21msoControlPane
22msoControlActiveX
23msoControlSpinner
24msoControlLabelEx
25msoControlWorkPane
26msoControlAutoCompleteCombo

ではお目当ての作業ウィンドウツールバーはどう構成されているかといぅと、先のコードをちょっと変えて

Sub sFindCommandbar04()

Dim objCBar As CommandBar
Dim objCCtrl As CommandBarControl

Set objCBar = CommandBars("Task Pane")

For Each objCCtrl In objCBar.Controls
Debug.Print objCCtrl.Type & " - ";
Debug.Print objCCtrl.Caption
Next

End Sub
答は 25 - 新しいブック。…あれ?

Excelでは4種類の機能を任意に切り替えられるので、作業ウィンドウには4種類の機能があらかじめ埋め込まれてるんだと思ってました。が、1種類だけなんですね。ふぅん。

ってちょっとよそにも興味が行くんですが、まずは「25」って。msoControlWorkPaneって何でしょう。

もぅ一度MSDNで探してみると、米国版の方でこんなん見つけてみたんですけど…だめだこれ、CommandBarの属性列挙のプログラムサンプルだぁ。私が今までやってきたことと大差ないです。



うーむ。どぅやら完全に詰まってしまいました。
てことで、本日はここまで。進展があれば、また報告します。

自力で調査している時なんて、こんなもんですって。100あたって実を結ぶのは1とか2とか。

…ま、負けるもんか。

2002年03月01日

05 行選択ショートカットキーができるまで

前回なんか大急ぎでソースだけ提示してしまって失敗したなぁと思っているさるべーじですこんばんは。

本サイトは一応、

発想→試行錯誤→完成(または挫折)

のプロセスの部分をこそお伝えしていきたいといぅか実況生中継といぅかなんかそんな感じでいきたいので。

てことで今回は、前回のソースができるまでのお話となります。



行選択をショートカットで実行したい。
ただしIMEのOn/Offの状況に関わらず。

VBAで組み込んで実装しよう。

ってまず発想の部分はいいですよね?で、ショートカットとしての実装の部分はEXCEL生産性向上委員会のコンテンツ参照ということでいいですよね?

のでここでは主に実装したい機能の中身を作るところを。



Excelに限らずMicrosoft Officeには、Visual Basic for Application(VBA)といぅプログラミング言語が組み込まれています。今さらですが。

このVBA、いかにもVBの仲間だよーって感じのネーミングなんですが、成り立ちはまったく違います。VBがMicrosoft BASICの流れを汲むのに対し、VBAはWordやExcelのマクロからの進化形ですので。

ですから、未だにマクロという言い方がアプリ本体にもヘルプにも残ってしまっています。なんとなく誤解しやすそぅな部分ではありますが、

マクロ=VBA

です。まったくおんなじもんです。マクロを実行するってことは、VBAプログラムを実行するってことなんです。

ので。[新しいマクロの記録]をすると、VBAプログラムが自動作成されます。逆に言えば、作りたいプログラムの主な動作は[新しいマクロの記録]で手に入れることができるってことになります。ふっふっふ。

今回作りたいプログラムは行選択なわけですから、行選択の操作を記録すれば、その部分のコードは手にはいることになります。まずはそこからやってみましょう。

Sub Macro1()
'
' Macro1 Macro
' マクロ記録日 : 2002/3/1 ユーザー名 : salvage
'

'
Rows("24:24").Select
Range("G24").Activate
End Sub
これは24行目、G列にカーソルがあるときの動作です。"24:24"ってのは、1つめの数値が開始行、2つめの数値が終了行でしょうか。では、複数行を選択して行選択操作を記録してみれば、ここらへんの数値の変化を確認できそぅですね。試してみましょう。
Sub Macro1()
'
' Macro1 Macro
' マクロ記録日 : 2002/3/1 ユーザー名 : salvage
'

'
Rows("24:28").Select
Range("E24").Activate
End Sub
やはり"24:24"→"24:28"に変わりました。

最後のRangeはカレントカーソルを設定するメソッドですが、別にカーソルが移動するわけではなし、不要なよぅな気がするんですけど挿入されているのはなぜでしょうわかりません。
まぁとりあえずRangeメソッドは無視しといて、後で不具合でも出てきたら入れてみるといぅことで。わははは。

となると、後は選択されているセルの一番上と一番下の行番号が取得できればいいんです。 選択されているセルはRangeオブジェクトとして参照できるわけですから、「Rangeオブジェクト」でヘルプをみてみればいいんですよね。

ないよそんな使い方。

Rangeオブジェクトを使うには、必ず引数として選択セルの行列を指定しなくちゃいけない。って、その選択セルの行を知りたいわけですから。

しかもOfficeのヘルプってむちゃくちゃ使いにくい。てゅうかバグだらけ。
目次はExcel Basic・Office Basic・Visual Basic・Forms Basicで分かれているし、[質問]機能も[キーワード]機能も漏れだらけ。なんだねこれは。Office2000でもXPでも同じへんてこ具合ですし、msdnLibrayならばどぅかと見てみると、2000とXP両方のヘルプが入っちゃってるし。

でもまぁしかたがないので、msdnLibrayの検索機能(なぜVBAのヘルプから[検索]機能がなくなっちゃったのかなぁ…[質問]機能では代替になってないっす)で「Range」をキーワードに引きまくり&読みまくり。

…どぅもRangeオブジェクトは、選択セルの情報を持つさまざまなオブジェクトの定義なだけで、実際のインスタンスはそれぞれ別個に固有名詞がついているよぅです。
自分でセル範囲を指定してどぅこぅしたい時にRangeオブジェクトを直接いじくるってだけの話で、すでに選択されているセル範囲とか名前付けされているセル範囲を参照するにはそれ専用のオブジェクトを使うらしい、と。

じゃあ、選択セルの情報を持つオブジェクトってなんだ。

これはもぅ単語の見当がつかないので、ヘルプを目次に沿って片っ端から読みまくり。…どぅやらApplicationオブジェクトのSelectionプロパティみたいなんですね。Rangeオブジェクト型のプロパティ。なんだそりゃ。

いゃ、本家VBだってFontプロパティは構造体を持つわけですから、オブジェクト型のプロパティだってあっておかしくはありません。ありませんけど。

などとExcelのオブジェクト構造のデザインにいまいち承伏しかねつつ先へ。

ApplicationオブジェクトのSelectionプロパティアクティブ ウィンドウで現在選択されているオブジェクト(ヘルプより)ででありRangeオブジェクトを返すので、この下の構造はRangeオブジェクトの方の説明を見ろ、といぅことになりますので見ます。

…って、なぜか見ているのはRangeコレクションの項目。どぅもRangeにはコレクションとオブジェクトとプロパティがあるよぅで。

コレクションってのはオブジェクトの集合
プロパティはオブジェクトの1要素

と理解していた私にはちょっとついていくのが難しいです。

えーと。
Selectionプロパティ=Rangeオブジェクトとして考えていいのかな?で、Rangeコレクションのヘルプがコレクションとオブジェクトをごちゃごちゃに説明しているとして読めば、単純にSelectionオブジェクトのRowプロパティを参照すればいいのかな?であれば、

Selection.Rowで最小の行番号が取得できる。

ということになりますね。実際やってみたら、おっけーでした。

ここまでくれば。

最終行は、最初の行+行数-1で算出できます。あとはこの最初の行と最終行をそれぞれ変数に入れて、それを文字列化したものを間に":"かましてつなげてRows().SelectのRows側の引数にしてやればいいわけです。

で、できあがったのがこれ。

Dim intSttRow As Integer
Dim intEndRow As Integer

intSttRow = Selection.Row
intEndRow = Selection.Rows.Count + SttRow - 1

Rows(CStr(intSttRow) & ":" & CStr(intEndRow)).Select
おっけー!後はこれをAuto_Openプロシージャの中にApplication.OnKey "+^ ", "RowsSelect"として入れてExcelの再起動をかければ。

おぉっ、ちゃんと動作するする。Shift+Ctrl+Spaceで行選択ができますよ。



よぅしこれで文書の作成がさくさく効率よくだめだ

複数領域選択の時に最初のひとつしか行選択できない。

しかたない。2つ以上の選択領域がある時にはエラーのダイアログを出すことでしのぐことにしましょう。

先ほどの、ヘルプのRangeコレクションのページをもぅ一度丹念に読んで。たぶんRangeコレクションの中に選択されている領域の個数まで格納されているはずですから。

…見つけました。Countプロパティ。これでSelection.Countが2以上ならだめだ。Selection.Countは総行数を返す。どぅもSelection.Count=Selection.Rows.Countみたいですね。てゅうか、Selectionの要素省略時デフォルトが行関係のよぅな。

では、領域数のカウントは?といぅと、ヘルプ-Countプロパティの使用例にありました。

Selection.Areas.Count。

てことで、さっきのコードに追加。

Dim SttRow As Integer
Dim EndRow As Integer

If (Selection.Areas.Count > 1) Then
MsgBox "複数のセル選択領域がある場合には" & vbCrLf _
& "行選択はできません"
Exit Sub
End If

SttRow = Selection.Row
EndRow = Selection.Rows.Count + SttRow - 1

Rows(CStr(SttRow) & ":" _
& CStr(EndRow)).Select
おっけー!ちゃんと動作(以下略。)


よぅしこれで文書の作成が今度こそさくさく効率よくまだだめだ

一行おきに一行ずつ行挿入したい時に、ひとつずつ選んで行挿入→繰り返す、なんてやってられるか

ここはひとつ、複数行選択→一発あちこち挿入をなにがなんでも実装したい

てことで、調査のし直しからやり直し。

複数領域を選択している時に行挿入をすると、マクロの記録ではどーいぅコードが生成されるか。

Sub Macro1()
'
' Macro1 Macro
' マクロ記録日 : 2002/3/1 ユーザー名 : salvage
'

'
Range("11:11,14:14,18:19").Select
Range("A18").Activate
End Sub
Rows().SelectじゃなくてRange().Selectかっ!

てことは"11:11,14:14,18:19"の部分を文字列として用意してやればいいわけですから。

先ほどの領域数取得の時に、Selectionを選択領域単位で見るときにはAreasを使えばいいといぅことはわかりました。でヘルプで見ると、Rangeコレクションからたどった時に出てくるAreasはプロパティなんですが、その説明はAreasコレクションを返しますといぅ。ご丁寧にAreasコレクションへの文中リンクもあるといぅ。でそちらをたどると、Areasコレクションの説明ページへ。そのページの使い方の中に、Selection.Areas(1).Clearの記述発見。

Areas(選択領域通し番号)でひとつの選択領域指定可能。
しかもRangeオブジェクト。

ちなみに3領域選択した時にAreas(0)はエラー、Areas(3)は3つめの領域の要素を返しましたので、Areasの引数は、1~選択領域数(0~選択領域数-1ではない)といぅことになります。

てことは、こぅだ!

Dim intSttRow   As Integer
Dim intEndRow As Integer
Dim strRows As String
Dim i As Integer

'*** 対象行バッファの初期化
strRows = ""

'*** 全ての選択領域の取得
→対象行バッファへ格納(複数選択領域に対応) 
For i = 1 To Selection.Areas.Count
If (strRows <> "") Then strRows = strRows & ","
intSttRow = Selection.Areas(i).Row
intEndRow = intSttRow _
+ Selection.Areas(i).Rows.Count - 1
strRows = strRows & CStr(intSttRow) _
& ":" & CStr(intEndRow)
Next

'*** 選択領域の行選択
Range(strRows).Select
おっけー!ちゃんと動作(以下略。)


以上、ここまでと前回Upしたソースとなります。

いやぁ苦労しましたしました。わずか十数行のコードを書くのに

ってまとめに入ろぅとしたら、前述EXCEL生産性向上委員会の玉蔵さんがこのページを見てくださって、

Integerだと表の下の方ではばけるよ
(北海道弁意訳)

との熱いメッセージが。

うそ。

試しにやってみたら…ってExcelXPのMax行番号65536。すでにこの時点でアウト。念のためにやってみたら

実行時エラー'6':
オーバーフローしました。

そりゃそぅですね。

てことでさらに修正。真のコードはこれだぁ!

Sub RowsSelect()

Dim lngSttRow As Long
Dim lngEndRow As Long
Dim strRows As String
Dim i As Long

'*** 対象行バッファの初期化
strRows = ""

'*** 全ての選択領域の取得
→対象行バッファへ格納(複数選択領域に対応) 
For i = 1 To Selection.Areas.Count
If (strRows <> "") Then strRows = strRows & ","
lngSttRow = Selection.Areas(i).Row
lngEndRow = lngSttRow _
+ Selection.Areas(i).Rows.Count - 1
strRows = strRows & CStr(lngSttRow) _
& ":" & CStr(lngEndRow)
Next

'*** 選択領域の行選択
Range(strRows).Select

End Sub
いつのまに32767の壁を突破していたんだExcel。列数はIV=256までなのは変わらないくせに(いゃ昔は128までだったか?)。

迂闊。

玉蔵さん、ありがとうございました。
また前回のコードを真に受けた読者諸氏は今回のコードに差し替えるようお願い申しあげたく平に。

…くすん。恥かきんぼでした。
まぁそんなこともあるさっ。

2002年02月25日

04 Excelで独自のショートカットキー

Excelは、Ctrl+なんとかとかAlt+なんとかとか押すと、メニューからあーだのこーだの選択したのと同じ動作をするキーの組み合わせがあります。この、めんどくさい操作を一発で行ってしまうキーの組み合わせを、

ショートカット(近道)キー

と呼びます。

いゃ、別にそんなエラそぅにいぅほどのことでもなく、大抵のアプリケーションにはある程度実装されてる機能なんですけど。本サイトの文章を読むよぅな方は大なり小なり私とこだわりの方向に近似性がおありだと思っておりますので、まぁご存じではないかとは思ぅんですが。話の流れとして一応説明文を入れてみたり。

しかしこのショートカットキー、とても全部の機能をキーに割り当てることなんか、大抵のアプリケーションでは機能数が多すぎてできません。ので、多数派の方が一般的に使うだろぅ機能に絞って初期実装しておくのがふつーです。そーでないショートカットキーを使いたいなら、自分でカスタマイズせいよ、と。

たとえば、秀丸。
私、インストール時にデフォルトで表示されるツールバーもファンクションキー表示もOffにしています。なんかテキストエディタをマウスで操作するのが邪道なとくな気がしまして。
ところがBOX選択(矩形選択→カット&ペーストできる機能)はツールバーに登録されている(らしい)ので、ショートカットキーには登録されていません。
この機能は便利で多用していますので、独自のショートカットキーShift+F5に自分で割り振って使っています。

ところが。

Excelは、ショートカットキーのカスタマイズができないんです。

もぅ、あくまでもデフォルト値で使えと。変更は許さんぞと。マニュアルにも固定でがっちり書いてあるぞと。

ここまでがっちり固定されているのではやむを得ません。あとは自分の方をExcelの操作性に近づけるしかないんですけど…セルを結合するたびに右クリック→[セルの書式設定(F)...]-[配置]タブの「セルを結合する(M)」チェックボックスをいちいちOn/Offしなければならんのはなんとかなりませんか。手をキーボードとマウスの間でひっきりなしにひらひらさせて、どこに出てくるかいまいちわからないダイアログボックスに目を光らせるのがどんどん苦痛になっていくんですけど。

あぁWordならばキーカスタマイズができるのにできるのに。だから私はやはりWordに。



などと日々苦しみ悶えていた私に、福音のようなサイトが降臨しました。

玉蔵さんが運営されているEXCEL生産性向上委員会

まさに目からうろこ。

詳しくは[personal.xls 強化講座]-[ショートカット機能の追加]のあたりをご覧いただくとして。
ざっくり言ってしまえば、起動時マクロ([PERSONAL.xls]-[Auto_Open()]プロシージャ)にショートカットキーの割り当てを書いてしまえと。でそのキーを押した時にどーいぅ動作をしてほしいかもVBAで組んでしまえと。

さらにこのページではむちゃくちゃ実用的なショートカットキー割当て用プロシージャもどっさり公開されています。
自分にフィットする機能をいくつか取り込んで、ワンタッチでセルを結合したり文字配置を右揃えにしたりして日々さくさくと設計書を書けるよぅに。う、嬉しいよぅ。



さて。
実はもぅひとつ、Excelの操作性について前々から大不満に思っていたことがあります。

行選択。

一応Excelでは、Shift+Spaceで行選択、Ctrl+Spaceで列選択ができるよぅになっています。キーボードだけでこの機能が使えるのであれば、Shift+[↓]連打で不要な行のセルをてきとーに複数選択しておいてからShift+Spaceで行選択、ショートカットキーでショートカットメニューを表示させてから[D]で一発行削除。なんてことができます。逆に[I]で、ほしいだけの行を一発挿入なんてこともできます。

Excel上で文章を推敲するにはどうしても必要なんです、これ。今この文章のここに着目しているのに行が足りなくて文章が足せない、なんて時に行番号表示領域に目を移す心の余裕があるわけもなく。

ところがこのShift+Space、

IMEがOnになっている時には使えません。

反対のスペース(全角スペースがデフォルトになっている時には半角の、半角スペースがデフォルトになっている時には全角のスペース)が入力されてアクティブセルが入力モードに入っちゃうんですね。

いゃ確かに元祖英語版Windowsには全角スペースなんて概念はありませんけど。おこぼれで対応いただいている日本語版ですけど。IMEとの相性なんてアメリカの皆さんは考えたことないんでしょうけど。

あまりにもおそまつすぎやしないかい。

どちらかといぅと、この場合IMEは悪くないと思ぅんですよ。ATOKでも同様の動作しちゃいますし。ので、これはもぅShift+SpaceをIMEがかっぱらわないと思い込んだデザインのExcelが悪い。

しかし。どーしてもキーボードからの行選択機能を使いたいんです。私にとっては、一日に仕様書を3本書けるか2.5本しか書けないかくらいの作業効率のせとぎわなんです。

行選択する際にIMEをOffにする。

これであれば確かにShift+SpaceはExcelがフックするよぅになりま却下
文章を編み出している最中にAlt+[半角/全角]なんかそぅそぅ連打してられません。それでなくても複数のアプリケーション立ち上げてAlt+TabやCtrl+Tabで切り替えまくりながら、DBのカラム(フィールド)設計なんかしている時にはShift+CapsLockまで押したり押したりしながら作業しているのに。似たよぅな位置にひんぱんに使うキーありまくり。で誤操作しまくり。
おもに左手の中指方面が軽くパニックになりました。

IME側の反対のスペースキー割当てを変更する。

Shift+SpaceをExcelでしか使わないショートカットに位置づけてしまえば却下
もぅ何年もShift+Spaceで全角と半角のスペースを使い分けてきたんです。テキストエディタやメーラでこれを自由に入力し分けられないとこれはこれで作業効率落ちまくりです。

ので。
EXCEL生産性向上委員会を本歌にいただいて、行選択ショートカットキーを自作してしまいました。

やり方は簡単。まず、次のようなプロシージャをPERSONAL.xlsに記述します。

Sub RowsSelect()

Dim intSttRow As Integer
Dim intEndRow As Integer
Dim strRows As String
Dim i As Integer

'*** 対象行バッファの初期化
strRows = ""

'*** 全ての選択領域の取得→対象行バッファへ格納
' (複数選択領域に対応)
For i = 1 To Selection.Areas.Count
If (strRows <> "") Then strRows = strRows & ","
intSttRow = Selection.Areas(i).Row
intEndRow = intSttRow + Selection.Areas(i).Rows.Count - 1
strRows = strRows & CStr(intSttRow) & ":" & CStr(intEndRow)
Next

'*** 選択領域の行選択
Range(strRows).Select

End Sub
PERSONAL.xls内なら特に記述場所はいーよぅな感じです。まぁ標準モジュールをこしらえて、その中に入れるのが筋ですが。

あとはこのプロシージャをShift+Ctrl+Spaceで呼び出せるよぅ、同じくPERSONAL.xlsのAuto_Openプロシージャ(こちらは標準モジュール内に書くのが当たり前ですね)に、以下の記述を追加しときます。

Sub auto_open()

'*** Shift + Ctrl + △ 行選択
Application.OnKey "+^ ", "RowsSelect"

End Sub
いかがでしょぅ。私、ものすっごく使いやすくなったんですが…わ、私だけ?


おまけ。

ヘルプを見ていると、Ctrl+Shift+:で、アクティブセルに時刻が挿入できるといぅことになっています。が、実際に操作してみると、時刻が挿入されるショートカットはCtrl+「:」(コロン)です。
ちなみに日付挿入はCtrl+「;」(セミコロン)。

これはどーいぅことなのか。

実は、Microsoft製品のヘルプ群は、そのほとんどが英語版の直訳です。日本語訳スタッフはいちいちその記述が正しいかどぅかのウラをとっているわけではないらしい証拠がさまざまなヘルプやmsdn Libraryなんかで散見されます。

どぅも英語版Excelの操作では正しくCtrl+Shift+:で時刻挿入の動作をするみたいですなんですよね。

私たち日本人(あるいは主に日本で生活している方)がふつー使っているのは、日本語対応の106/109キーボードといぅ仕様の奴です。それに対して英語圏の方々は、英語用の通常101/102キーボードを使っています。

101/102と106/109キーボードは、記号のキー割付が違うんです。106/109キーボードでは「;」(セミコロン)と「:」(コロン)は別々のキーで隣り合っているんですが、101/102キーボードではこの2つは同じキーに割り付けられているんですね。そのまま押すと「;」、Shift+で「:」となります。

つまりヘルプが言いたいのは、

Ctrl+「;」で日付、Ctrl+「:」(=Shift+「;」)で時刻が挿入できる

ってことなんでしょう。

でも106/109キーボードでは「;」と「:」は別のキー。Shift+なしで「:」は入力できてしまいます。Ctrlを押した状態で「:」が入力できれば時刻挿入の動作はするわけですから、

日本語版Excel(てゅうか106*109キーボードを使っているときのExcel)では
時刻挿入にShift+は不要

といぅことになるわけです。

2002年02月24日

03 個人用マクロブック

Excelでのマクロ(VBA)を格納する先はいくつか選択できるよぅになっていますが、その中の個人用マクロブック。これは、一度登録してしまえばExcelの起動と同時に読み込まれ、どのブックに対しても有効になるよぅになっています。

さて、実際にはこの個人用マクロブックといぅのはどこに格納されているなんといぅファイルなのか。

私の環境では、C:\Documents and Settings\salvage\Application Data\Microsoft\Excel\XLSTART\PERSONAL.XLSでした。
一般的にいぅと、%USERPROFILE%\Application Data\Microsoft\Excel\XLSTART\PERSONAL.XLSってことになりますね。

実はこれ、複数のユーザ環境で共有ができます。

誰かの当該環境にPERSONAL.XLSを作っておいて、他の人のユーザ環境当該フォルダにはショートカットを置いておけばOK。わははは、安易。

ついでにいぅと。このPERSONAL.XLS、Excel2000とExcelXPで共通仕様っぽいです。同じファイルがどちらでも動作可能でした。
Excel2000とExcelXPとでVBAがまったく同じかどぅかの確認はとっていませんので、たまたまかもしれませんが。

じゃってんで、ツールバーカスタマイズ情報なんかが格納されているファイルの共有も効くかも。ってやってみたんですが、こちらは失敗。

どちらも%USERPROFILE%\Application Data\Microsoft\Excelに格納されるんですが、ExcelXPの場合はExcel10.xlb、Excel2000の場合はExcel.xlbでした。
ファイル名のつじつまを合わせてもエラーが出てしまいます。こちらも共用できるとなかなか便利になりますので、なんか別の方法がないかもぅ少し調べてみよぅと思っています。



さて。
話がPERSONAL.XLSまで行ったところで。次回からはExcel VBAにまつわるエピソードを紹介していこぅと考えています。
このOfficeVBAはふつーのプログラミング言語と違って、組み込みや使い回しにはユーザ側の知識も必要なんですね。ので、最低このくらいの理解はしといていただかないと、この先ついてきていただけそぅにありません。

2002年02月23日

02 Excelの新規作成

でまぁ、好きと嫌いに関わらず。使ぅ以上は使い込んでみせよぅではありませんかExcel。

でも、Excelはけっこぅ他の方がいろんなサイトで言及されていますし。掲示板やMLも、Office関連では一番賑わいを見せていますし。いゃ大抵のことはこのへんで捜せばなんとかなっちゃうんですよね。

他でやってることはそっちにまかす。

てゅうのがめんどくさがりな私のポリシーですので、本サイトでは他ではついぞ見かけない、といぅと聞こえはいいですがすきま家具っぽいスタンスで。むだなすきまを有効活用。ってなんだそれ。



でまず。新規作成

Excelをスタートメニューから起動すると、まずBook1.xlsが開きます。

これはインストール直後の環境では、確かMSPゴシック11Pt.となります。

これでは画面表示行列数も少なく、印刷時も妙に文字がでかい。
といぅ場合、行列見出しの接合部(左上の灰色の、何も書いてないマス)をクリックして行列を全選択→右クリック→[セルの書式設定(F)...]→[フォント]タブで一斉変更。

…いぇ、いぃんですけどね。それでも。できるし。

でも、行列見出しの「A」とか「1」とかのフォントはMSPゴシック11Pt.のままでカッコ悪いですし、保存した時のファイルサイズも若干ですが大きくなっちゃぅ。しかも新しいシートを追加するたびにフォント修正の手間が必要となります。

あんまりスマートではないでしょぅ?

そんな時には、初期設定を変更しちゃいましょう。

メニューバーから[ツール(T)]-[オプション(O)...]-[全般]タブの、[標準フォント(A):]であらかじめ設定しておけば。新しく作るファイルの初期状態を指定できます。
ついでに、ふつー1つしかシートを使わないよなんて方は、同じタブにある[新しいブックのシート数(S):]の値も変更しておけばより吉ですね。

以上の設定で、Excel起動時のBook1.xlsも、メニューバー/ツールバーからの新規作成も、Ctrl+Nでの新規作成も、自分好みのフォント&シート数で作成できるよぅになります。



次、行きます。

さて、実は上記の方法での設定は、Excelを起動した上で新しく作成する時にしか反映されません。
エクスプローラで右クリック→[新規作成(W)]-[Microsoft Excel ワークシート]を選択して、と操作した時に出来上がるファイルはインストール時の状態のままです。

これが実に気にくわない。

仕事でいろんなファイルをイジりまくっていると、どぅしてもフォルダの階層は深くなります。自分のマシンだけではなく、サーバやら他のマシンの中へも入っていったりもしますので、扱うフォルダが広く深くなってくるわけですね。

ですから私は作業中、常にエクスプローラの4つや5つは同時に立ち上げてたりもします。

なのに、Excelを起動してからしか新規ブックを作成できない状態では。

初回保存するたびに、保存ダイアログボックス相手にフォルダをひとつずつ上がったり下がったりしなければなりません。
まぁそれでもダイアログボックスのサイズを拡げたりなんだりとWin95の頃よりは使いやすくなってきてはいるんですが。

しかしやはり右クリック→[新規作成]をなんとかしたい。

この操作方法ではExcelを起動していない状態でブックファイルを作れるわけですから、何らかのプログラムが1から作り起こしているとは考えにくいです。から、単純にどこかにとってある元ファイルをコピーしてきているくらいなだけなはず。

では、その元ファイルはどこにあるなんといぅファイルなのか。

OSの動作から使用されるファイルですから、まずはシステムドライブ(OSのインストールされているドライブ)にあるんではないでしょぅか。
ふっふっふ、そーいぅ時に捜しやすくするために、ほとんどのWindows関係とかアプリ関係のフォルダは初期値のままCドライブに突っ込んであるのでした。

エクスプローラの[検索]機能を使って、C:\以下の*.xlsを全検索。

…ありましたありました、それらしいのがいくつか。

ここまで来れば。アヤシそぅなブックファイルを全部開いて、それぞれに目印代わりに別々の文章を挿入して上書き保存。

その上で右クリック→[新規作成]をしたら…

ビンゴっ!C:\WINNT\ShellNew\EXCEL9.xlsがそれだっ!

このファイルを自分の好きな状態にカスタマイズして入れておけば。
フォントやシート数のみならず、シート横スクロールバーのサイズだろぅがヘッダ/フッタだろぅがもぅ自由自在。

もぅExcelからの新規作成なんて不自由な方法はおさらばさっ!時代はエクスプローラ右クリックだぜぃ。

でも、ExcelXP(Ver10)でも「EXCEL9.xls」なのねぇ。Accessも9だしWordなんか8だし。10だったのはPowerPointだけでしたよ。



さらに次。

さてエクスプローラ右クリックの時に元ネタにするファイルは突き止めたわけですが。
あり場所がOS用のフォルダの中ですし、個人用設定フォルダ(デフォルトではC:\Documents and Settings以下のログインIDの名前が付いているフォルダ)の中にさらに元ネタファイルがあるわけではないので、どぅもこれはユーザ単位ではなくマシン単位での元ネタのよぅです。

自分専用のマシンであるならそれでもいいんですが、他の人と共用しているマシンではそぅそぅわがままな初期設定にもできないしなぁ。

ってことで、もぅ少しツッコんで調べてみることにします。

Win2000はOS自体を任意のドライブ/フォルダにインストールできますし、OfficeXPだって好きなところにインストールできるわけですから、元ネタの捜し方がフォルダ決め打ちだったりどこかを基準とした相対パスではない可能性も十分に考えられます。

であれば、その情報が入ってるくさいのは、レジストリが一番可能性高いよな。って推測もできたりします。

そこで今度はレジストリの検索。
レジストリエディタを起動して、一番頭から「EXCEL9.xls」で検索してみました。

またビンゴっ!
HKEY_CLASSES_ROOT\.xls\Excel.Sheet.8\ShellNew の中の
FileNameがそれだっ!

ここに書いてある内容はEXCEL9.XLS。
ドライブ/フォルダをまったく書いていないファイルだけのデータ、ってことは、デフォルトでC:\WINNT\ShellNewの中を見に行ってるってことです。

…だめかなぁ…

いゃ、あきらめない。

ここをドライブ名からのフルパスに書き換えたらどぅなるか?
たとえば、ってんでHKEY_CLASSES_ROOT\.xls\Excel.Sheet.8\ShellNew\FileNameの値を"C:\Documents and Settings\salvage\Templates\excel999.xls"とかに書き換えてみました。
もちとんその指定先にはexcel999.xlsを置いといて。

あ。できるよ。

そこでもぅひとがんばり。

フルパスで書き換えることができることはわかりましたが、これではまだログインユーザごとに参照先を切り替えられるわけではありません。
レジストリのクラスがHKEY_CLASSES_ROOTですから、ユーザ単位ではなくマシン単位での設定ですしねぇ。

…あ。環境変数はどぅだろ。

コマンドプロンプトを立ち上げてSETコマンドで環境変数一覧を見てみたら。

ありましたありました。USERPROFILE=C:\Documents and Settings\salvageですって。

ので先ほどのHKEY_CLASSES_ROOT\.xls\Excel.Sheet.8\ShellNew\FileNameの値を、今度は"%USERPROFILE%\Templates\excel999.xls"とかに書き換えて再度チャレンジ。

…よしっおっけえぇぇぇっ!!

この環境変数はログインするユーザごとに個人フォルダのパスをキープしますので、レジストリ側がさし変わらなくてもユーザ単位で参照先を切り替えることができます。
ただし個人フォルダ内での相対パスやファイル名は揃えとかないとだめですけどね。
まぁどぅせここまでセッティングするなら手作業でするしかないわけですから。

2002年02月22日

01 私がExcelを使ぅわけ

私、Officeの中ではWordが一番好きなんです。あのびみょーなオートコレクトといぃレイアウト自動修正といぃ、もー寄せては返す恋人たちの甘いがしかし不毛な会話のごとき反応を見越して裏をかいて屈服させるのが。Word VBAなんかと来た日にゃ、なるほど文書はこぅオブジェクト化するのかとシニカルな意味で目からうろこ落ちまくり。

などとうがった嗜好の話は置いといて。

お仕事で定義書とか設計書とか書いていますと、やっぱ一番文書作成に使われるのはExcelだったりします。自動でうじょうじょと妙に段差ができたり隙間が空いたりするWordより、四角四面な編集作業ができるExcelの方が日本人好みだったりするんだと思います。



昔のパソコン用日本語ワープロの文字サイズは、等幅フォントの全角と半角(あとせいぜい縦横倍角と4倍角)しかありませんでした。
段下げして桁を合わそぅと思ったら、もぅスペース連打ですよ。そして、そのきっちり感が日本人の几帳面な感性にジャストフィットだったわけですよ。

んでもって、何でそこまで日本人は等幅フォントを好むかといぅと、活版印刷がそぅだったからなんですよ。

筆字の頃の日本文字は、一文字一文字大きさが違って当たり前でした。縦にも横にもサイズばらばらで、しかも中心線を縦に合わせるタイプのデザインだったために、これが印刷技術を輸入した時にとても活字化できなかったんです。

であれば。同じ大きさのマス目を先に用意して、画数が多かろぅと少なかろぅととにかく無理やりマスの中に突っ込んでしまえと。
で、原稿用紙のような縦横のマスの中に同じ間隔で文字を埋め込んでいくレイアウトでの印刷となって普及していったわけです。

さて輸入元のアルファベット圏の国(印刷の発祥ってイギリスでしたっけ?)では、せいぜい縦に3段階、横に3段階の段差しかありませんでしたし。横書きでしたし。文字の基準線を最下位置よりちょっと上に揃えた数十種類の活字を個々の幅にはお構いなしに横にだだだーっと並べてしまえばでき上がりでしたので、文字幅はひとつひとつ違ってて当たり前だったんです。

これが、タイプライタの出現により i も m も同じ幅で並べざるを得なくなってしまいました。タイプライタって、1回打鍵するごとに1文字分ドラム(紙を巻きつけるところ)を左にずらす機構が組み込まれていまして、だから連続でだかだか打っても同じ位置へではなく右へ右へと文章が進んでいくんですけどね。まさか機械式(歯車式)の機械で、打つ文字の種類に応じてシフト幅を変えるわけにもいかず。

どぅもこの可変シフト、やろぅと思えばできたみたいなんですけど、当時のタイプライタってむちゃくちゃよく壊れたらしいんです。タイプライタが壊れたからどーのってジョークが聞き飽きてサムい位置付けになってしまうほどに。のであまり複雑な機構にするとより壊れやすくなるってんで(あるいは商品化されたのかもしれませんが)さほど普及しなかったよぅなんですね。

しかしその間も、印刷物としてはプロポーショナルフォントなわけですよ。こっちの方が文書として美しい、といぅ美的感覚の中で暮らしているわけですよ。

ので、パソコンのスペックが十分に上がってプロポーショナルフォントを縦横無尽に使いこなせるインフラが整った途端。

Wordでびしっとプロポーショナル。

なんせ美意識の具現化ですもん。そりゃぁ皆さん飛びつきますわな。

さて、話を日本に戻して。

欧米がプロポーショナルフォントにこだわるのとまったく同じいきさつで、日本は等幅フォントにこだわるわけです。
しかも和文タイプは原則等幅(活版印刷と同じ活字を使いますしね)だったので、欧米のよぅなタイプライタによる屈辱→プロポーショナル文書への届かぬ想い、なんて時期がありませんでした。
もぅ

ビバ等幅というか等幅天国というか。

ですから、Wordのデフォルトがプロポーショナルになっちゃったのはむちゃくちゃ気持ち悪かったんですね。特に和文タイプを常設していたお役所/大企業関係。

ですから、和文タイプによる文書提出は認めるがワープロによる文書は認めない時代→ワープロ文書も認めるが等幅文書に限る、なんて時代が実際にありましたもん。

日本製表計算ソフトがぼろ負け(1-2-3とMultiplan→Excelがシェアを圧倒してました)したのに対して日本製ワープロがわりと善戦しているのは、ここらへんの国民性が深く影響しているんだと思います。



しかし。さすがにMicrosoftの販売戦略の元に一太郎も職場でメジャー、とはいかない状況になってしまいました。が、うにょうにょWordには抵抗感ありありといぅ感性も廃れきってはいません。

Windowsになじんだ世代はプロポーショナルフォントもさほど悪印象を持たれていないよぅなんですけどね。でも図表の組み込みにくさとか文字とのシンクロ具合の悪さとかもありますし。

てなわけで、やはり設計作業にはExcel。個人的な嗜好は置いといて私も追従。お仕事ですからってなぜにこんなにびみょーに使いにくいですかExcel。のばか。