0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【VBA】Excelを一気にフォルダ分け

0
Last updated at Posted at 2025-10-01

Excelファイル仕分けマニュアル(VBA版)

250店舗分のExcelファイルを、担当者ごとのフォルダに定期的に仕分け直す方法をまとめます。
数か月に1回店舗の担当者が変わるのですがその都度手動でファイルを移動させるのがとてもめんどくさいので、ChatGPTにコードを書いてもらってVBAで一気にやることにしました。


手順概要

  1. 対象フォルダ内のExcelファイル名を一覧化
  2. 仕分けルール(ファイル名と担当者フォルダの対応表)を作成
  3. VBAマクロで一括仕分けを実行

1. フォルダ内のファイル名を一覧化(PowerShell)

PowerShellで指定フォルダ内のExcelファイルを取得し、CSVに出力します。

※コードは以下の通り修正する
1行目のC:\Work:取得したいファイルが入っているフォルダのパス
3行目のC:\Work\:出力する場所のパス

Get-ChildItem "C:\Work" -Filter *.xlsx |
 Select-Object Name, FullName |
 Export-Csv "C:\Work\ExcelFileList.csv" -NoTypeInformation -Encoding UTF8

2. 仕分けルールの作成

ExcelまたはCSVで以下の形式の対応表を作成します。

FileName Destination
12345_店名_目標管理表.xlsx-ショートカット 堀口
12346_店名_目標管理表.xlsx-ショートカット 萩原
  • FileName … ファイル名(拡張子を含んでもOK、ショートカットの場合は .lnk を除いたベース名で可)
  • Destination … 仕分け先フォルダ名(担当者名など)

3. VBAマクロの実行

以下のVBAコードを2で作った仕分け一覧シートを開き、Alt+F11でVBAを起動し
以下のコード貼り付け

image.png

VBA
Option Explicit

Sub MoveShortcuts_Safe()
    Dim ws As Worksheet, logWs As Worksheet
    Dim srcFolder As String, destBase As String
    Dim lastRow As Long, i As Long
    Dim colFile As Long, colDest As Long
    Dim fname As String, dest As String
    Dim srcPath As String, destFolder As String, destPath As String
    Dim fso As Object

    '==== ここをあなたの環境に合わせて ====
    srcFolder = "C:\Work\Shortcuts\"        ' ショートカットがあるフォルダ
    destBase  = "C:\Work\Sorted\"           ' 仕分け先のベースフォルダ
    '========================================

    ' シート自動検出:アクティブシートを使う(固定したい場合は Sheets("あなたのシート名") に)
    Set ws = ActiveSheet

    ' ヘッダーの列位置を探す(1行目)
    colFile = FindHeaderColumn(ws, "FileName")
    colDest = FindHeaderColumn(ws, "Destination")

    If colFile = 0 Or colDest = 0 Then
        MsgBox "ヘッダー行に 'FileName' または 'Destination' が見つかりません" & vbCrLf & _
               "スペル全角/半角余分な空白を確認してください", vbExclamation
        Exit Sub
    End If

    ' データ最終行
    lastRow = ws.Cells(ws.Rows.Count, colFile).End(xlUp).Row
    If lastRow < 2 Then
        MsgBox "データ行がありませんヘッダーのみ)。", vbExclamation
        Exit Sub
    End If

    ' フォルダ末尾の \ を保証
    If Right$(srcFolder, 1) <> "\" Then srcFolder = srcFolder & "\"
    If Right$(destBase, 1) <> "\" Then destBase = destBase & "\"

    ' FSO
    Set fso = CreateObject("Scripting.FileSystemObject")
    If Not fso.FolderExists(srcFolder) Then
        MsgBox "仕分け元フォルダが見つかりません: " & srcFolder, vbCritical
        Exit Sub
    End If
    If Not fso.FolderExists(destBase) Then fso.CreateFolder destBase

    ' ログシート用意
    On Error Resume Next
    Set logWs = ThisWorkbook.Worksheets("SortLog")
    On Error GoTo 0
    If logWs Is Nothing Then
        Set logWs = ThisWorkbook.Worksheets.Add
        logWs.Name = "SortLog"
    Else
        logWs.Cells.Clear
    End If
    logWs.Range("A1:D1").Value = Array("Row", "FileName", "Destination", "Result")

    Dim logRow As Long: logRow = 2

    ' 仕分け本体
    For i = 2 To lastRow
        fname = Trim$(ws.Cells(i, colFile).Value)
        dest  = Trim$(ws.Cells(i, colDest).Value)

        If fname <> "" And dest <> "" Then
            ' .lnk 付与の有無を吸収(ベース名 or すでに .lnk を含む両対応)
            If LCase$(Right$(fname, 4)) = ".lnk" Then
                srcPath = srcFolder & fname
                destPath = destBase & dest & "\" & fname
            Else
                srcPath = srcFolder & fname & ".lnk"
                destPath = destBase & dest & "\" & fname & ".lnk"
            End If

            destFolder = fso.GetParentFolderName(destPath)
            If Not fso.FolderExists(destFolder) Then fso.CreateFolder destFolder

            If fso.FileExists(srcPath) Then
                On Error Resume Next
                fso.MoveFile srcPath, destPath
                If Err.Number = 0 Then
                    logWs.Cells(logRow, 1).Resize(1, 4).Value = Array(i, fname, dest, "Moved")
                Else
                    logWs.Cells(logRow, 1).Resize(1, 4).Value = Array(i, fname, dest, "Error: " & Err.Description)
                    Err.Clear
                End If
                On Error GoTo 0
            Else
                logWs.Cells(logRow, 1).Resize(1, 4).Value = Array(i, fname, dest, "Not found: " & srcPath)
            End If
            logRow = logRow + 1
        End If
    Next i

    MsgBox "完了しましたログは 'SortLog' シートをご確認ください", vbInformation
End Sub

Private Function FindHeaderColumn(ws As Worksheet, headerText As String) As Long
    Dim rng As Range
    Set rng = ws.Rows(1).Find(What:=headerText, LookAt:=xlWhole, LookIn:=xlValues, MatchCase:=False)
    If rng Is Nothing Then
        FindHeaderColumn = 0
    Else
        FindHeaderColumn = rng.Column
    End If
End Function


終わり!!簡単でした!

今回はExcel本体は動かさず、250個のExcelのショートカットを作成しそれをフォルダ分けしました。
仕分けしなおすときは
フォルダごと全ショートカットを削除
→250個のショートカット作成しなおし
→上記の手順

担当者ごとのフォルダも自動で作成されるので準備不要!(多分)
この自動化によって月によっては30分程度の時間削減になるかも。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?