ついに夏本番!さぁ、家族でキャンプに行くぞ! >>

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

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

このQ&Aに関連する最新のQ&A

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
    • 0

このQ&Aに関連する人気のQ&A

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

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qテキストファイルから改行コードを削除して読込む方法

ExcelエクセルVBAマクロについてテキストファイルから改行コードを取り除いて
変数に読み込む方法について確認させてください。

下記のVBAログラムはWordファイルをテキストファイルに落としたファイルを変数aに
読み込んでいます。
このとき、読み込んだテキストファイルはWordファイルをテキストファイルに
落とし込んだファイルなので改行コードが残ってしまいます。
この改行コードを削除したうえで変数aに読み込みたいのですが可能でしょうか。
改行コードはメモ帳では「↓」と下矢印に似た文字で表示されます。
(実際には下矢印ではないようです。)
今のところ、Replace関数で改行コードを削除するプログラムを
考えているのですが、改行コードのVBAでの表現方法が分からないので
先に進むことが出来ません。いい案があればぜひご教授下さい。
あるいはほかの方法でも改行コードが削除出来れば結構です。

またこの変数aに読み込んである文字列からかぎカッコの内部にある文字を
抽出してエクセルの行方向に出力する方法があればご教授頂ければ幸いです。
例えば
“あなたは「こんにちは」と言いました。
私は「元気ですか」と聞きました。”

が文字列aに読み込んである場合、“こんにちは”、“元気ですか”を抽出して
エクセルに順に出力という方法です。

色々と書きましたが、よろしくお願いいたします。
以下、VBAプログラム本文です。

----------------------------------
Sub sample1()

Dim a As String

a = CreateObject("Scripting.FileSystemObject").GetFile("C:\sample.txt").OpenAsTextStream.Readall
CreateObject("Scripting.FileSystemObject").GetFile("C:\sample.txt").OpenAsTextStream.Close

End Sub

ExcelエクセルVBAマクロについてテキストファイルから改行コードを取り除いて
変数に読み込む方法について確認させてください。

下記のVBAログラムはWordファイルをテキストファイルに落としたファイルを変数aに
読み込んでいます。
このとき、読み込んだテキストファイルはWordファイルをテキストファイルに
落とし込んだファイルなので改行コードが残ってしまいます。
この改行コードを削除したうえで変数aに読み込みたいのですが可能でしょうか。
改行コードはメモ帳では「↓」と下矢印に似た文字で表示されま...続きを読む

Aベストアンサー

Windowsの改行はCRLFです。#1さんの仰るとおり、chr(13)+chr(10)ですね。
あるいはvbCr,vbLf,vbCrLfなんてのもあります。

あとプログラム本文は良くないです。
最低でもこう書くべきです。
'-------------------------------------------------
dim objStream as Object
set objStream = CreateObject("Scripting.FileSystemObject").GetFile("C:\sample.txt").OpenAsTextStream
a=objStream.readall
objStream.Close
'--------------------------------------------------
もとのソースだと、...OpenAsTextStreamと書いた時点でテキストを開いてます。
1回目と2回目は別のモノ。つまり2回開いてて、1回目は開きっぱなし。

>かぎカッコの内部にある文字を抽出

これはご自分で考えてみて下さい。
例えば、crlfを除去したのなら
b=replace(a,"「",vbcr)
b=replace(b,"」",vbcr)
とでもしておいてvbcrでSplit()すれば配列の奇数番目が括弧の中身です。
括弧が閉じてない場合とか半角だったりする場合とかもあるので注意ですね。
一番良いのは正規表現を使う方法ですが、これはちょっとハードルが高いでしょう。

Windowsの改行はCRLFです。#1さんの仰るとおり、chr(13)+chr(10)ですね。
あるいはvbCr,vbLf,vbCrLfなんてのもあります。

あとプログラム本文は良くないです。
最低でもこう書くべきです。
'-------------------------------------------------
dim objStream as Object
set objStream = CreateObject("Scripting.FileSystemObject").GetFile("C:\sample.txt").OpenAsTextStream
a=objStream.readall
objStream.Close
'--------------------------------------------------
もとのソースだと、...OpenAsTextSt...続きを読む

Q【VBA】テキストファイルを指定行数からの読み込み

こんばんは。

EXCEL VBAでテキストファイルを読み込む事について質問です。

VBAでテキストファイルをこちらから指定する行数(上から何番目という感じで)からデーターを読み込みたいのですが、どの関数をつかっていいかわからず困っています。
1行ずつ読みこむ「Input Line関数」では、無駄な行まで読み込むので動作が遅くなります。
読み込みたい行はすでにわかっているので、最初からその行に飛んでからデーター読み込みたいと思ってます。

ちなみに指定する行数は、ファイルによって違います。
あらかじめ「Input Line関数」で、ある文字が何行目にあるかを探す行為をあらかじめ行っています。

みなさまのアイデアを拝借したく、よろしくお願いします。

Aベストアンサー

速度は分かりませんが、これとか
http://officetanaka.net/excel/vba/filesystemobject/textstream10.htm

あるいは、丸ごと読みこんで、改行コードでSplitして、文字列配列を相手に該当行検索も含めて処理するとか。
昨今のPCでは、相当大きなテキストファイルでもメモリー内で処理できると思います。
http://officetanaka.net/excel/vba/filesystemobject/textstream07.htm

テキストファイルの構造によってはADOで処理する案も考えられますが、Recordsetにはファイルの先頭から(あるいは末尾先頭で)入っている事が保証されているのか、ちょっと心配。参考URLはCSVになっていますが、タブ区切りテキストファイル(拡張子.txt)でもいけます。
http://home.att.ne.jp/zeta/gen/excel/c04p47.htm

以上ご参考まで。

QEXCELファイルのカレントフォルダを取得するには?

EXCELファイルのカレントフォルダを取得するには?

C:\経理\予算.xls

D:\2005年度\予算.xls

EXCEL97ファイルがあります。

VBAで
  カレントフォルダ名
(C:\経理\,D:\2005年度\)
を取得する事は可能でしょうか?

CURDIRでは上手い方法が見つかりませんでした。

Aベストアンサー

こんばんは。
Excel97 でも、同じですね。以下で試してみてください。

Sub test()
'このブックのパス
a = ThisWorkbook.Path
'アクティブブックのパス
b = ActiveWorkbook.Path
'Excelで設定されたデフォルトパス
c = Application.DefaultFilePath
'カレントディレクトリ
d = CurDir
MsgBox "このブックのパス   : " & a & Chr(13) & _
   "アクティブブックのパス: " & b & Chr(13) & _
   "デフォルトパス    : " & c & Chr(13) & _
   "カレントディレクトリ : " & d & Chr(13)
End Sub

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

Qエクセル マクロで指定フォルダを開く

エクセルにて
指定フォルダを開く、マクロがあれば教えて頂けないでしょうか。
よろしくお願いいたします。

Aベストアンサー

こんにちは。

こういうものですか?
開くフォルダを変えたいときは targ に与えるパスを変更します。

Sub OpenFolders()
Dim targ As String
targ = "C:\"
Shell "C:\Windows\Explorer.exe " & targ, vbNormalFocus
End Sub

QExcelVBAでデータを一括してセルに貼り付ける

こんばんは

ExcelVBAで教えてください。
配列のデータをセルに貼り付ける方法です。
一つ一つ行う方法は解ります。
しかし、これでは件数が多いと時間がかかってしまいます。
まとめて貼り付ける方法を教えてください。
例えば次のように100列1000行のデータのとき、一つ一つでは10万回も貼り付けることになります。
これを1行単位で1000回とか全部まとめて1回とかでできないでしょうか。
配列データを用意する都合で1行単位もお願いします。


For Row = 1 To 1000
For Column = 1 To 100
Cells(Row, Column).Value = 配列(Row - 1, Column - 1)
Next
Next

Aベストアンサー

http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_070_08.html
を参考にしてください。

QSub ***( ) と Private Sub ***( ) の違い

初歩的な質問で申し訳ありませんが・・・

自分でコードを書いていても、イベントが発生したりした時の処理で、コードのウィンドウで上のドロップダウンリストで選択できる時の処理などは自動的に[Private Sub Command1_Click( )]などと出てくるのでそのまま使っています。自分で別途プロシージャーを作成する時は[Sub ****( )]としています。
ですがその違いを理解しないまま、自分で作成する時は[Private Sub]ではなくて[Sub]を使っています。

Sub ***( ) と Private Sub ***( ) の違いは何なんでしょうか?
どなたか説明頂けませんか?
よろしくお願いします。

Aベストアンサー

「Sub」の部分にカーソルを置いて[F1]を押せばヘルプが起動します。
「指定項目」のところに「Public」と「Private」の説明がありますよ。
省略して「Sub hogehoge()」とした場合は「Public」とみなされます。

Publicは「すべてのモジュールから呼び出せるプロシージャ」ということになります。
Privateとすると「同じモジュールの中からしか呼び出せないプロシージャ」となります。

もしExcelをお持ちでしたらExcelのVBEで標準モジュールを追加し、「Sub Test1()」と「Private Sub Test2()」を作成してみてください。
そしてExcelの[ツール]-[マクロ]-[マクロ(Alt+F8)]でマクロ実行のダイアログを表示させてみるとわかります。
ここには実行できるプロシージャの一覧が表示されますが、Test1は表示されているけれどTest2は表示されません。
Test1はPublicで、Test2はPrivateだからです。

QエクセルVBAのIf,Then 構文でOr条件とAnd条件の結合方法?

ワークシート関数で書けば
=IF(OR(F18=0,AND(F15>0,F16>0)),TRUE)です。
これをVBAで書こうとして

If Sheet1.Range("F18") = 0 Or Sheet1.Range("F15") > 0 And Sheet1.Range("F16") > 0 Then
MsgBox True
Else
MsgBox False
End If

とやってみたのですが、正しくないようです。
どのように書けばいいのでしょうか?

Aベストアンサー

>とやってみたのですが、正しくないようです。

式は正しいと思いますよ

ANDとORは、ANDが先に演算されます。/*と+-では、/*が先に演算されるようなものです。

でも、わかり易くするために、#1のかたのように括弧をつけるほうが良いですね。

QエクセルVBA:テキストデータ(txt)の読込(改行が変なところでされる)

勉強しながら、エクセルVBAを組んでみたのですが
うまくいきません。

テキストデータを以下のようなプログラムで読んだのですが
(100行のデータを縦に並ぶように100個のセルの書き出す)
読み込みデータに「↓」で改行されているところでは
「↓」の間は同一行と見なされてしまうのですが
どのようにしたら一行で一つのデータと見てくれるのでしょうか?

分かる方がいましたら教えて下さい。
よろしくお願いします。



Sub pon()
'*** 変数の宣言 ***
Dim filenum As String
Dim i As Integer
Dim num As Integer, ms As String, cnt As Integer
Dim BookName As String, PathName As String
Dim ca As String

cnt = 1
i = 1

ca = Cells(1, 56)

PathName = "C:\"
textpath = Dir(PathName & "pon" & ca & ".txt")

BookName = Dir(PathName & "pon" & ca & ".txt")

Open PathName & BookName For Input As #1 'ファイルを開きます

Do While Not EOF(1)
Line Input #1, ms
cnt = cnt + 1
Cells(1, 57) = BookName 'データの書き出し

Cells(cnt, 56) = ms 'データの書き出し

Loop
Close #1

End Sub

勉強しながら、エクセルVBAを組んでみたのですが
うまくいきません。

テキストデータを以下のようなプログラムで読んだのですが
(100行のデータを縦に並ぶように100個のセルの書き出す)
読み込みデータに「↓」で改行されているところでは
「↓」の間は同一行と見なされてしまうのですが
どのようにしたら一行で一つのデータと見てくれるのでしょうか?

分かる方がいましたら教えて下さい。
よろしくお願いします。



Sub pon()
'*** 変数の宣言 ***
Dim filenum As String
Dim i As Integer
...続きを読む

Aベストアンサー

FileSystemObjectを使って入力すれば、改行コードに悩まされることなく同じようにプログラムできます。
Public Sub pon()
Dim objFs, file, filename, BookName
Dim cnt
Dim ca, ms

Set objFs = CreateObject("Scripting.FileSystemObject")

ca = Cells(1, 56)
filename = "C:\pon" & ca &".txt"
BookName = dir(filename)
Set file = objFs.OpenTextFile(filename, 1) 'read Only

Cells(1, 57) = BookName 'データの書き出し
cnt = 1
Do Until file.AtEndOfStream
ms = file.ReadLine
cnt = cnt + 1
Cells(cnt, 56) = ms 'データの書き出し
Loop
file.Close
End Sub

FileSystemObjectを使って入力すれば、改行コードに悩まされることなく同じようにプログラムできます。
Public Sub pon()
Dim objFs, file, filename, BookName
Dim cnt
Dim ca, ms

Set objFs = CreateObject("Scripting.FileSystemObject")

ca = Cells(1, 56)
filename = "C:\pon" & ca &".txt"
BookName = dir(filename)
Set file = objFs.OpenTextFile(filename, 1) 'read Only

Cells(1, 57) = BookName 'データの書き出し
cnt = 1
Do Until file.AtEndOfStream
ms = file.ReadLine
...続きを読む

QVLOOKUPによる他シートの値参照

初心者で以下の処理を行うコーディングの方法が分りません。
いろいろと他の質問、サイトを調べましたが、解決できませんでしたので、ご指導頂ければ有り難いです。

(1)"Sheet1"に下記例の通り、2列にデータが並んでいる。
 左列には商品、右列にはその単価がセットされている。

(例)

商品1  \11
商品2  \22
商品3  \33


(2)別シート"Sheet2"の左列には、商品が"sheet1"とは
異なる順序で並んでいる。また同一商品が複数存在することもある。
この商品の右列にそれぞれの単価をセットしたい。

商品3  (Sheet1を参照して値をセット)
商品7  (Sheet1を参照して値をセット)
商品1  (Sheet1を参照して値をセット)


、って感じです。EXCEL関数の"VLOOKUP"を使おうと思っているのですが、どうも思った通りの結果がでません。
商品のデータ数は当然変動するのでVLOOKUPの参照セルに変数を使おうと思っているのですが、
その方法がまずいのでしょうか?

初心者で以下の処理を行うコーディングの方法が分りません。
いろいろと他の質問、サイトを調べましたが、解決できませんでしたので、ご指導頂ければ有り難いです。

(1)"Sheet1"に下記例の通り、2列にデータが並んでいる。
 左列には商品、右列にはその単価がセットされている。

(例)

商品1  \11
商品2  \22
商品3  \33


(2)別シート"Sheet2"の左列には、商品が"sheet1"とは
異なる順序で並んでいる。また同一商品が複数存在することもある。
この商品の右列にそれぞれの単価をセ...続きを読む

Aベストアンサー

#1です。

VBAで?
Sheet2 にVLOOKUP式を入れたいなら可変させるのは入れたい範囲だけで良いと思います。

Sub Test()
Dim r As Range
 With Worksheets("Sheet2")
  .Columns(2).ClearContents
  Set r = Range("A65536").End(xlUp).Offset(0, 1)
  .Range("B1", r) = "=IF(ISERROR(VLOOKUP(A1,Sheet1!$A$2:$B$4,2,0))" & _
              ",""""," & "VLOOKUP(A1,Sheet1!$A$2:$B$4,2,0))"
 End With
End Sub


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

人気Q&Aランキング