非表示ブックの数を返すFunction(Excel)
非表示Bookの数を返すFunction
アドインとか、個人用マクロブックみたいな、ブックを開いたら裏で勝手に開いているブックの数と、オモテで正々堂々と開いているブックの数を別々に取得する必要があったので作ってみた。
考えかた
Application.Workbooks
コレクションのCount
プロパティは、表示/非表示に関係なく、開いているブック全ての数を返すっぽいので、Workbooks
コレクションの要素ひとつひとつを調べるしかないと思った。
非表示ブックの拡張子は、たぶん「xlsb
」、「xlt
」、「xltm
」、「xla
」、「xlam
」の5つっぽいので、拡張子で判定できると思った。(実は「テンプレートファイル」ってのが何のことだか分かっていないので、「xlt
」と「xltm
」は入れておくべきなのかどうなのか分かっていない。←調べろよ!)
コード
リスト1 標準モジュール
Public Function getHiddenBooksCount( _ ByVal excelApp As Excel.Application) As Long Dim ret As Long ret = 0 Dim Wb As Workbook For Each Wb In excelApp.Workbooks If isHiddenBook(getExtentionString(Wb.Name)) Then _ ret = ret + 1 Next getHiddenBooksCount = ret End Function Private Function getExtentionString( _ ByVal targetFileName As String) As String Dim positionOfDot As Long positionOfDot = InStrRev(targetFileName, ".") Dim ret As String ret = Right(targetFileName, Len(targetFileName) - positionOfDot) getExtentionString = ret End Function Private Function isHiddenBook( _ ByVal targetExtention As String) As Boolean isHiddenBook = True Dim ar As Variant ar = Split("xlsb xlt xltm xla xlam") Dim i As Long For i = LBound(ar) To UBound(ar) If StrConv(ar(i), vbLowerCase) = _ StrConv(targetExtention, vbLowerCase) Then _ Exit Function '……(*)' Next isHiddenBook = False End Function
メインのgetHiddenBooksCount
から、getExtentionString
とisHiddenBook
を呼び出して、非表示ブックの数をカウントしている。
isHiddenBook
の(*)のところでStrConv
関数を用いているのがミソ。
単純に素の拡張子文字列で比較しようとすると、getExtentionString
で取得した拡張子が大文字だったら一致したと見なされないのである。
たとえば、個人用マクロブックの拡張子は「XLSB
」だった。
使ってみた
プロジェクトエクスプローラーは
この状態。
で、イミディエイト・ウインドウに
?getHiddenBooksCount(Application)
と入力して[Enter]をポチッ。
とりあえず意図どおりの結果が出た。
おわりに
テストが不十分なので、これで良いのかどうかはよく分かっていない。
追記
id:imihito さんからコメントをいただいたので、それを参考に修正。
id:imihito さんによると、
ブックが非表示になるのは `Workbook.IsAddin`がTrueのとき、
そして`Window.Visible`がFalseのとき
との由。
つまり、上記リスト1のisHiddenBook
メソッドを、
Workbook
オブジェクトのIsAddin
プロパティがTrue
または
Workbook
オブジェクトの全ての[Window].Visible
プロパティがFalse
だったらTrue
を返すようなものにすればよい。
リスト2 標準モジュール
Private Function isHiddenBook( _ ByVal targetBook As Workbook) As Boolean '……(1)' isHiddenBook = True '……(2)' If targetBook.IsAddin Then Exit Function Dim i As Long For i = 1 To targetBook.Windows.Count '……(3)' If targetBook.Windows(i).Visible Then _ isHiddenBook = False: Exit Function Next End Function
(1)の
Private Function isHiddenBook( _ ByVal targetBook As Workbook) As Boolea
もはや、引数からして変えた。別に拡張子で判定する必要はないし、ExcelVBAer (id:x1xy2xyz3) さんからいただいたコメントからしても、「.xlsb」のブックを非表示ブックとカウントしてしまうのはまずい。
よって、Workbook
オブジェクトを引数として受け取るようにした。
(2)からの2行
isHiddenBook = True If targetBook.IsAddin Then Exit Function
では、最初に返り値をTrue
にしておき、IsAddin
プロパティだったら即returnするようにした。
ここを通過すると、アドインではないことになるので、後はWorkbook
オブジェクトが持つ全てのWindow
オブジェクトを調べる段階へ進む。
(3)から4行(実質3行)がそれ。
For i = 1 To targetBook.Windows.Count If targetBook.Windows(i).Visible Then _ isHiddenBook = False: Exit Function Next
Window
オブジェクトのVisible
プロパティに1つでもTrue
のものがあったら、即False
をreturn、という仕組み。
再び、おわりに
これによって、getExtentionString
メソッドは用なし芳一と相成りました。