新・闘わないプログラマ No.341

昼飯1回


Microsoft Excelは、Microsoft Office製品の中でも一番よく使っているアプリケーションです。逆に一番使わないのがWordでしょうか……いやいや、Outlookってのも入っていたような、これは全く使ったことありません。そもそもインストールしなようにしていますし。
表計算ソフトは、適当に表を作ったり、はたまた適当にデータ処理をしたり、なんてときに適当に使うとそこそこ便利ですね。もちろん、ガチガチのデータ処理だったり、データ量が多かったり、重い処理をやらせたり、なんて場合には別の方法を考えたほうがいいとは思います。でも、「適当にデータ処理をする」なんてのは結構ありがちで、そういうのにはExcel(というか表計算ソフト)は向いているわけです。

さて、先日、こんなやりとりがありました。
「Excelのオートフィルタの条件をセルに表示したいんだけど」
「マクロを使えば出来るんじゃないかなあ」
「そのマクロ作って!」
「自分でやれよ。前にExcelのマクロ本買ったよね?」
「だって、載ってなかったんだもん、そのやり方」
「そりゃあまあ、そのものズバリのマクロは載ってないかも知れないけどさあ。その本を手がかりにして調べてみれば?」
「まったくわからないんだってば。だから作って」
「……」
「んじゃさあ、昼飯1回でどお?」
というわけで結局、昼飯1回で手を打つことに…。

Excelのオートフィルタ機能というのをここで詳しく説明するだけの余裕もないのでそれは省略しますが、簡単に言えばRDBの「SELECT * FROM 表 WHERE 条件」みたいなのをワークシート上でやる機能です。ここで「条件」には表の各列の値の条件を指定できます。
Excelのマクロは、VBAという言語を使って書くわけですが、今回やりたいことは推測するに「オートフィルタ」がオブジェクトになっているだろうから、それのプロパティに多分入っているだろう条件を引っ張り出してきて、それを決められたセルに埋める、って感じかなあ、と。じゃあ、オートフィルタのオブジェクトはなんていう名前で、プロパティはなんていう名前なんだろうか、ということになります。これはVBAのヘルプで探してもいいのですが、オブジェクトもプロパティもいっぱいあって探すのが面倒です。そういう場合に使える手は「マクロの記録」機能です。これを使えば、人が操作したことをマクロとしてプログラム化してくれます。このプログラムを眺めてみれば、マクロ(VBA)からどういうオブジェクトをどういう風に使えばいいかが推測できます。
というわけでさっそくやってみました。やった操作は以下の2つ(使ったソフトはExcel 2000)。

その結果得られたマクロは、

    Sub Macro1()
        Selection.AutoFilter
        Selection.AutoFilter Field:=1, Criteria1:="3"
    End Sub

でした。どうやら「AutoFilter」というのがオートフィルタを表しているようです(そのまんま)。また、条件としては「Criteria1」というのがあるみたいです。これだけ情報が得られれば、後は、VBAのヘルプを見て、

等々のことがわかりました。これらを使って、表のタイトル行の上の行(タイトル行の上に1行空けておく必要あり)に、各列の条件(Criteria1のみ)を表示するマクロを作ってみました。

    Sub test1()
        If ActiveSheet.AutoFilter Is Nothing Then Exit Sub 'オートフィルタが無ければ何もしない
        With ActiveSheet.AutoFilter
            col1 = .Range.Column                           'フィルタ範囲の最も左の列番号
            row1 = .Range.Row                              'フィルタ範囲の最も上の行番号
            If row1 < 2 Then Exit Sub                      'フィルタ範囲の上に行が無ければ何もしない
            For i = 1 To .Filters.Count                    'フィルタの数だけループ
                With .Filters(i)                           'i番目のフィルタ
                    If .On Then
                        Cells(row1 - 1, col1 + i - 1).Value = "'" & .Criteria1
                    Else
                        Cells(row1 - 1, col1 + i - 1).Value = ""
                    End If
                End With
            Next i
        End With
    End Sub

とまあ、こんな感じのサンプルプログラムです。しかしこれ、このままですと手動でこのマクロを動かさないと値を更新してくれません。オートフィルタの条件を変更したら、セルに入る条件も自動的に更新して欲しいわけです。そこで調べて見たところ、AutoFilterオブジェクトはイベントを生成しないことが判明しました。AutoFilterオブジェクトが「Change」などのイベントを生成してくれれば、それをつかまえて上記のマクロを動かすこともできるのですが……仕方が無いので、WorksheetオブジェクトのSelectionChangeイベントでマクロを動かすことにしました。ううむ、いまいち。

ってな感じで納品(?)して昼飯1回の報酬を得たわけですが……この報酬ってもしかして所得税がかかったりしますか? って、それはどうでもいいのですが、面倒くさいので、今後はこれを参考にして自分で考えてください > 依頼者


2004.7.19 補足
「昼飯1回の報酬」にも所得税はかかりますよ、申告している人はいないでしょうけど、というメールをいただきました。やっぱり。

[前へ] [次へ]

[Home] [戻る]


mailto:lepton@amy.hi-ho.ne.jp