• ベストアンサー

VBAでテキストファイルの改行を無視する方法

VBAでテキストファイルにある文字列を配列の変数に格納したいのですが、改行が含まれているとそこから2バイトずつずれてしまいます。 1行毎に読もうとしても1行の文字列が6000バイトぐらいあるので変数に格納しきれません。 読み込むテキストファイルは _________0_________1_________2・・・・________10 _______100________51 のようになっており、10バイトずつ変数に格納していきたいです(スペースも格納する必要あり) 以下のように作ったのですが、改行のあるところからずれてしまいます。 Sub ファイル読み込み() Dim buf(30000000) As String Dim i As Long i = 0 With CreateObject("Scripting.FileSystemObject") With .OpenTextFile("C:\test.text", 1) Do While .AtEndOfStream <> True buf(i) = .read(10) Loop End With End With End Sub 「次の文字列が改行コードである」ということが分かれば.skipで飛ばせるのですが、その判定式が探しても見つかりません。 どなたかご教授よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

>改行のところでエラーとなってしまいます; i = 0 With CreateObject("Scripting.FileSystemObject") With .OpenTextFile("C:\test.text", 1) Do While .AtEndOfStream <> True Do While .AtEndOfLine <> True buf(i) = .read(10) i = i + 1 Loop .skipLine '改行をスキップ Loop End With End With てな感じでやっていますか? 一応ウチの環境ではこれでうまくいきました。 あと、Stringが256バイトまでしか読めないって本当ですか? OSは、なんでしょう? 最終的にセルに入らなかったからでは? bufについては、他の人も指摘されていますが、ローカル変数にするのは、サイズが大きいので、大域変数にするか、最終的にセルに格納するならセルに入れるようにしたらどうでしょう?

kikei
質問者

お礼

ありがとうございます! 出来ました。 256文字までしか読めないと言ったのですが、 デバックのクイックウォッチでBuf(i)を確認したら256までしか入ってなかったので「256までしか駄目なのか~」と思ってしまいました。 今Buf(i)をCellに書き出したらちゃんと読み込めてました。早とちりして申し訳ないです。 .skipLine '改行をスキップ ↑これ入れてなかった為エラーとなっていたようです。 とても参考になりました。ありがとうございます。 (Bufについては、実は300万超えのデータもあるようなのである程度読み込んだら書き出してクリアする等の方法を取ってみます。「大域変数」について調べてみたのですがちょいと難しそう@@)

その他の回答 (5)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.6

私の書いていた話は、あまり理解されていないような気がしますから、論より証拠で、私の言っていたコードも公開しておきます。一行、6K のチェックもしました。ただ、その処理は、テキストで再びOutputするなら、Read_OutLine_Testのように配列のBuf はいりませんね。 Sub ReadLine_Test()  Dim Buf() As String  Dim Textline As String  Dim i As Long  Const myFname As String = "C:\Test.txt"  Open myFname For Input As #1  Do While Not EOF(1)   Line Input #1, Textline   If Len(Textline) > 1 Then    ReDim Preserve Buf(i)    Buf(i) = Left(Textline, 10)    i = i + 1   End If  Loop  Close #1 End Sub '--------------------------------------------- 'テキスト出力用 Sub Read_OutLine_Test()  Dim Buf As String '出力前段階のバッファ  'Dim Buf As String * 10 '固定長ならこちら,Buf = TextLine  Dim TextLine 'テキストInputデータ  Dim inFno As Integer 'in用ファイルNo  Dim outFno As Integer 'Out用ファイルNo  '読み込みデータ  Const InFname As String = "C:\Test.txt"  '出力データ  Const OutFname As String = "C:\Test2.txt"  inFno = FreeFile  Open InFname For Input As #inFno  outFno = FreeFile  Open OutFname For Output As #outFno  Do While Not EOF(1)   Line Input #inFno, TextLine   If Len(TextLine) > 1 Then    Buf = Left(TextLine, 10)    'Buf = TextLine    Write #outFno, Buf   End If  Loop  Close #inFno  Close #outFno End Sub

kikei
質問者

お礼

ご回答ありがとうございます。 おかげで対処することができました。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.5

>(正確には250万くらい)でも2文字ずつずれた状態ですが、全て確保はできました。 あっ、そうですか、入りましたか? そんなにできるとは知りませんでしたね。 そのBuf は、後で、再び、Text あたりに出力するのでしょうか?そのために、Excelを使っているとしたら、多少、もったいないような気がしますが、シーケンシャルにするにしても、ランダムにするにしても、そのままではないですよね。 Excelで、シーケンシャルに入れていくのなら、静的領域のCells(i) [←この場合は左から右の横になる]で、データを埋め込む方法もありますね。 BLUEPIXYさん曰く 「Stringが256バイトまでしか読めないって本当ですか?」  私も同感です。 もし、そうなら、どちらかというと、WSH の Version の問題なのかもしれませんが。  Dim buf(30000000) As String という組み方は、Excel 2000以上だったとは思いますね。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

まだ、良く質問がわかっていないのですが、いくつか疑問を感じています。 最初に、VBAとありますが、何のVBAですか?Excelですか?Wordですか?  buf(i) = .read(10) これって、10byte ではありませんよね。10語ですね。2byte 文字は存在しないのですか?それによって、コードは変わると思います。 FileSystemObject を使う必要があるのでしょうか? 単純なテキストファイルなら、Line Input ステートメントで、シーケンシャルモードで行が取れますね。 それから、なぜ、 Dim buf(30000000) As String 配列に、300万も必要ですか?VBAの配列の限界値そのものは知らないのですが、VBAでは、それだけの量になると、満杯になる前に、確保できないのではないでしょうか?数十メガになると思います。 Redim Preserve で確保していけばよいのではありませんか?

kikei
質問者

補足

ご回答ありがとうございます。 >最初に、VBAとありますが、何のVBAですか?Excelですか?Wordですか? ExcelのVBAになります。 >これって、10byte ではありませんよね。10語ですね。2byte 文字は存在しないのですか?それによって、コードは変わると思います。 失礼しました。10バイトではなく10語ですね。ですが2バイト文字は存在しません。 質問事項にも書いてありますが、1行の文字列が多いため読みきれません。 Dim buf as String ・ ・ buf = .ReadLine とやっても256バイトまでしか読みきれないのです。 あと配列が300万と定義していますが、実際に必要なんです。(正確には250万くらい)でも2文字ずつずれた状態ですが、全て確保はできました。 Outputは格納したデータを複数のシートにわけて 1つの列に書き込んでいきます。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

>「次の文字列が改行コードである」ということが分かれば.skipで飛ばせるのですが、その判定式が探しても見つかりません。 試してはいませんが、 AtEndOfLineが使えるのではないかと思います。

kikei
質問者

補足

回答ありがとうございます。 AtEndOfLineも試してみたのですが、 Do While .AtEndOfLine <> True buf(i) = .read(10) とやると、改行のところでエラーとなってしまいます;

  • Traja
  • ベストアンサー率19% (107/546)
回答No.1

buf(i) = .read(10) で、一項目ずつ読むのではなく 一行分のバッファを準備し、Readlineで一行分まとめて読み出し そのバッファから、一項目ずつ拾い出せば改行コードを意識しなくても良いと 思いますが 注)関数内変数で、巨大なバッファを確保するとトラブルの元なので   バッファは静的領域に確保した方がよいと思います。

関連するQ&A