PC初心者にもありがたいExcelVBA



[SC（非公式） Advent Calendar 2018](https://qiita.com/advent-calendar/2018/unofficial-sc) 6日目
今年の4月からＰＣを触り始め半年後...
javaやSQLの基礎(と少しのWebアプリ開発知識)を学び、Ctrl + C/Ctrl + V/Ctrl + Zだけを胸にプロジェクトに配属された新人を待っていたのは、、、
#ディレクトリの中にファイルを作ろう
```vb:ExcelVBA

Sub おれ_ふぁいるつくる()

Dim fso As FileSystemObject
Set fso = New FileSystemObject

Dim ts_1 As TextStream
'ファイル名'
Dim file As String
'フォルダ名'
Dim folder As String
'フォルダパス'
Dim folder_path As String
'出力先パス'
Dim path_1 As String


Dim n As Integer
n = Sheets("SQL").Cells(Rows.Count, "O").End(xlUp).Row

'繰り返し処理'
Dim i As Integer
For i = 3 To n
file = Sheets("SQL").Cells(i, 14).Value
folder = Sheets("SQL").Cells(i, 14).Value

folder_path = "C:\\"& folder

' Cドラに指定の名前のフォルダがなければ作成する'
    If Dir(folder_path, vbDirectory) = "" Then
        MkDir folder_path
    End If

path_1 = folder_path & "\\" & file & ".sql"

' 書き込み処理1'
Set ts_1 = fso.OpenTextFile(path_1, ForWriting, True)
ts_1.Write (Sheets("SQL").Cells(i, 15).Value)

' ファイルを閉じる'
ts_1.Close

Next i

End Sub
```
・Excelでマクロを使用するためには何やらいくつかの設定をする必要があり、こちらを参考にしました。
[Excel2010 でマクロを有効にする](https://kokodane.com/2010/excel2010macro_01.htm)
・私の最初の疑問は、「Excelマクロって便利らしいけどなんのことや。」だったので、同サイトのこちらもわかりやすくてよかったです。
[マクロとはVBAで作成したプログラム](https://kokodane.com/macro1.htm)

さて、このたび「名前の異なるフォルダ１００個作ってその中にそれぞれ対応する名前、中身(ほとんど共通)を持つファイルを作ってね。」と伝えられ絶望した私ですが、先輩様にヒントをいただきExcelマクロにたどり着き、九死に一生を得ました。

一応、簡単な説明ですが、

```vb
Sub [マクロ名]()
~本文
End Sub
```
で一つのプロシージャとなります。マクロを使うときはこのプロシージャ単位で呼び出します。
Dim　で各変数を定義しています。As以下は省略もできます。

```vb
For i = 3 to n
~処理内容
Next i
```
でここでは３行目から最後の値のある行(ｎ行)まで繰り返し処理を行っています。

ほかのものもコメント通りの処理を行っているので、関数をググるとすぐ出てきます。

FileSystemObjectは若干ややこしかった記憶が、、

#エクセルファイルの中身チョコチョコいじって名前変えて保存

「このエクセルファイルのこのシートのこの値変えて次にこっちのシートのここセル結合してこの名前に変えて保存して*50」

```vb:ExcelVBA
Sub おれ_えくせる_まもる()

'各種変数宣言'
Dim thisBook As Workbook
Dim workBook1 As Workbook

Dim folderPass1 As String
Dim fileName As String
Dim newFileName As String

'マクロ実行中の画面遷移をさせないように設定'
Application.ScreenUpdating = False

'フォルダのパス'
folderPass1 = "C:\\folder"

'フォルダのパス'
folderPass2 = "C:\\folder_2"

'マクロを実行しているワークブック'
Set thisBook = ThisWorkbook
'ループ終了条件'
Dim n As Integer
n = thisBook.Worksheets("xxx").Cells(Rows.Count, "D").End(xlUp).Row
'ループ'
Dim i As Integer
For i = 52 To 53
    fileName = folderPass1 & "\\" & thisBook.Worksheets("xxx").Cells(i, 3).Value
    newFileName = folderPass2 & "\\" & thisBook.Worksheets("xxx").Cells(i, 4).Value
    Application.DisplayAlerts = False
    Set workBook1 = Workbooks.Open(fileName & ".xlsx")
    workBook1.Sheets(1).Delete
    
    Application.DisplayAlerts = True
    thisBook.Worksheets("yyy").Copy Before:=workBook1.Worksheets(1)
    
    workBook1.Worksheets("zzz").Activate
    workBook1.Worksheets("zzz").Range("H13").Select
    Selection.Copy
    workBook1.Worksheets("zzz").Range("L13").Select
    ActiveSheet.Paste
    Selection.ClearContents
    workBook1.Worksheets("zzz").Range("L13").Select
    Selection.Copy
    ActiveCell.Offset(1, 0).Select
    ActiveSheet.Paste
    ActiveCell.Offset(-1, 0).Select
    Selection.Resize(Selection.Rows.Count + 1).Select
    Selection.Copy
    workBook1.Sheets(2).Range("M13:S13").Select
    ActiveSheet.Paste
    
    Range("K2:L2").Select
    ActiveCell.FormulaR1C1 = "エクセル守るマン"
    ActiveCell.Characters(1, 2).PhoneticCharacters = "エクセルマモルマン"
    Range("M2:O2").Select
    ActiveCell.FormulaR1C1 = "11/29/2018"
    Range("A1:C4").Select
    
    workBook1.SaveAs (newFileName & ".xlsx")
    
    workBook1.Close

Next i
Application.ScreenUpdating = True

End Sub
```
※**都合上、シート名等様々なものを本来のソースから変更しています。**

こちらのソースで作業を１クリックで終わらすことができました。
行っている作業はソースを見てもよくわからないと思うのであまり気にしないことをお勧めします。
ループの中で指示された内容を履行するために様々な努力が行われていますが、
大事なことは、
1. マクロを実行しているブックからほかのブックへの操作も簡単に行える。
2. 画面遷移を無くすと処理スピードがすごく上がる。

```vb
Application.ScreenUpdating = False
```



#所感
上述の通りエクセルに関して繰り返し行う作業をボタン一つで行えるので、すごく作業を効率化できたと思います。マクロの記憶を行えば自分のしたい操作がVBA上でどのように記述されるか簡単に調べることができることもあり、**作るのが思っていた５倍くらい簡単**でした。今後も乱用していきたいです。(結果として作業はできたけどソースは汚いし無駄もあり、あまり詳細な動作の内容や関数についての知識等がないため、実務の中で学んでいきたいです。)

あと、別件ですがサクラエディタって便利だなって思いました。