パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)
固定長文字列とランダムファイル (準備中)
--------------------------------------------------------------------------------
Visual Basicにおける固定長文字列とランダムファイルの操作について基本的な事項を書きます。
ランダムファイルを使ったプログラムの例はランダムファイル実例集にあります。
旧BASICにおけるランダムファイルの扱いについては、N88互換BASIC For Win95の
場合についてファイルの操作(ランダムファイル)にて書いています。
--------------------------------------------------------------------------------
Visual Basicでは、文字列に長さが固定の固定長文字列の指定ができます。
これは古いBasic(F-BaiscとかN88Basicなど)にはなかったものです。VB.netにも固定長文字列
というものはないようです。
固定長文字列の宣言の仕方
Dim s AS String*10
とすると、10文字に長さが固定された固定長文字列の変数が措定できます。
文字は半角英数(Ansi文字)でも全角の文字(平仮名、漢字等)でも、いずれにしても10文字分
になります。
Visual Basicは内部的には文字列をunicodeで扱っており、半角英数(Ansi文字)でも1文字に
2バイト確保されるようです。
固定長文字列の取り扱いには少し注意が必要なので
ちょっと以下の簡単なコードでVisual Basicの文字列の実験をしてみます。
Private Sub Command1_Click() Dim s As String Dim k As String * 8 Cls s = "s" Print s Print "Len"; Len(s); " : LenB"; LenB(s) k = "Cの基礎" Print k Print "Len"; Len(k); " : LenB"; LenB(k) Print k + "abcd" Print Trim(k) + "abcd" k = "Python実践講座" Print k Print "Len"; Len(k); " : LenB"; LenB(k) End Sub
実行結果
(図1)
まず最初に普通の文字列sを Dim s As String で宣言して
s="s" で文字変数sに半角英数文字(Ansi文字) s 1文字を入れます。
この時の文字列sの長さをLen(s)とLenB(s)で測ります。
Lenは文字数を、LenBはその文字列のバイト数を返す関数です。
Len=1, LenB=2 となりました。
半角英数文字(Ansi文字) s 1文字でも、文字変数sは2バイトになっています。
これは先に書いた通り、 Visual Basicは内部的には文字列をunicodeで扱っており、
半角英数(Ansi文字)でも1文字に2バイト確保するためです。
次にDim k As String * 8 として8文字の固定長の文字変数kを宣言します。
k = "Cの基礎" と半角英数(Ansi文字)を1文字("C"です)と全角文字3文字の形4文字を
文字変数kに代入します。
この場合は、Len=8, LenB=16となっており、文字変数kは8文字、16バイトの長さになっています。
"Cの基礎"の後に4文字分の空白が挿入されているようです。
Print k + "abcd" で表示させてみると、"Cの基礎"と"abcd"の間に空白があることがわかります。
固定長文字列では、文字の余りの部分には空白が挿入されるようなので、空白を取り除いて表示
したい場合は、Trim, Trim$を使います。
Print Trim(k) + "abcd" としたら、空白が削除されて"Cの基礎abcd"と表示されました。
最後はkに8文字を超える文字列を代入した場合にどうなるかを見ておきます。
k = "Python実践講座" としたら、固定長文字変数kには"Python実践"の8文字しか保存されなかった
ようです。8文字を超えた部分は切られてしまったようです。
Visual Basicではランダムファイルを扱う時に1レコードのレコード長は自由に設定できます。
しかし、レコードの中に文字列を含む場合は当然固定長文字列を使う必要があります。
ランダムファイルでのデータの入出力にはPut,Getを使いますが、この時の固定長文字列の
扱いが上記のプログラム中で使う固定長文字列とちょっと違うようなので注意が必要です。
(declarations) Private Type book name As String * 15 price As Integer End Type Dim bk As book Private Sub Command2_Click() Open "book.dat" For Random As #1 Len = Len(bk) bk.name = "Cの基礎" bk.price = 1200 Put #1, 1, bk bk.name = "Python実践講座" bk.price = 1800 Put #1, 2, bk Cls Get #1, 1, bk Print bk.name Print bk.price Get #1, 2, bk Print bk.name Print bk.price Close #1 End Sub
まず宣言部(declarations)で
レコードの構造を構造体で宣言しておきます。
ここでは本の名前と価格をメンバーとして持ったbookという構造体を宣言することにします。
Private Type book
name As String * 15
price As Integer
End Type
本の名前は15文字の固定長文字列とします。
変数bkをbookという構造体の変数として宣言したおきます。
book.datというランダムファイルをopenするときは以下のように書きます。
Open "book.dat" For Random As #1 Len = Len(bk)
ほぼ昔のBasicと同じ書き方ですが最後にレコード長をLen = で指定します。
レコード長は Len = Len(bk)として構造体変数bkのサイズを指定します。
nameがstring*15で15文字分=15バイト、priceはinteger(整数)なので2バイト分
あわせてレコード長として17バイト(※)が指定されました。
(※) LenB(bk)で構造体ノバイト数を測ると32という値が返ります。
string*15の固定長文字列は1文字に2バイト確保されて30バイト、これに整数型の2バイト
を加えて32バイトです。Lenを使う場合とLenBを使う場合でレコード長が異なることに
なるので注意が必要です。
ランダムファイルの入出力にはGetとPutを使うのは旧Basicと同じです。
書式は以下の通り。
Get #n, r, x
Put #n, r, x
#n ファイルバッファの番号を指定
r レコード番号を指定
x 変数
Len = Len(bk) で17バイトのレコード長が用意された時の実行例(図2)と、book.datをバイナリダンプして
みた例(図3)を掲載します。
(図2)
以下バイナリダンプした結果です。
@最初のレコード
43は半角の"C"
82CC8AEE9162は"の基礎"
以下8バイトは半角(Ansi)の空白2020202020202020が続いています。
その後のB004は整数で&H04B0=1200です。
全角文字は2バイト、それ以外は1バイトで保存されている点が、メモリに保存されている場合と
異なっており、ランダムファイルを扱う場合に注意しておきたい点です。
(図3)