LoginSignup
3
7

More than 5 years have passed since last update.

[VBA]ファイル操作

Last updated at Posted at 2017-05-30

概要

エクセルのVBAマクロでデータをファイルから読み込みセルに入力する方法
demo.gif

こんな感じでエクセルにデータを読み込むコードを書いてみました。
https://github.com/katsuma99/FileOperation

module1
Option Explicit

'一番下位のファイル/フォルダの文字列を抽出
Public Function GetFileName(ByRef path As String) As String
    Dim fileName As String, pos As Long

    '\フォルダー★\ファイル :★の位置を取得
    pos = InStrRev(path, "\")

    '上位パス と ファイル で分割して文字列取得
    fileName = Mid(path, pos + 1)
    path = Left(path, pos - 1)

    GetFileName = fileName
End Function

Public Function ReadData(sampleNo As Integer, filePath As String)
    Dim fileName As String              'フォルダ/ファイル
    Dim folderName As String            '拡張子を抜いたファイルパス
    Dim splitPath As String: splitPath = filePath

    'フォルダ/ファイル名を抽出
    fileName = GetFileName(splitPath)
    folderName = GetFileName(splitPath)

    '各データを読み込む
    Cells(1, sampleNo) = folderName
    Cells(2, sampleNo) = fileName
    Call ExtractData(filePath, Cells(3, sampleNo))

End Function

Public Function ExtractData(inputPath As String, startCell As Range)
    Dim tmpBuf As String, fno As Long

    'ファイルを開く
    If Dir(inputPath) = "" Then
        MsgBox "データファイルがありません"
        End
    End If

    fno = FreeFile
    Open inputPath For Input As #fno

    ' テキストデータチェック
    If EOF(fno) Then
        ' データファイルが不正
        MsgBox "テキストデータが不正です"
        End
    End If

    ' データを最後まで読み込む
    Dim offset As Integer: offset = 0
    Do Until EOF(fno)
        Line Input #fno, tmpBuf
        Cells(startCell.Row + offset, startCell.Column) = tmpBuf
        offset = offset + 1
    Loop

    Close #fno

End Function

Sub Import()
    Dim filePaths As Variant, fileName As String

    'ファイルマネージャー(起動時は現在開いているのファイルのパス)
    ChDir ThisWorkbook.path
    filePaths = Application.GetOpenFilename(FileFilter:="データファイル(*.txt),*.txt", MultiSelect:=True)

    'キャンセル時終了
    If IsArray(filePaths) = False Then
        End
    End If

    'アクティブシートの内容を全て削除
    ActiveSheet.Cells.Clear


    '選択されたデータを逐次読み込み
    Dim i As Integer
    For i = 1 To UBound(filePaths)
        Call ReadData(i, CStr(filePaths(i)))
    Next

    MsgBox "選択した" & UBound(filePaths) & "ファイルを読み込みました"
End Sub

解説

計測など実験するときに、一旦数値データを以下のようにテキストファイルに書き出し、エクセルで可視化するというパターンがあります。そんな時に、VBAを使ってファイル操作を自動化することで、ファイルを開いてコピペする手間を省くことができます。
出力された数値データ.PNG

処理のポイント

  1. 複数のファイル選択:Application.GetOpenFilename()
  2. ファイルパスの配列:filePaths
  3. 文字列の検索:InStrRev()
  4. ファイルの読み込み:Line Input

Point1.複数のファイル選択

    'ファイルマネージャー(起動時は現在開いているのファイルのパス)
    ChDir ThisWorkbook.path
    filePaths = Application.GetOpenFilename(FileFilter:="データファイル(*.txt),*.txt", MultiSelect:=True)

ChDir : 開くフォルダーのパスを指定
ThisWorkbook.path:開いているエクセルのパス
Application.GetOpenFilename(FileFilter:="AB",MultiSelect:=True):ファイルマネージャーを開く
 A:表示名
 B:選択できる拡張子

Point2.ファイルパスの配列

    '選択されたデータを逐次読み込み
    Dim i As Integer
    For i = 1 To UBound(filePaths)
        Call ReadData(i, CStr(filePaths(i)))
    Next

UBound():配列のサイズ
CStr():Stringにキャスト
注意:filePathsの引数は1から(0だと有効範囲外エラー)

Point3.文字列の検索

Public Function GetFileName(ByRef path As String) As String
    Dim fileName As String, pos As Long

    '\フォルダー★\ファイル :★の位置を取得
    pos = InStrRev(path, "\")

ByRef:参照渡し
InStrRev():文字の検索(AB
 A:検索の対象となる文字列
 B:検索する文字列
注意:検索は最後の文字から始まり、最初に見つかった位置を返す

Point4.ファイルの読み込み

    fno = FreeFile
    Open inputPath For Input As #fno

    ' データを最後まで読み込む
    Dim offset As Integer: offset = 0
    Do Until EOF(fno)
        Line Input #fno, tmpBuf
        Cells(startCell.Row + offset, startCell.Column) = tmpBuf
        offset = offset + 1
    Loop

    Close #fno

流れ:Openでファイルを開いて、Closeでファイルを閉じる
  Open ファイルパス For Input As #ファイル番号
   ファイル操作の処理
  Close #ファイル番号

FreeFile:使用可能なファイル番号を取得

Do Until EOF(fno)
        Line Input #fno, tmpBuf

Do Until EOF(ファイル番号):最後に達するまでループ
Line Input #ファイル番号文字列:ファイルを上から一行ずつ読み込み、文字列として変数に代入

参考資料

3
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
7