アプリ版:「スタンプのみでお礼する」機能のリリースについて

ExcelVBAで組んだプログラムの中にファイルを開くルーチンを組み込もうとしています。
開きたいファイルは固定長なのですが、改行コードが付けられていません。
ファイルを開く際に、例えば120バイトごとに改行コード(CRLF)を挿入することは可能でしょうか?
出来るようでしたら方法をご教示いただきたいのですが。。。
どうぞ宜しくお願いいたします。

A 回答 (8件)

こんにちは。



私は、ここの質問は、釈然としないままでしたが、今、思い出して作ってみました。なぜ、釈然としないかという理由は、データファイルを特定しないで、単に、120 byte と決められていた根拠が分らないのです。全角で、60 文字、半角で、120文字とかいうなら、話は見えました。
なお、バイト数(BYTE_NUMBER)は、4で割り切れる数でないと、全角が入ると文字化けを起こします。

バイナリ単位で、というのは、テキストファイルでは、Unicodeファイルのみです。私たちが一般的に取り扱うファイルは、シーケンシャルファイルでも、Lineのポインタは存在していますし、バイナリファイルでも、別のポインタが存在しています。だから、厳密に、改行のない、ということはありえないのです。もう、かえりみられることはないかもしれませんが、アップロードしておきます。

Sub BinaryInput()
  Dim FileNo As Integer
  Dim FileName As String
  Dim bufB() As Byte
  Dim strBuf As String
  Dim i As Long
  Const BYTE_NUMBER As Integer = 120
  FileName = "testB.txt" 'ファイル名
  OutFileName = "o_" & FileName
  FileNo = FreeFile()
  Open FileName For Binary Access Read As #FileNo
  If LOF(FileNo) = 0 Then
   MsgBox "ファイルが空です。終了します。"
   Exit Sub
  End If
  bufB = InputB(LOF(FileNo), #FileNo)
  Close FileNo
  FileNo = FreeFile()
  Open OutFileName For Output As #FileNo
  Do
   strBuf = MidB(bufB, i * BYTE_NUMBER + 1, BYTE_NUMBER)
   If LenB(strBuf) < 2 Then Exit Do
   strBuf = StrConv(strBuf, vbUnicode)
   Print #FileNo, strBuf
   i = i + 1
  Loop
  Close FileNo
End Sub
    • good
    • 0

こんにちは。

KenKen_SP です。補足します。

1レコードのバイト長が 120 バイトと決まっているなら、各フィール
ドの長さも恐らく固定長だと思います。

仮にその 120バイトの中で可変長フィールドがあるとしても、その場
合にはフィールド区切りがあるはずです。

したがって、いずれにしてもレコードのバイト長が 120 バイトと決
まっている以上、120 バイトごとに改行を挿入さえできれば、フィー
ルド毎に分割するのは Excel の[区切り位置]の機能で対応できるん
じゃないかなぁ、、、120 バイト、、というのが「レコード区切り」
なのだと思います。

この状況で、「うまくいかない」可能性があるとすると、キャラクタ
セットの問題と、2バイト文字が混在するする場合に切り出しの位置
に注意が必要なことぐらいしか思いつきません。

キャラクタセットに問題がある場合(つまり文字バケ)する場合、別
途でエンコード処理が必要になりますが、とりあえず省略。

今回は2バイト文字がないようですから、120 バイト毎に改行を挿入
するコードは #1 でいけると思います。

また、マクロでフィールドを切り出しするコードの一例が #5 です。
#5 では構造体を使用しましたが、2バイト文字がないのであれば、
120 バイトを変数に読み込んで、Mid 関数などで切り出しても一応は
問題ないでしょう。

というのが私の考えですが、はずしていたら済みません。
    • good
    • 0

こんにちは。

#3のWendy02です。

>120バイトの固定長レコード

固定長レコードが120byteということはありえますが、ただ、それぞれのデータに関しての情報がありません。

一見は、テキストファイルにみえても、だいたいは、固定長ファイルは、ランダムファイルなんですね。だから、通常のテキスト処理ではエラーが出るかうまくいかないし、またEOF関数は役に立ちません。

それと、ふつう、元のDatabase から、ある程度出力イメージを持っているはずです。私などは、現物が手元になくては、できる自信がまったくありません。120byteといっても、今の情報は少なすぎます。元のDatabase の設計データがあればベストですが、そうでない場合は、最初、1レコードをみて、変数を構造体にして決めていくわけです。

サンプルコードは、インターネット検索をするか、こちらからでも出せますが、それ以上、マクロの中に組み込むとすれば、ご自身でお作りになっていただくしかありません。

とりあえず、一旦、ユーティリティを使って、変換させてから、Excelに読み込むなどしたほうが楽なんです。検索して、以下のようなものが、「窓の杜」にありました。

「IKARI」v1.5.4

参考URL:http://www.forest.impress.co.jp/article/2003/09/ …
    • good
    • 0

こんにちは。

KenKen_SP です。

2byte 文字が混在しない、改行コードがないデータに、単純に改行
コードを挿入していくだけなら、#1 のコードでいけると思います。
その結果をシートに貼り付けて、[区切り位置]で固定長を選ぶか、
それもマクロ化しても良いでしょう。

ちなみに、、キャラクターセットは大丈夫なんですか?

下記は、固定長データの読み込みをマクロで行うサンプルです。
具体的なデータの様子が分からないので、参考程度ですが。

【前提】

テストデータの仕様は、1レコード46バイトで、5フィールドあります。
名前:20byte 性別:1byte 血液型:2byte 携帯:13byte 誕生日:10byte

WEB では半角SPはつめて表示されてしまいますが、メモ帳などで固定長
データとなるように整形して下さい。また WEB での読みやすさのため、
テストデータは改行をいれています。メモ帳で改行をカットしてマクロ
のブックと同じ場所に、Test.text という名前で保存して下さい。

【テストデータ】

yamada tarou MAB090-1234-56781978/01/01
yamada hanako FA 090-8765-43211980/05/20
osiete buu MO 090-9999-99992001/12/31
ok webuu MB 090-1111-11112005/10/21

【マクロのコード】

'1レコードを定義する構造体を用意します。
'変数名は任意ですが、プロシージャ側とそろえて下さい。
'型の宣言の後にある数字が、フィールドのバイト長です。
'フィールドの数だけ変数を用意して下さい。
'次の例だと1レコード5フィールドのバイト長46byteです。
Type typRecord
  名前  As String * 20
  性別  As String * 1
  血液型 As String * 2
  携帯  As String * 13
  誕生日 As String * 10
  '今回は改行コードがないのでコメント化
  '改行コードがある場合はコメント解除
  'strCRLF As String * 2
End Type


'// 固定長ファイル読み込みサンプル
Sub Sample()
  
  Dim udtRec   As typRecord
  Dim TargetFile As String
  Dim n     As Long
  Dim SH     As Worksheet
  Dim GYO    As Long
    
  '処理対象ファイル
  TargetFile = ThisWorkbook.Path & "\Test.txt"

  '転記開始行(レコード番号カウンタ兼用)
  GYO = 1
  
  'ランダムアクセスモードでファイルオープン
  n = FreeFile
  On Error Resume Next
  Open TargetFile For Random Access Read As #n Len = Len(udtRec)
  If Err.Number > 0 Then
    MsgBox "ファイルオープン失敗", vbCritical
    Exit Sub
  Else
    On Error GoTo 0
    'ファイルオープンに成功したら結果出力シートを作成
    Set SH = ActiveWorkbook.Sheets.Add
  End If
  
  'ファイルの終端までループ
  Do Until EOF(n)
    'レコードを構造体にバッファ
    Get #n, GYO, udtRec
    If EOF(n) Or GYO > 65536 Then Exit Do
    With udtRec
      'GetData関数に構造体のデータとバイト数を渡し、
      '戻り値をセルに書き込む
      SH.Cells(GYO, 1).Value = GetData(.名前, 20)
      SH.Cells(GYO, 2).Value = GetData(.性別, 1)
      SH.Cells(GYO, 3).Value = GetData(.血液型, 2)
      SH.Cells(GYO, 4).Value = GetData(.携帯, 13)
      SH.Cells(GYO, 5).Value = GetData(.誕生日, 10)
    End With
    'カウントアップ
    GYO = GYO + 1
  Loop
  
  'ファイルクローズ
  Close #n
  
  '結果出力シートをアクティブに
  SH.Parent.Activate
  SH.Activate

  Set SH = Nothing
  
End Sub

'正しいバイト長でデータを返す(Unicode対応)
Private Function GetData(ByVal strDat As String, ByVal lngByte As Long)
  
  Dim strTmp As String
  strTmp = StrConv(strDat, vbFromUnicode)
  GetData = RTrim$(StrConv(LeftB$(strTmp, lngByte), vbUnicode))

End Function
    • good
    • 0

Sub test10()


Open "C:\Documents and Settings\xxxxx\My Documents\text5.txt" For Input As #1
For i = 1 To 5
a = Input$(10, #1)
MsgBox a
Next i
Close #1
End Sub
こんなのが使えるようです。
上記は10文字を順々に読んできました。
DOS-Basic時代のコマンドですがVBAでファイルから10文字づつ順次取ってきました。
これを応用できませんか。& vbCrLf などをつけて、出力するとか。

この回答への補足

ご回答ありがとうございます!
月曜日に試してみます。

補足日時:2005/10/22 02:21
    • good
    • 0

こんばんは。

Wendy02です。

ちょっと割り込み失礼します。

今、まだ、読んだだけですが、もしかして、「固定長」と書いていますが、固定長ファイルと違いますか?\r\n(CrLf) を単に入れていったら、Excelで言ったら、横が縦になるだけだと思います。レコード区切りを取らないといけないと違いますか?

どういうファイル出力なのか、ちょっと分らないと、簡単に出来ないのではありませんか?

この回答への補足

コメントありがとうございます。
今回処理したいファイルは、120バイトの固定長レコードが改行なしでビッチリくっついたファイルです。
これをバラしたいのですが。。。

補足日時:2005/10/22 02:22
    • good
    • 0

#1 です。

補足します。

> 改行コードが付けられていません。

の意味が CRLF が無いということであって、LF ならあるとか
改行を表す文字があるなどの場合は、バイナリーモードで
ファイル全体を読み込んでから、一気に置換するという手も
あります。

ちなみに 2 バイト文字が混在している場合は、もうちょっと
工夫が必要かもしれませんが、詳細が不明なのでなんとも
言えません。

この回答への補足

No.1・2でのコメント、ありがとうございます。
今回扱うファイルにはLFやその他改行を表す文字はありません。
また2バイト文字も含まれていません。
No.1でご提示いただいた方法を月曜日に試してみます。。。

補足日時:2005/10/22 02:25
    • good
    • 0

こんにちは。

KenKen_SP です。

試してないのですが、こんな感じでいけませんか?

Sub Sample()

  Dim Buf    As String * 120 'Buffer size 120byte
  Dim TargetFile As String
  Dim n     As Long
  Dim strResult As String
  
  TargetFile = "C:\test.txt"
  
  n = FreeFile
  Open TargetFile For Binary As #n
    Do Until EOF(n)
      Get #n, , Buf
      strResult = strResult & Buf & vbCrLf
    Loop
  Close #n
  
  Debug.Print strResult

End Sub
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!