月刊プログラム!
Visual Basic For Excel

Vol_12
2001.JUL.14

Presented by kouta_y
感想等は掲示板、苦情はメールへ。

にこちゃん
おぉ!?もう12号いってるゾ!
前回・前々回と気が付かなかったよぉ・・・。
果たして、これ全部読んでくださっている読者はいるのだろうか・・・?


ファイル操作もうちっと高度に

前々回にファイル操作関連をやりました。
今回はその続きと思ってください。

結構、ファイル操作ってのは慣れてくると面白いもんで、やってく内にファイルの操作だけでなく、「文字列の扱い」「ファイルの形式」「バイナリの意味」など
いろんなものが見えてきます。
今回もその触りの部分的な幹事感じなんですが、ファイル操作関連でよく使いそうな関数をまとめてみました。

まず基本コード

'FileStatus構造体
Type
FileStatus
    Name   As String
    Rows   As Integer
    Size   As Long
    Data() As String
End Type

Sub
File()
Dim fs   As FileStatus
Dim NO   As Integer
Dim Data As String

'
'ChDir()  : カレントディレクトリ移動関数
'CurDir() : カレントディレクトリ名取得関数
'

Call ChDir$("\") 'ルートディレクトリへ移動
fs.Name = CurDir() & "windows\win.ini"

NO = FreeFile()
Open fs.Name For Input As #NO
     Line Input #NO, Data
Close #NO

Cells(1, 1).Value = Data
End Sub

実行結果:



はい。ここは全然簡単ですね。
構造体については、後で使いますので、今は深く考えないで良いです。

おそらくWindows使ってる人ならば、多分みんな同じような結果が返ったと思います。
違う人もいるかも知れませんが、読み取れてればOKです。


サイズを取得

では次に「ファイルのサイズの取得」をやってみましょう。
この、「ファイルのサイズ取得」方法は、現在開いているファイルにのみ有効な方法です。
下の様にコードを追加してください

 ・
 ・
 ・
--- ↓こっからが変更行 ---

NO = FreeFile()
Open fs.Name For Input As #NO
    fs.Size = LOF(NO) 'ファイルのサイズを取得
   Line Input #NO, Data
Close #NO

Cells(1, 1).Value = Data
Cells(2, 1).Value = fs.Size
End Sub

実行結果:



LOF関数。
ファイルの長さ取得関数です。(ファイルのサイズは、よく「長さ」と呼ばれます。文字列の文字数?もよくそう呼ばれる)
たぶん「Lenth Of File」の略です。
ファイルのサイズは個々に変わると思います。
えー。これは「Win.ini」ファイルのサイズを取得しました。単位は「Byte(バイト)」です。
K(キロ)にしたい時は「/1000」すればOKです。つまり作者の「Win.ini」は9.85KBだという事です。


行数を調べてみる

では次に、ファイルの行数を調べます。
行数調べるなんて滅多にないんですが、EOF関数の使い方と、後に出てくる「行ごとの内容取得」の副産物です。

【1行の定義】
えーと、突然変な事を書きますが、この辺りはまだ覚えなくても問題は特にないです。頭の隅の方にでも入れといてください。
1行とは、どっからどこまでの事なのか?
メモ帳とか、いろんなテキストエディタなソフトを使って、テキストファイルを開くと、「改行」とか勝手にされてて見やすいですね。
そうですね。その「改行」されている所までが「1行」となります。
次の行は、その「改行」から1文字目から始まります。

ではその「改行」ってどうやって「改行」だと認識してるのでしょうか?
はい。答えは「文字コード」で判別しています。
よく「String型」変数を使ったりして文字列を格納します。
でも実際は「文字コード」がその変数に格納されていて、表示させる時には「現在のフォント」とかにあわせて表示させています。
「文字コード」は1バイトで0〜255(16進:0〜FF)までしか判別出来ません。
よく「半角1バイト、全角2バイト」と言います。半角文字であれば0〜255で十分判別出来る範囲みたいです。

えっと、前置きが長くなりましたね。(++;
「改行」の文字コードですが、これは「10(16進:0A)」になります。通称「ラインフィード」文字と呼ばれます。
あともう1つ「キャリッジリターン」、コードは「13(16進:0D)」というのもあります。

エディタの設定、もしくはエディタ自体によって違ってくる時もあるんですが、、、
メモ帳なんかは、この2つの組み合わせで「改行」となります。(フォントによってはどっちか1つでも改行となります)
ほぼ全てのテキストエディタなソフトは、この「10もしくは13」を1文字づつ読み取って、判別しているんです。大変ですね。
ちょっと長くなりましたが、「1行の定義」わかりましたかね?
文字コードとあわせて、一挙両得ですね!(笑)


では、さっきの続きで「ファイルの行数」です。
下のコードを変更追加してください。

 ・
 ・
 ・
--- ↓こっからが変更行 ---

i = 0
NO = FreeFile()
Open fs.Name For Input As #NO
    fs.Size = LOF(NO) 'ファイルのサイズを取得
    Do While Not EOF(NO)
        Line Input
#NO, Data '使いまわし(あんまよくない)
        i = i + 1

    Loop

Close #NO
fs.Rows = i

Cells(1, 1).Value = Data
Cells(2, 1).Value = fs.Size
Cells(3, 1).Value = fs.Rows
End Sub

実行結果:



EOF関数。
ファイルの末端(EOF)かどうかを返す関数です。
「End Of File」の略です。

ファイル操作では、よく使うので覚えてください。
現在の読み込み位置が末端にきたら「True」を返します。
作者の「Win.ini」ファイルはEOFを除いた行が「549行」あったって事ですね。
この原理としては、「Input」を実行後、通称「ファイルポインタ(読み込み、もしくは書き込み位置)」というものが、
読み込んだ分(つまり1行分)ズレる原理を利用したものです。
この辺は簡単ですね。


1行づつ内容取得

それでは最後に「1行づつ内容取得」です。
ここは、前の方でやった「配列」を使います。配列の使い方のポピュラーな例でもあります。
では追加・変更コードです。

 ・
 ・
 ・
--- ↓こっからが変更行 ---

'ReDim fs.Data(0 To 0) As String '配列の要素数変更
i = 0
NO = FreeFile()
Open fs.Name For Input As #NO
    fs.Size = LOF(NO) 'ファイルのサイズを取得
   Do While Not EOF(NO)
        ReDim Preserve
fs.Data(0 To i) As String '前のデータを残したまま要素数変更
        Line Input
#NO, fs.Data(i)
        i = i + 1

    Loop

Close #NO
fs.Rows = i

Cells(1, 1).Value = Data
Cells(2, 1).Value = fs.Size
Cells(3, 1).Value = fs.Rows
For i = LBound(fs.Data) To UBound(fs.Data)
    Cells(4 + i, 1).Value = fs.Data(i)
Next i

End Sub


実行結果:

実際は500何十行まで続いています。


はい。こんな幹事感じですかね?
Redimとかの詳しい意味はヘルプを見てくださいな。(無責任者)
まぁこんくらいなら最初から「Data(0 to 1000)」とかってやってもOKですけどね。
メモリが膨大な領域まで使える今日この頃のパソコンですが、なるたけメモリの無駄遣いはやめときましょう。(なんとなくヤだから。僕は)


お終い

あと、もう1コよく使う関数で「Seek」というのがあります。
これは現在のファイルポインタを移動したり、取得出来たりするものです。
実際どういう動作するかはご自分で試してみてください。(無責任じゃないよー、自分で見てみるのがやっぱ一番!)
Seek関数を利用すれば、LOF関数でなくてもファイルサイズを取得出来たりします。

えーっと、こんなトコロが「よく使うファイル操作関連」ですかね?
まぁ今回は「読み込み」を主として話を進めましたが、書き込みも大体こんな感じでやってけます。
気が向けば、書き込み関連も詳しくやるかもしれません。

そうそう、今回サンプルで利用したマクロを下からダウンロード出来る様にしました。
今まではExcelブックを本体でしたが、今回はモジュールファイルのみです。
(ウィルスとかの関係。別に今までのブックで発見されたわけではないです。感染されたら怖いからってこと)
実際に動作させたい方は「インポート」してください。
やり方わからない方は、聞いてくれれば教えると思います。

Module1.lzh
619バイト(圧縮するまでもない・・・)