Q19-2 ファイルリストからファイル名をリネームするには？

今回は、過去の投稿した記事の少し発展したものを考えていきます。
過去の記事で、特定のフォルダのファイル一覧を取得してセルに記載していくというものを取り扱いました。
※詳細は過去記事参照。

[➡Q19.フォルダ内のファイルリストを表示するには？][1]
[1]:https://qiita.com/guren111/items/5296761e08511b2a61bf


それで、今回はファイルリストで取得したファイル名にリネームの処理をかけるというものを考えていこうと思います。

リネーム用のシート及びリネーム用のフォルダというものを作成しました。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/94e353f4-f4a0-deea-2194-8f044b282cdd.png)

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/6e4f65e9-d28a-ac54-1c98-aa2078479cdd.png)




###■リネーム用シートと作るマクロについて
リネーム用のシートには、以下を取得します。
・対象フォルダ(今回はリネーム用フォルダ)
・変更したいファイル(リネーム用フォルダの中に配置)
・ファイル名(2ヵ所)　※B列とD列

今回は上図にあるリネーム用シートができている前提のマクロとなります。
ファイル読み込みの画像に、ファイル一覧を取得するマクロを登録します。
リネームの画像には、リネームの処理をするマクロを登録します。

つまり、今回は2つのマクロを作っていくことになります。

ファイル一覧は基本的にQ19で作ったものと同様ですが、上述のように
ファイル一覧を記載する箇所が2ヵ所になっており、位置も少し変わっているので、
あらためて、記載しておきます。

```VB
Sub Q19_2_Answer()
    Dim buf As String, cnt As Long, Path As String
    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
            Path = .SelectedItems(1)
        End If
    End With
    Range("C2").Value = Path
    cnt = 4
    buf = Dir(Path & "\")
    Do While buf <> ""
        cnt = cnt + 1
        Cells(cnt, 2) = buf
        Cells(cnt, 4) = buf
        buf = Dir()
    Loop
    
End Sub
```

このマクロをファイル読み込みの画像に登録します。


さて、今回マクロで行うリネームの処理ですが、
1．上記マクロのボタンからファイル一覧を取得する
2. 編集後ファイル一覧列(D列)にある名前を任意に編集
3．B列にある変更したいファイル名を選択(複数選択可)
4．選択した状態で、リネームボタンを押しリネームの処理
　 (編集前の名前が、編集後の名前に変更される)
5．変更があった場合、対象フォルダを開く。

となります。実際にリネームマクロの処理としては3～5となります。


###■回答
```VB
Sub Rename()
    Dim r As Range
    Dim RenameFlag As Boolean
    Dim Path As String
    Path = Range("C2").Value
    For Each r In Selection
        If r.Value <> "" And r.Offset(, 2).Value <> "" And r.Value <> r.Offset(, 2).Value Then
            Name Path & "\" & r.Value As Path & "\" & r.Offset(, 2).Value
            RenameFlag = True
        End If
    Next r
    If RenameFlag = True Then
        Shell "explorer" & Chr(32) & Path, vbNormalFocus
    End If
End Sub

```


###■解説
まず、B列にある変更したいファイル名を選択(複数選択可)したファイルを
対象にループ処理を行う方法についてですが、以下となります。

For Each r In Selection

rは、range型の変数です。選択した範囲はSelectionに格納されます。
ctrlを押しながら飛び飛びで選択したとしても、複数格納することができます。


次にリネームですが、

Name Path & "\" & r.Value As Path & "\" & r.Offset(, 2).Value

この記述となります。

リネームは
Name 変更元ファイル名(パスを含む) As 変更後ファイル名(パスを含む)
となります。

従って今回は、対象フォルダの値　+ \ + 変更元ファイル名(選択したセルの値)
が変更元で、変更後はoffsetにより、2列ずらした値、すなわちD列の値を取得しています。

リネームする際のIf文の条件は、
・B列が空欄でない　かつ　D列が空欄でない　かつ　B列の値とD列の値が違う
という3つの条件を満たしたときとしています。
さらに、リネームした際はリネームフラグをtrueとしています。
これは、最後のリネームした後にフォルダを開く為です。


###■実行結果

まずは、ファイル読み込みの画像を押して、ファイル一覧を取得したあとの画像がこちら

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/249ef062-2633-1a49-dd62-b0300a17bdff.png)

画像が小さくて分かりづらいですが、20190128.txt ~ 20190217.txtというファイルがあります。
フォルダ内の画像がこちら

![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/21a65f84-fb70-24ca-8d31-66c2077ca3d0.png)


そして、手動で名前を変更します。
今回は、2019の部分を2020へ変更するので、D列の対象セルを選択して、
Ctrl + h で置換するウィンドウを呼び出して、一括で置換しています。


任意の名前に変更したら、今度は変更したいファイル名(変更前のファイル名)を選択します。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/ca4623be-6154-3ad7-57b8-bfe9278d6948.png)



選択後、リネームの画像を押下し、マクロを呼び出します。


すると、以下のように2019の部分が2020へ変更されていることが分かります。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/7a4ff5d3-2f92-9eca-67bc-cdc6d52e03f4.png)



以上となります。

改善ポイントとしては、

・1回変更したあとにまた変更したくなった場合に、都度、ファイル読み込みを押す必要がある。
➡ファイル名変更後にリロード処理をかける。
もしくは、あらたにリロードボタンを設置し、リロードするマクロをつくり登録する。
 (フォルダ選択の省略用)

・ファイル読み込みの際に、ファイル数が少なかった場合、前回読み込んだファイル名が
残ってしまう。
➡ファイル名を記載する際に、前もってセルの値を削除する処理を入れる

・リネームする際、ファイルを選択するのが手間。
➡今回は、任意で変更したいファイルを選べるようにこのようにしています。
ただし、記載している箇所を事前に特定すれば、選択する動作は不要とすることができます。


などです。