[Excel VBA] ダイアログで指定したCSVをブックとして開く

データ処理が業務に入っている方にはつきものの「CSVファイルをExcelでもちゃもちゃ処理する」作業。一回きりならCSVをそのまま開いて処理し、Excelブックとして保存すればいいだけの話なんですが、こういう作業って日次だったり月次だったり、ルーチン化することもよくありますよね。

で、面倒くさいからVBAでオートメーション化しちゃおうって話になるんですが、どうやってCSVデータを取り込むか。永遠のテーマです(そうか?)。

私がよく使う手法は以下の3つです。

  • 1.CSVをFSOのTextstreamを通して配列に読み込む
  • 2.QueryTableを使う
  • 3.めんどくさいからCSVをブックとして開く

Openステートメントはほとんど使いません。なんか古臭い感じがする、ってだけのイメージでw

今回は3の「めんどくさいからCSVをブックとして開く」コードをペタッとします。


スポンサーリンク

1.全体コード

まずは全体像を。

Function OpenCSV() As String
'ファイルダイアログからCSVを開き、該当ファイルのブック名を返す
    Dim FName As Variant, myBook As Workbook, BName As String
    'ダイアログを開いてCSVファイルを指定
    FName = Application.GetOpenFilename("CSVファイル(*.csv),*.csv")
    'キャンセルされたらExit(キャンセル時、戻り値は空文字とする)
    If VarType(FName) = vbBoolean Then
        OpenCSV = ""
        Exit Function
    Else
        'ファイルが開かれていなければ開く
        If IsOpenBook(FName, BName) = False Then
            Application.Workbooks.Open (FName)
        End If
    End If
    '戻り値としてブック名を返す
    OpenCSV = BName
End Function

続いてサブルーチン。

Function IsOpenBook(FName As Variant, Optional BName As String) As Boolean
'対象ブックが開いているかBoolean型で返すサブルーチン
'渡すのはフルパスでOK
'オプションでブック名(パスなし)も返せる
    Dim WB As Workbook, F As Boolean
    F = False
    'フルパスからブック名だけを切り出す
    BName = Mid(FName, InStrRev(FName, "\") + 1)
    '開いているブックでループを回し、ブック名が合致したらフラグをTrueにする
    For Each WB In Workbooks
        If WB.Name = BName Then
            F = True
            Exit For
        End If
    Next WB  
    IsOpenBook = F
End Function

とまあ、こんな形で定式化しております。

2.解説

全体的な流れとしては、開きたいファイルのフルパスを取得する→取得したファイル名をブックとして開くを行っているだけです。

バリデーションとして「ファイルを選ばずにキャンセルされた場合」と「既にそのブックが開かれていた場合」に分岐を入れています。

目的のCSVをブックとして開いた状態でブック名(ファイル名ではない)を返すため、この関数を呼び出したあとは呼び出し側でブックオブジェクトにブックをセットすることを想定しています。

opencsv_01

ただいま絶賛フローチャート作成の練習中。

2-1.選択したファイルのフルパスを返すGetOpenFilenameメソッド

'ダイアログを開いてCSVファイルを指定
FName = Application.GetOpenFilename("CSVファイル(*.csv),*.csv")

GetOpenFilenameメソッドは、ユーザーインターフェース的には「ファイルを開く」ダイアログを表示します。が、実際の動きとしてはそのままファイルを開くのではなく、ファイル名のフルパスをString型で返してくれます。

書式:GetOpenFilename([FileFilter])

引数のFileFilterにはダイアログ中に表示するファイルの種類を指定します。String型で、【ファイルの種類名(任意),拡張子】という形式で指定します。拡張子指定は複数指定もワイルドカード指定もできます。

GetOpenFilenameメソッドは、ファイルを選ばずにキャンセルした場合はBoolean型のFalseを返します。なので、結果を代入した変数(FName)がBoolean型であればキャンセルされた、と考えます。

'キャンセルされたらExit(キャンセル時、戻り値は空文字とする)
    If VarType(FName) = vbBoolean Then
        OpenCSV = ""
        Exit Function

勘のいい方はお気づきかと思いますが、この場合FNameにはString型もしくはBoolean型のどちらも入る可能性があるので、変数の宣言時はVariant型にしておきましょう。

2-2.あるブックが開いているかどうかを確かめるサブルーチン

これはひとつ雛形を持っておくと色んなところで使えます。開かれているブックと同じ名前のブックを開こうとすると、Excelさんがエラーメッセージを出してしまいますからね。

サンプルではFor each~Nextで開かれているブック全てのブック名を調べています。合致したらフラグをTrueにします。

    '開いているブックでループを回し、ブック名が合致したらフラグをTrueにする
    For Each WB In Workbooks
        If WB.Name = BName Then
            F = True
            Exit For
        End If
    Next WB

その前に、Workbook.Nameはフルパスではないので、ブック名だけを切り出してやる必要があります。ブック名というやつはパスはないけど拡張子はつきます。いつもどうだったか忘れるポイント…。

'フルパスからブック名だけを切り出す
    BName = Mid(FName, InStrRev(FName, "\") + 1)

Mid関数で一番最後の\(¥)より後を切り出しています。これもパスを除去したいときによく使います。FileSystemObjectを使った方がスマートなんですけどね…。


スポンサーリンク

3.使いどころ

CSVを整形してExcelファイルとして保存、という場面にとても便利です。返ってきたブック名を使ってブックオブジェクトにセットしてしまえばいろいろ処理できますし、最後にSaveAsでExcelファイル形式で保存すればOKです。

この投稿の投稿者は おさみ です。ブックマーク用 パーマリンク

スポンサーリンク