ユーザー定義型をファイルに書き込み


オレンジ  2008-04-18 00:15:15  No: 100579  IP: 192.*.*.*

VB6、XPです。

フォーム画面を作成。(フォームfrmMain)
テキストボックスを作成。(txtMidasi、txtName)
テキストボックスの値を、変数Midasi、変数Nameに設定。
ファイルに書き込む。(1レコード25バイト)

ユーザー定義型
Public Type DataType
    Midasi As String * 10 '見出し
    Name   As String * 15 '氏名
End Type

Public tbl As DataType

Public Sub test()
    tbl.Midasi = " "
    tbl.Name = " "
    tbl.Midasi = frmMain.txtMidasi.Text (定義型)と入力
    tbl.Name = frmMain.txtName.Text     (山田太郎)と入力
End Sub
↑  
ここで、Midasi、Name、のバイト数を
確認(LenB(StrConv(tbl.Midasi , vbFromUnicode))すると、
13バイト、19バイト となりました。

ファイルには、1レコード、見出しは10バイト、氏名は15バイトで
書き込みしたいのですが、全角で入力を行うと、バイトを超えてしまいました。

半角で試しに見出しを(MIDASI)と入力した所、ファイルには、10バイトで、
(MIDASI△△△△)←[△は半角スペースです]書き込みができました。

MidB関数で取り出してからセットするようにもしてみたのですが、
だめでした。
tbl.Midasi = MidB(frmMain.txtMidashi.Text, 1, 18)

全角で入力した場合、2バイトと判断して△スペースは判断できないのでしょうか?

どなたかアドバイスをお願いできませんでしょうか?

編集 削除
もげ  2008-04-18 08:58:00  No: 100580  IP: 192.*.*.*

>全角で入力した場合、2バイトと判断して△スペースは判断できないのでしょうか?

たとえば、
http://homepage2.nifty.com/Dee/
→VB,VBA,VBS,ACCESS情報屋  Tips 
→→VisualBasic,VBA関係
→→→文字列をSJIS換算のバイト数で切断出力する関数
とか

編集 削除
オレンジ  2008-04-18 10:47:16  No: 100581  IP: 192.*.*.*

もげ様、ご回答ありがとうございます。
動作させてみたのですが、ユーザー定義型の変数 Midasi に全角をセットすると

(あいう△△△△△△△)←△は半角スペースです。10文字でセットされ、
ファイルへは、13バイトで出力されるようです。

「Midasi As String * 10」 は、10バイトではなく、10文字とVBで判断されてしまいます。
ファイルへ出力する際、(あいう△△△△△△△)ではなく、(あいう△△△△)で出力したいのですが。
取り出してみても、ユーザー定義型の変数にセットするとダメなようです。

仕様でユーザー定義型を使用しなければならないのですが、何かよい方法はありませんでしょうか?

編集 削除
もげ  2008-04-18 11:55:19  No: 100582  IP: 192.*.*.*

いや、そうではなくて、
>「Midasi As String * 10」 は、10バイトではなく、10文字とVBで判断されてしまいます。
はい。文字数ベースで定義されていて、
VB内部ではUnicodeなので半角も全角も2バイトですね。
なので、
書き出すときにShift_JISのバイト単位で辻褄が合うようにしてみてください。

もしくは、
ユーザ定義型でバイト配列にしてShift_JISで値を保持する
書き出すときはバイナリ扱い
もアリかと思います。

「出力ファイルが10+15バイトになる」ことが仕様なのか、
「ユーザ定義型にすること」自体が仕様なのか、
ユーザー定義型を
Public Type DataType
    Midasi As String * 10 '見出し
    Name   As String * 15 '氏名
End Type
とすることが仕様なのか、
その仕様が上記VBの仕様を考慮した話なのか、
を仕様を決めた人に確認したほうがよいかもしれませんが。

編集 削除
YK  2008-04-18 16:31:58  No: 100583  IP: 192.*.*.*

こんにちは。
バイナリ用サンプルです。
標準モジュールに

'ユーザー定義型 書込み用
Public Type DataType
    Midasi As String * 10   '見出し
    Name   As String * 15   '氏名
    CrLf   As String * 2    '改行コード  必要なければCut
End Type

'ユーザー定義型 読出し用
Public Type ByteType
    Midasib(9)  As Byte
    Nameb(14)   As Byte
    CrLf(1)     As Byte     '改行コード  必要なければCut
End Type

フォームモジュールに
Option Explicit

' 書込み
Private Sub Command1_Click()
    Dim Tbl         As DataType
    Dim intFileNo   As Integer
    Dim strFileName As String
    
    strFileName = "D:\BinTest.bin"
    On Error Resume Next
    Kill strFileName    '書込みファイルがあった場合削除
    On Error GoTo 0
    
    With frmMain
        Tbl.Midasi = strLenChk(.txtMidasi.Text, 10)
        Tbl.Name = strLenChk(.txtName.Text, 15)
        Tbl.CrLf = vbCrLf           ' 必要ない場合は Cut
    End With
    
    intFileNo = FreeFile
    Open strFileName For Binary Access Write As #intFileNo
        ' ファイルに書込み  同じことを2回行っています。
        Put #intFileNo, , Tbl
        Put #intFileNo, , Tbl
    Close #intFileNo
End Sub

' 読出し
Private Sub Command2_Click()
    Dim TblB        As ByteType
    Dim intFileNo   As Integer
    Dim strFileName As String
    Dim lngE        As Long
    
    strFileName = "D:\BinTest.bin"
    intFileNo = FreeFile
    Open strFileName For Binary Access Read As #intFileNo
        Do While lngE < LOF(intFileNo)
            Get #intFileNo, , TblB
            lngE = Loc(intFileNo)
            Debug.Print StrConv(TblB.Midasib, vbUnicode), _
                        StrConv(TblB.Nameb, vbUnicode)
        Loop
    Close #intFileNo
End Sub

Private Sub Form_Load()
    frmMain.txtMidasi.Text = "定義型123あいう"  '10 Byte Over させています。
    frmMain.txtName.Text = "山田太郎"
End Sub

' 長さチェック  長い場合は長さでカット
Private Function strLenChk(strM As String, BytNum As Long) As String
    Dim Act As String
    Act = StrConv(LeftB(StrConv(strM, vbFromUnicode), BytNum), vbUnicode)
    If InStr(1, Act, vbNullChar) > 0 Then Act = Left(Act, Len(Act) - 1)
    strLenChk = Act
End Function

編集 削除