Excelファイルと同階層にあるCSVファイルを読み込ませるマクロを作ってみたのですが、正常に動作しません。
アドバイスいただければ幸いです。
Excel2003を使用しています。
Sub 同階層フォルダ内のCSV読込_Click()
Dim fname As String 'ファイル名
Dim pathname As String 'パス名
Dim dat(1 To 4) As Variant '読み込んだデータ
Dim rr As Long '対象行番号
Dim i As Integer '列のオフセット
Dim j As Integer 'ファイル識別番号のオフセット
'同階層フォルダ内のCSVファイルを参照
pathname = ".\*.csv"
fname = Dir(pathname, vbNormal)
'データを挿入する行番号
rr = 2
'該当するファイルがある間
Do While fname <> ""
j = 0
j = j + 1
'ファイルを開く
Open fname For Input As #j
'ファイルの終端まで
Do Until EOF(j)
'データを取得
Input #j, dat(1), dat(2), dat(3), dat(4)
'読み込んだデータをセルに出力
For i = 1 To 4
Cells(rr, i).Value = dat(i)
Next
'行番号を更新
rr = rr + 1
Loop
Close #j
'フォルダ内の次のファイルを検索
fname = Dir()
Loop
End Sub
No.3ベストアンサー
- 回答日時:
こんにちは。
FileNo は、その都度閉じるのですから、FreeFile関数で、決めてあげれば、インクリメントする必要はありません。それから、私は、Line Input を使って、一行全体を取り入れて切り分けします。そのほうが速いからです。On Error があるのは、空行のためです。Dat()の配列を、String型にするのは、Excel側が勝手なキャストをしないためです。(Excel 2000以上)
なお、一部の変数名は変更しました。プロシージャ名も英語に変更しました。なるべく、変数は、キャメル形式にしたほうがエラーを見つけやすいです。
Sub OpenCSV_in_SameFolder_Click()
Dim Fname As String
Dim PathName As String
Dim StartRow As Integer
Dim FileNo As Integer
Dim TextLine As String
Dim i As Long
Dim Dat() As String
PathName = ThisWorkbook.Path & "\"
Fname = Dir(PathName & "*.csv")
StartRow = 2
Do While Fname <> ""
FileNo = FreeFile()
Open PathName & Fname For Input As #FileNo
Do Until EOF(FileNo)
Line Input #FileNo, TextLine
Dat() = Split(TextLine, ",")
On Error Resume Next
'4列目までなら、Resize(,4).Valueとする
Cells(StartRow + i, 1).Resize(, UBound(Dat()) - LBound(Dat()) + 1).Value = Dat()
i = i + 1
On Error GoTo 0
Loop
Close #FileNo
Fname = Dir()
Loop
End Sub
この回答への補足
目から鱗です。
コードの書き方を変えるだけでこれだけ見やすくなるのですね。
コメントを入れなくても分かりやすいです。
Line Input を使うと汎用性が高いですね。
こちらを利用させていただきます。
ところで、ご提示いただいたコードで私の知識不足により理解できない点が2箇所あります。
もしよろしければ、こちらもお教えいただけませんでしょうか。
●Cells(StartRow + i, 1).Resize(, UBound(Dat()) - LBound(Dat()) + 1).Value = Dat()
これの意味がよく分かりません。
下記のコードと結果的に同じなのでしょうか?
For i = 0 To UBound(Dat())
If Len(Dat(i)) <> 0 Then
Cells(StartRow, i + 1) = Dat(i)
End If
Next
●エラー処理の On Error Resume Next と On Error GoTo 0 を入れる場所ですが、
この位置に入れる理由をお教えいただけませんでしょうか?
No.5
- 回答日時:
こんにちは。
Wendy02です。>●エラー処理の On Error Resume Next と On Error GoTo 0 を入れる場所ですが、
> この位置に入れる理由をお教えいただけませんでしょうか?
(On Error があるのは、空行のためです。)とすでに書いてあったかと思いますが、配列にしても配列が空の場合は、エラーになりますので、それを避けるためです。
持ち込むデータが、何かわからない場合(この特定は、目視では分らないことがあります)、なかなかむつかしいのです。何であると、こちらで決めて掛かるわけにはいかないわけで、出力元を教えてもらうなどしてもらわないと、正確には出来ません。
コンマ区切り(CSV)なのか、タブ切りなのか、スペース区切りなのか、まだ他にも、バイナリタイプのものや、シーケンシャルファイルなど、それぞれに区切り方があります。それは、CSVは、今は、Excelの専売特許のようですが、どちらかというと、データベースソフトのためのものです。
#4 の KenKey_SPさんの
2005/11/2,東京支店,田中,"\123,456"
の場合も、Line Input に変りませんが、Split関数の代わりに、サブルーチンで、切り分けて配列にします。私は、いままで、これを正規表現で切り分けてきましたが、Instr関数で切り分けることも可能です。
vbCR (\n) の場合は、経験したことがありませんので分りませんが、文書全体を、正規表現のループで切り分けることは可能だと思います。
ご返答いただきありがとうございます。
私の乏しい知識では理解できない部分もありますが、
これから疑問点を調べながら、いただいたアドバイスをモノにしていきたいと思います。
この度は誠にありがとうございました。
No.4
- 回答日時:
#2 です。
余談ですが、、
Split 関数や Line Input を使って CSV データのフィールド分割
を行う場合は、次のようなデータの読み込みに失敗しますので、
ご注意を。
例1) 2005/11/2,東京支店,田中,"\123,456"
→2005/11/2 東京支店 田中 "\123 456"
ありがちですが、金額フィールドの桁区切りカンマとか。
例2) キャリッジ リターン (vbCr)を含むフィールドがある
データ
→1レコードがそのフィールドで複数のレコードに分割され
てしまいます。これが Line Input の特性です。
Excel でセル内改行のあるデータを CSV に書き出すと
このようなデータになります。
したがって、Line Input や Split 関数を使って CSV データを読み
込むコードを書く場合には、CSV ファイル内にこのようなデータが
含まれるかどうかを検証する必要があります。
例1は分かっておりましたが、例2は知りませんでした。
教えていただいて助かりました。
危うくトラブルに見舞われるところでした。
読み込ませたいデータを検証してから、Line Input を利用したいと思います。
貴重なアドバイスをありがとございます。
No.2
- 回答日時:
こんにちは。
KenKen_SP です。Dir 関数の戻り値はファイル名だけで、パスが含まれません。
Sub 同階層フォルダ内のCSV読込_Click()
Dim fname As String 'ファイル名
Dim pathname As String 'パス名
Dim dat(1 To 4) As Variant '読み込んだデータ
Dim rr As Long '対象行番号
Dim i As Integer '列のオフセット
Dim j As Integer 'ファイル識別番号のオフセット
'同階層フォルダ内のCSVファイルを参照
pathname = ThisWorkbook.Path
fname = Dir(pathname & "\*.csv", vbNormal)
'データを挿入する行番号
rr = 2
j = 0
'該当するファイルがある間
Do While fname <> ""
j = j + 1
'ファイルを開く
Open pathname & "\" & fname For Input As #j
'ファイルの終端まで
Do Until EOF(j)
'データを取得
Input #j, dat(1), dat(2), dat(3), dat(4)
'読み込んだデータをセルに出力
For i = 1 To 4
Cells(rr, i).Value = dat(i)
Next
'行番号を更新
rr = rr + 1
Loop
Close #j
'フォルダ内の次のファイルを検索
fname = Dir()
Loop
End Sub
Dir 関数の戻り値はファイル名だけなのですね。
大変勉強になりました。
ご提示いただいたコードで、正常に動作するようになりました。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Excel(エクセル) マクロでテキストファイルを読み込んだ際の最終セルにデータと改行が含まれる問題の改善方法 2 2022/03/25 16:50
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
- Excel(エクセル) Excel VBAどこが間違ってますか? 4 2023/07/17 10:04
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Excel(エクセル) フォルダ内のワードファイルをPDFに一括変換するVBA 3 2023/06/09 16:51
- その他(Microsoft Office) マクロVBAについて 1 2022/09/06 18:12
- Visual Basic(VBA) 貼り付けた値が消えていく 以下はソースファイルの2番目のシートのB6から最終行を取得 ターゲットファ 2 2023/07/27 12:23
- Visual Basic(VBA) あるフォルダーのファイルを違う親フォルダーのサブフォルダーに移したい 11 2023/02/15 19:00
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAで巨大なファイルの途中から...
-
ADOによるCSVファイルからのデ...
-
ExcelをCSV書き出す場合のシー...
-
画像をバイナリデータに変換す...
-
テキストデータから指定した1...
-
Perl 時間同士の差
-
バッチファイルの作り方(CSV→...
-
ファイル出力をUTF8Nではなくて...
-
正規表現で"-" "0-9"以外を削除...
-
ファイル名を複数個配列で確保...
-
fopen64について
-
自動更新
-
<br />と<p></p>の使い方
-
VBA テキストファイルを読み取...
-
メールアドレス登録の重複をチ...
-
HTMLのフォームで画像と文...
-
perlでcsvの出力について
-
Perl<->Oracle間での文字化けに...
-
Perlで特定文字列から特定文字...
-
Perlで特定行から特定行までを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAでCSVファイルの特定行を書...
-
ExcelをCSV書き出す場合のシー...
-
openした後、closeしないでプロ...
-
VBAでCSVファイルを途中行まで...
-
VBAで巨大なファイルの途中から...
-
ReadLineでの読み出し行を指定する
-
JavaでCSVファイルを高速に読む...
-
MATLAB グローバル変数の宣言
-
エクセルVBA コードが同じでも...
-
Perlの変数に文字数制限(容量...
-
perlで、後ろの行を読んで、前...
-
2つのCSVファイルをマッチング
-
C言語でのファイルのデータ更...
-
VB6.0でDB接続する際に切断時の...
-
CSVが可変長の場合の検索方法
-
perlで容量の大きいCSVファイル...
-
1ファイルずつ読み込みたい
-
VBScriptでファイル保存先のデ...
-
C#でCSVファイルを逐一更新したい
-
perl で googleAPIを呼び出す...
おすすめ情報