Excelの旧バージョン.xlsファイルを新バージョンの.xlsxファイルに変換するツールを作成してみた

# Excelの旧バージョン.xlsファイルを新バージョンの.xlsxファイルに変換するツールを作成してみた

Excelの旧バージョン.xlsファイルが多数あり、新バージョンの.xlsxファイルに変換する必要が発生した。少数のファイルなら個々にファイルを開いて.xlsxへ再保存すれば良いが、多数のファイルがあるため、.xlsファイルを.xlsxファイルに変換するする簡易的なツールを作ってみたので備忘録的に記載します。

---
__《目次》__
[ツールの動作環境](#ツールの動作環境)
[ツールの概要](#ツールの概要)
[ツールの実行例](#ツールの実行例)
[部品の配置](#部品の配置)
[ソース](#ソース)
[ソース解説](#ソース解説)

---

# ツールの動作環境

* <font color="Blue">__OSはWindows10__</font>
	* 1903(OSビルド18362.1016)

* <font color="Blue">__Excel2016__</font>
	* MSO(16.0.13127.20266)　64ビット

# ツールの概要

<font color="Blue">__画面イメージ__</font>
![Excel2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/bc6797ee-0d3d-9643-4cb0-73fdf4176ec1.png)

1. 『xlsファイル格納先』欄にxlsファイル格納先フォルダを入力する。
2. 『参照』ボタンクリックでファイルダイアログを表示して『xlsファイル格納先』欄を指定することも可能。
3. xlsファイル格納先フォルダ下のサブフォルダ内のxlsファイルも変換対象としたい場合、『サブフォルダも対象とする』チェックボックスをチェックする。
4. 『変換開始』ボタンクリックで変換を開始する。指定された条件でxlsファイルをxlsxファイルに変換する。xlsファイルにマクロがある場合、xlsmファイルに変換する。変換結果はxlsファイルと同じフォルダに出力する。
5. 変換を実施したxlsファイルが『変換したxlsファイルリスト』欄に出力される。
6. 『変換したxlsファイルリスト初期化』ボタンをクリックすると、『変換したxlsファイルリスト』欄が初期化される。
7. 変換処理実行中に強制終了させたい場合は[Ctrl] キーを押したまま [Break] キーを押す。

# ツールの実行例

<font color="Blue">__画面イメージ(実行前)__</font>
![tool_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/0f76b04f-842a-9796-2fec-a6d8fea53530.png)
* 『ファイル格納先』欄に『C:\work\temp』を指定する。
* 『サブフォルダも対象とする』をチェックする。
* 『変換開始』をクリックする。

<font color="Blue">__xlsファイル格納先の状態(実行前)__</font>
![cmd_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/63aeff6c-2e1d-b215-93a9-2951d24bed96.png)
* 7個のxlsファイルが存在する。

<font color="Blue">__画面イメージ(実行後)__</font>
![tool_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/aa9ec093-18b5-dbca-4576-4e2d844027a1.png)
* 『変換したxlsファイルリスト』欄に変換を実施した7個のxlsファイルが出力される。

<font color="Blue">__xlsファイル格納先の状態(実行後)__</font>
![cmd_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/7343fdf6-8bf0-4828-a3ff-70da231d0506.png)
* xlsファイルに対応するxlsxファイルが7個作成される。

# 部品の配置
<font color="Blue">__コマンドボタン、チェックボックスの配置方法__</font>

* Excelの開発タブにてコントロール→挿入でフォームコントロールのコマンドボタンやチェックボックスを指定して配置する。

<font color="Blue">__開発タブ__</font>
![f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/41a6426e-73e2-f750-6c14-dc88c89340de.png)

* 開発タブは、Excelのディフォルトでは非表示となっているため、表示設定が必要です。ファイルタブ→オプション→リボンのユーザ設定で開発をチェックすると開発タブが表示される。

<font color="Blue">__Excelのオプション画面__</font>
![o.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/11800dbb-2868-7dd5-d4f2-4f1e258d8c87.png)


<font color="Blue">__コマンドボタン配置例__</font>

* コマンドボタンを配置すると以下のマクロの登録画面が表示される。『マクロ名』欄にマクロの名前(本例の場合、『Excel_format_Convert』)を入力して、『新規作成』ボタンをクリックする。


<font color="Blue">__マクロの登録画面__</font>
![vba_1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/d9d22423-5b4b-94cc-6f38-e09defdb4d0b.png)

* Visual Basic for Applications画面が表示される。

<font color="Blue">__Visual Basic for Applications画面__</font>
![vba_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/2c2fa840-fc47-4b65-10ea-43aa76169f6c.png)

* コマンドボタンが作成される。

![vba_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701538/f5e28207-6892-dfde-6d06-49f08054fbc4.png)

# ソース
```
 1	Private Const INPUT_SEL As String = "B6"                     'xlsファイル格納先入力セル
 2	Private Const LIST_START_SEL As Long = 20                     '
 3	Private Const List_CLEAR_RANGE As String = "B20:B1048576"    '変換したxlsファイルリスト初期化範囲
 4	Dim cnt As Long
 5	
 6	
 7	'変換開始
 8	Sub Excel_format_Convert()
 9	
10	     
11	    'フォルダの場所を変数に入れる
12	    Dim Folder_path As String
13	    Dim rc As Boolean      'サブフォルダも対象とするかチェックボックスの値
14	    Folder_path = Range(INPUT_SEL).Value
15	    cnt = LIST_START_SEL
16	    '変換したxlsファイルリスト初期化
17	    List_Clear
18	    'xlsファイル格納先指定チェック
19	    If Folder_path <> "" Then
20	        'xlsファイル格納先存在チェック
21	        If Dir(Folder_path, vbDirectory) <> "" Then
22	             'サブフォルダも対象とするかチェックボックスの値取得
23	             rc = Worksheets("Sheet1").CheckBoxes(1).Value = xlOn
24	        
25	             '変換実行
26	             Call Convert(Folder_path, rc)
27	        Else
28	            MsgBox vbCrLf & vbCrLf & "xlsファイル格納先に指定されたフォルダが存在しません" & vbCrLf & vbCrLf, vbOKOnly + vbCritical
29	            Exit Sub
30	        End If
31	    Else
32	        MsgBox vbCrLf & vbCrLf & "xlsファイル格納先が指定されていません" & vbCrLf & vbCrLf, vbOKOnly + vbCritical
33	        Exit Sub
34	    End If
35	    MsgBox vbCrLf & vbCrLf & "     処理完了しました        " & vbCrLf & vbCrLf, vbOKOnly + vbInformation
36	End Sub
37	
38	'変換実行
39	Sub Convert(Folder_path As String, rc As Boolean)
40	    Dim Excel_book
41	
42	    'xlsファイルを探すように指定
43	    Excel_book = Dir(Folder_path & "\*.xls*")
44	
45	    '指定フォルダから、xlsファイルを開き、xlsxで保存
46	    Do Until Excel_book = ""
47	        If LCase(Right(Excel_book, 3)) = "xls" Then
48	
49	            Workbooks.Open Filename:=Folder_path & "\" & Excel_book
50	
51	            Application.DisplayAlerts = False
52	            'マクロ有無
53	            If ActiveWorkbook.HasVBProject = True Then
54	                ActiveWorkbook.SaveAs Filename:=Folder_path & "\" & Excel_book & "m", FileFormat:=xlOpenXMLWorkbookMacroEnabled
55	            Else
56	                ActiveWorkbook.SaveAs Filename:=Folder_path & "\" & Excel_book & "x", FileFormat:=xlOpenXMLWorkbook
57	
58	            End If
59	            ActiveWorkbook.Close
60	            Application.DisplayAlerts = True
61	            
62	            ThisWorkbook.Worksheets("Sheet1").Cells(cnt, 2).Value = Folder_path & "\" & Excel_book
63	            cnt = cnt + 1
64	        End If
65	        Excel_book = Dir()
66	    Loop
67	
68	    'サブフォルダも対象なら以下を実行
69	    If rc = True Then
70	        With CreateObject("Scripting.FileSystemObject")
71	            For Each f In .GetFolder(Folder_path).SubFolders
72	                '変換実行(再帰的呼び出し)
73	                Call Convert(f.Path, rc)
74	            Next f
75	        End With
76	    End If
77	End Sub
78	
79	'変換したxlsファイルリスト初期化
80	Sub List_Clear()
81	    ThisWorkbook.Worksheets("Sheet1").Range(List_CLEAR_RANGE).Value = ""
82	End Sub
83	
84	'参照
85	Sub Dir_Select()
86	    With Application.FileDialog(msoFileDialogFolderPicker)
87	        If .Show = True Then
88	            Range(INPUT_SEL).Value = .SelectedItems(1)
89	        End If
90	    End With
91	End Sub
92	'『サブフォルダも対象とする』チェックボックス
93	Sub check_Click()
94	
95	End Sub
```

# ソース解説

1. <font color="Blue">__参照処理：Dir_Select(84～91行目)__</font>
『参照』ボタンをクリック時に呼び出される処理。
ファイルダイアログを表示して選択されたフォルダを『xlsファイル格納先』欄に設定する。

2. <font color="Blue">__変換したxlsファイルリスト初期化処理：List_Clear(79～82行目)__</font>
『変換したxlsファイルリスト初期化』ボタンをクリック時に呼び出される処理。
また、変換開始処理(Excel_format_Convert)からも呼び出される。
『変換したxlsファイルリスト』欄を初期化する。

3. <font color="Blue">__『サブフォルダも対象とする』チェックボックス：check_Click(92～95行目)__</font>
『サブフォルダも対象とする』チェックボックスをクリック時に呼び出される処理。
何もしない。

4. <font color="Blue">__変換開始処理：Excel_format_Convert(7～36行目)__</font>
『変換開始』ボタンクリック時に呼び出される処理。
	* 14～17行目：各種初期化等を実施する。
	* 19,31～34行目：『xlsファイル格納先』欄の入力チェックを実施する。未入力の場合、エラーのメッセージボックスを表示して終了する。
	* 21,27～30行目：『xlsファイル格納先』欄に入力されたフォルダの存在チェックを実施する。フォルダが存在しない場合、エラーのメッセージボックスを表示して終了する。
	* 23行目：『サブフォルダも対象とする』チェックボックスの状態を取得する。
	* 26行目：変換実行処理(Convert)を呼び出す。第1引数：『xlsファイル格納先』、第2引数：『サブフォルダも対象とする』
 
5. <font color="Blue">__変換実行処理：Convert(38～77行目)__</font>
変換開始処理(Excel_format_Convert)から呼び出される。
また、サブフォルダも対象とする場合は自身から再帰的呼び出しを行う。
	* 43～46,65～66行目：*.xls*を探し見つかった分ループする。
	* 47,64行目：ファイル名の右から3つが、『xls』の場合のみ、処理をする。LCase関数は大文字を小文字にする関数なのでファイル名が『XLS』でも処理をする。
	* 49行目：Excelファイルを開く。
	* 51行目：警告を無視するように設定する。(保存時にすでに同じ名前のファイルがあった場合等の警告を出さないように設定する)
	* 53～58行目：HasVBProjectで該当xlsファイルにマクロ入っているか判定を行い、マクロが入っている場合は、『xlsm』にして、ファイル形式(FileFormat)を、マクロ有効ブック（xlOpenXMLWorkbookMacroEnabled）にして保存する。マクロが入っていない場合は、『xlsx』にし、ファイル形式(FileFormat)を、Excelブック(xlOpenXMLWorkbook)にして保存する。出力先フォルダはxlsファイルと同じフォルダ(Folder_path)としている。
	* 59行目：Excelファイルを閉じる。
	* 60行目：警告を無視する設定を解除する。
	* 62～63行目：『変換したxlsファイルリスト』欄に変換を実施したxlsファイルを出力する。
	* 69,76行目：サブフォルダも対象の場合、以下の処理を行う。
	* 71～75行目：配下のサブフォルダを全て取り出し、変換実行処理(Convert)を再帰的に呼び出す。