dポイントプレゼントキャンペーン実施中!

VBAでCSVファイルを読み込もうとしていますが、
「ファイルが見つかりません」とエラーが表示されます。
どのように対処していいのかわかりません。
教えてくください。

Sub readCsv()
Dim csvFile As String
Dim ch As Integer
Dim csvStr As String
Dim str() As String
Dim i As Integer
Set ShellApp = CreateObject("Shell.Application")
Set oFolder = ShellApp.BrowseForFolder(0, "フォルダ選択", 1)
targetFolder = oFolder.Items.Item.Path
Set fso = CreateObject("Scripting.FileSystemObject")
Set fileList = fso.GetFolder(targetFolder).Files
For Each file In fileList
csvFile = file.Name
ch = FreeFile
Open csvFile For Input As #ch
i = 1
Do While Not EOF(1)
Line Input #ch, csvStr
Close #ch
str = Split(csvStr, ",")
Range(Cells(i, 1), Cells(i, UBound(str) + 1)) = str
i = i + 1
Loop
Next
End Sub

A 回答 (4件)

1)お示しの コード は、恐らく、


a)「1つの CSVファイル を開いて、1行ずつ ワークシート に展開する」マクロ
http://www.cocoaliz.com/excelVBA/index/30/

b)「指定した フォルダ 内の CSVファイル 1つずつ に対して、所定の作業を繰り返す」マクロ
http://q.hatena.ne.jp/1198813835 の #1
を参考にされたのだろうと拝察いたします。

2)(1) の憶測が当たっているとすると、下記の2点が、合理的な考え方になろうかと存じます。
ア)(b) の「所定の作業」に (a) を挿入する。
イ)(a) の中の「i」は ワークシート に展開する「行番号」なので、「i = 1」を「所定の作業」の外に出す。

3)ここで、「所定の作業」である「For ~ Next」に (a) をそのまま挿入し、「変数の宣言部」を前に出すと、eccschool さんがお示しの コード とほぼ同じになりますが、ここで、「Close #ch」の位置が間違っていることに気が付きます。

4)さて、話を元に戻しますが、(1) でご参考にされたと思われる元々の コード には、問題点があります。

ウ)先ず、(a) の中で
Do While Not EOF(1)
となっていますが、これは、[EOF 関数] の ヘルプ に
>構文 EOF(filenumber)
>引数 filenumber には、任意の有効なファイル番号・・・
とありますように、「ch = FreeFile」とするのでしたら、
Do While Not EOF(ch)
とすべきです。

エ)また、(a) のままでは、CSVファイル に空白行が合った場合に エラー になりますので、
If csvStr <> "" Then
という コード を付加するのがよいかと存じます。

オ)さらに、(b) のままでは、「targetFolder」に CSVファイル 以外の ファイル があった場合に エラー になりますので、
If fso.GetExtensionName(file) = "csv" Then
という コード を付加するのがよいかと存じます。

5)最後に、上記の各点を改善してマクロ を実行してみると、
Open csvFile For Input As #ch
のところで「ファイルが見つかりません」と怒られてしまいます。

 原因は、#1 さんがお書きの、
>そこはフルパスでなければいけない
です。

6)ということで、
・プロシージャ 内で用いる『変数』は、宣言する。
・[Set ステートメント] で オブジェクト を参照した後は「Set ~~ = Nothing」で「オブジェクト の解放」を行なう。
ということを除いて、上記をまとめると、下記のようなことになるかと存じます。

Sub readCsv()
'最低「str()」だけは宣言しておかないと、
'str = Split(csvStr, ",") で エラー になる。
 Dim str() As String
 Set ShellApp = CreateObject("Shell.Application")
 Set oFolder = ShellApp.BrowseForFolder(0, "フォルダ選択", 1)
 targetfolder = oFolder.Items.Item.Path
 Set fso = CreateObject("Scripting.FileSystemObject")
 Set fileList = fso.GetFolder(targetfolder).Files
 i = 1 '(イ)
 For Each file In fileList
  If fso.GetExtensionName(file) = "csv" Then '(オ)
   csvFile = file.Name
   ch = FreeFile
   Open targetfolder & "\" & csvFile For Input As #ch '(5)
   Do While Not EOF(ch) '(ウ)
    Line Input #ch, csvStr
    If csvStr <> "" Then '(エ)
     str = Split(csvStr, ",")
     Range(Cells(i, 1), Cells(i, UBound(str) + 1)) = str
    End If
    i = i + 1
   Loop
   Close #ch '(3)
  End If
 Next
End Sub
    • good
    • 1

未確認ですが、「ファイルがみつかりません」となるファイルは


"."(カレントフォルダ)と".."(一つ上のフォルダ)では?

まずは開けないファイルを調べてみてください。
例:
 MsgBox file.Name
 Debug.Print file.Name
    • good
    • 0

他の観点から



Close #ch は、Do Loop の外に出るものと思います。

i = 1 の記述箇所は、ここで良いのか確かめられればと思います。
(複数ファイルがあったら、上書きする様な・・・)
    • good
    • 0

>「ファイルが見つかりません」とエラーが表示されます。


>どのように対処していいのかわかりません。

実際にあるのに見つからないというエラーなら、
ファイル名をセットする変数を見てみればわかると思いますが。

>Open csvFile For Input As #ch

変数cvsFileには、ファイル名しか入ってないですよね。
そこはフルパスでなければいけないのでは?

Open targetfolder & "\" & csvFile For Input As #ch


それから、ちょと気になったのですが、
読み込むファイルはひとつ?
また、そのフォルダーには、CSVフィルのみ?
CSVひとつのみだとうまくいくコードになってませんか?
以上です。
    • good
    • 0

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