プロが教える店舗&オフィスのセキュリティ対策術

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で飛ばせるのですが、その判定式が探しても見つかりません。

どなたかご教授よろしくお願いします。

A 回答 (6件)

>改行のところでエラーとなってしまいます;


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については、他の人も指摘されていますが、ローカル変数にするのは、サイズが大きいので、大域変数にするか、最終的にセルに格納するならセルに入れるようにしたらどうでしょう?
    • good
    • 0
この回答へのお礼

ありがとうございます!
出来ました。

256文字までしか読めないと言ったのですが、
デバックのクイックウォッチでBuf(i)を確認したら256までしか入ってなかったので「256までしか駄目なのか~」と思ってしまいました。
今Buf(i)をCellに書き出したらちゃんと読み込めてました。早とちりして申し訳ないです。

.skipLine '改行をスキップ
↑これ入れてなかった為エラーとなっていたようです。

とても参考になりました。ありがとうございます。
(Bufについては、実は300万超えのデータもあるようなのである程度読み込んだら書き出してクリアする等の方法を取ってみます。「大域変数」について調べてみたのですがちょいと難しそう@@)

お礼日時:2005/04/24 19:09

私の書いていた話は、あまり理解されていないような気がしますから、論より証拠で、私の言っていたコードも公開しておきます。

一行、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
    • good
    • 0
この回答へのお礼

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

お礼日時:2005/04/25 09:46

>(正確には250万くらい)でも2文字ずつずれた状態ですが、全て確保はできました。


あっ、そうですか、入りましたか?
そんなにできるとは知りませんでしたね。

そのBuf は、後で、再び、Text あたりに出力するのでしょうか?そのために、Excelを使っているとしたら、多少、もったいないような気がしますが、シーケンシャルにするにしても、ランダムにするにしても、そのままではないですよね。

Excelで、シーケンシャルに入れていくのなら、静的領域のCells(i) [←この場合は左から右の横になる]で、データを埋め込む方法もありますね。

BLUEPIXYさん曰く
「Stringが256バイトまでしか読めないって本当ですか?」
 私も同感です。
もし、そうなら、どちらかというと、WSH の Version の問題なのかもしれませんが。

 Dim buf(30000000) As String
という組み方は、Excel 2000以上だったとは思いますね。
    • good
    • 0

まだ、良く質問がわかっていないのですが、いくつか疑問を感じています。


最初に、VBAとありますが、何のVBAですか?Excelですか?Wordですか?

 buf(i) = .read(10)
これって、10byte ではありませんよね。10語ですね。2byte 文字は存在しないのですか?それによって、コードは変わると思います。
FileSystemObject を使う必要があるのでしょうか?

単純なテキストファイルなら、Line Input ステートメントで、シーケンシャルモードで行が取れますね。

それから、なぜ、
Dim buf(30000000) As String
配列に、300万も必要ですか?VBAの配列の限界値そのものは知らないのですが、VBAでは、それだけの量になると、満杯になる前に、確保できないのではないでしょうか?数十メガになると思います。

Redim Preserve で確保していけばよいのではありませんか?

この回答への補足

ご回答ありがとうございます。

>最初に、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つの列に書き込んでいきます。

補足日時:2005/04/23 10:21
    • good
    • 0

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


試してはいませんが、
AtEndOfLineが使えるのではないかと思います。

この回答への補足

回答ありがとうございます。
AtEndOfLineも試してみたのですが、

Do While .AtEndOfLine <> True

buf(i) = .read(10)

とやると、改行のところでエラーとなってしまいます;

補足日時:2005/04/23 10:35
    • good
    • 0

buf(i) = .read(10)


で、一項目ずつ読むのではなく
一行分のバッファを準備し、Readlineで一行分まとめて読み出し
そのバッファから、一項目ずつ拾い出せば改行コードを意識しなくても良いと
思いますが

注)関数内変数で、巨大なバッファを確保するとトラブルの元なので
  バッファは静的領域に確保した方がよいと思います。
    • good
    • 1

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A