Excelで開いていないブックのシート一覧を取得するには、ブックの中を自分で探すしかありません。
Excelのブックはバイナリ交換ファイル形式(BIFF)と呼ばれるフォーマットで記録されており、BIFFのレコード名などがわからないと独学で解読するのは難しいでしょう。シートの一覧を取得するのは比較的やさしいので、ここでは仕組みと考え方をご紹介します。
BIFFのレコードは、基本的に次のように記録されています。また、下位バイトが先に記録され、上位バイトが後に記録されますので、実際に読み込むときは下位バイトと上位バイトをスワップしなければなりません。
1バイト目 | 2バイト目 | 3バイト目 | 4バイト目 | 5バイト目以降 |
レコード番号 | レコードデータ長 | レコードデータ |
たとえば、シート名が記録されるBOUNDSHEETレコードのレコード番号は85hで、次のように記録されます。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13~ |
レコード番号 | データ長 | lbPlyPosフィールド | grbitフィールド | シート名の長さ | シート名(可変) |
lbPlyPosフィールドは、実際のシートデータが記録されている位置へのオフセット値が記録されます。ここへジャンプすればシートデータを調べることができるわけです。当然ですが、この値はブックによって異なります。
grbitフィールドにはシートのタイプと表示/非表示の状態が次のように記録されます。
・1バイト目
00h:ワークシートまたはダイアログシート
01h:Excel 4.0マクロシート
02h:グラフシート
06h:Visual Basicモジュールシート
・2バイト目
00h:表示
01h:非表示
02h:再表示しない
シート名の長さは、バイト数ではなく文字数です。
では、具体的なデータで解説しましょう。ブックをバイナリエディタなどで開き、8500hを探して見ると次のようなレコードがあります。ここでは、Sheet1というワークシートを例にします。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
85 | 00 | 0E | 00 | 7D | 08 | 00 | 00 | 00 | 00 | 06 | 00 | 53 | 68 | 65 | 65 | 74 | 31 |
レコード番号 | データ長 | lbPlyPos | grbit | シート名の長さ | シート名 |
grbitが0000hなので、表示されているワークシートと分かります。もし非表示のワークシートでしたら0001hとなります。
シート名の長さは0006hで6文字ですが、ここで注意が必要です。BIFFの文字列はUnicodeで記録されます。Unicodeは文字ごとに2バイトのデータが必要ですが、BIFFはUnicodeを圧縮して記録します。ABCなどのアルファベットはすべて上位コードが00hなので、圧縮形式ではこの上位バイトを省略します。Unicodeが圧縮されているかどうかは、[シート名の長さ]の下位バイトで判断します。下位バイトが00hの場合はUnicodeが圧縮されています。下位バイトが01hのときは、文字列中に少なくとも1文字以上、上位コードが00hでない文字を含んでいるため、すべて2バイトで記録されています。
上記の例Sheet1の場合は圧縮された6文字ですので、上位コード00hを補完すると次のようにシート名を取得できます。
0053h→S
0068h→h
0065h→e
0065h→e
0074h→t
0031h→1
「田中A1」というワークシートの場合は次のようになります。「A1」は半角英数字です。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
85 | 00 | 0E | 00 | 7D | 08 | 00 | 00 | 00 | 00 | 04 | 01 | 30 | 75 | 2D | 4E | 41 | 00 | 31 | 00 |
番号 | データ長 | lbPlyPos | grbit | シート名の長さ | シート名 |
シート名の長さは4文字ですが下位バイトが01hなので非圧縮のUnicodeです。
30 75 2D 4E 41 00 31 00 の上位バイトと下位バイトをスワップさせると、75 30 4E 2D 00 41 00 31 となり、
7530h→田
4E2Dh→中
0041h→A
0031h→1
というシート名を取得できます。
続いてシートが存在する場合は、シート名の後ろに8500hから始まるBOUNDSHEETレコードが記録されます。
BIFFの仕様と仕組みを解説しましたが、シート名を取得する具体的なVBAサンプルは示しません。上記の解説でロジックがわかるはずですし、もし解説を読んでもロジックがわからない方は、危険ですからブックを直接編集するのは止めた方がいいでしょう。