- 締切済み
Excel_VBAで改行コードの無いファイルを開きたい。
ExcelVBAで組んだプログラムの中にファイルを開くルーチンを組み込もうとしています。 開きたいファイルは固定長なのですが、改行コードが付けられていません。 ファイルを開く際に、例えば120バイトごとに改行コード(CRLF)を挿入することは可能でしょうか? 出来るようでしたら方法をご教示いただきたいのですが。。。 どうぞ宜しくお願いいたします。
- みんなの回答 (8)
- 専門家の回答
みんなの回答
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 私は、ここの質問は、釈然としないままでしたが、今、思い出して作ってみました。なぜ、釈然としないかという理由は、データファイルを特定しないで、単に、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
- KenKen_SP
- ベストアンサー率62% (785/1258)
こんにちは。KenKen_SP です。補足します。 1レコードのバイト長が 120 バイトと決まっているなら、各フィール ドの長さも恐らく固定長だと思います。 仮にその 120バイトの中で可変長フィールドがあるとしても、その場 合にはフィールド区切りがあるはずです。 したがって、いずれにしてもレコードのバイト長が 120 バイトと決 まっている以上、120 バイトごとに改行を挿入さえできれば、フィー ルド毎に分割するのは Excel の[区切り位置]の機能で対応できるん じゃないかなぁ、、、120 バイト、、というのが「レコード区切り」 なのだと思います。 この状況で、「うまくいかない」可能性があるとすると、キャラクタ セットの問題と、2バイト文字が混在するする場合に切り出しの位置 に注意が必要なことぐらいしか思いつきません。 キャラクタセットに問題がある場合(つまり文字バケ)する場合、別 途でエンコード処理が必要になりますが、とりあえず省略。 今回は2バイト文字がないようですから、120 バイト毎に改行を挿入 するコードは #1 でいけると思います。 また、マクロでフィールドを切り出しするコードの一例が #5 です。 #5 では構造体を使用しましたが、2バイト文字がないのであれば、 120 バイトを変数に読み込んで、Mid 関数などで切り出しても一応は 問題ないでしょう。 というのが私の考えですが、はずしていたら済みません。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。#3のWendy02です。 >120バイトの固定長レコード 固定長レコードが120byteということはありえますが、ただ、それぞれのデータに関しての情報がありません。 一見は、テキストファイルにみえても、だいたいは、固定長ファイルは、ランダムファイルなんですね。だから、通常のテキスト処理ではエラーが出るかうまくいかないし、またEOF関数は役に立ちません。 それと、ふつう、元のDatabase から、ある程度出力イメージを持っているはずです。私などは、現物が手元になくては、できる自信がまったくありません。120byteといっても、今の情報は少なすぎます。元のDatabase の設計データがあればベストですが、そうでない場合は、最初、1レコードをみて、変数を構造体にして決めていくわけです。 サンプルコードは、インターネット検索をするか、こちらからでも出せますが、それ以上、マクロの中に組み込むとすれば、ご自身でお作りになっていただくしかありません。 とりあえず、一旦、ユーティリティを使って、変換させてから、Excelに読み込むなどしたほうが楽なんです。検索して、以下のようなものが、「窓の杜」にありました。 「IKARI」v1.5.4
- KenKen_SP
- ベストアンサー率62% (785/1258)
こんにちは。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
- imogasi
- ベストアンサー率27% (4737/17069)
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 などをつけて、出力するとか。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。Wendy02です。 ちょっと割り込み失礼します。 今、まだ、読んだだけですが、もしかして、「固定長」と書いていますが、固定長ファイルと違いますか?\r\n(CrLf) を単に入れていったら、Excelで言ったら、横が縦になるだけだと思います。レコード区切りを取らないといけないと違いますか? どういうファイル出力なのか、ちょっと分らないと、簡単に出来ないのではありませんか?
補足
コメントありがとうございます。 今回処理したいファイルは、120バイトの固定長レコードが改行なしでビッチリくっついたファイルです。 これをバラしたいのですが。。。
- KenKen_SP
- ベストアンサー率62% (785/1258)
#1 です。補足します。 > 改行コードが付けられていません。 の意味が CRLF が無いということであって、LF ならあるとか 改行を表す文字があるなどの場合は、バイナリーモードで ファイル全体を読み込んでから、一気に置換するという手も あります。 ちなみに 2 バイト文字が混在している場合は、もうちょっと 工夫が必要かもしれませんが、詳細が不明なのでなんとも 言えません。
補足
No.1・2でのコメント、ありがとうございます。 今回扱うファイルにはLFやその他改行を表す文字はありません。 また2バイト文字も含まれていません。 No.1でご提示いただいた方法を月曜日に試してみます。。。
- KenKen_SP
- ベストアンサー率62% (785/1258)
こんにちは。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
補足
ご回答ありがとうございます! 月曜日に試してみます。