社内SEになるからExcel VBAの定石をメモする

重い処理を書くなら

“Application.ScreenUpdating”は描画を止めたり、始めたりする。

“Application.Calculation”に”x|CalculationManual”をセットすると自動計算を止め、”x|CalculationAutomatic”をセットすると自動計算を始める。

' 処理開始前
Application.ScreenUpdating = False
Application.Calculation = x|CalculationManual

' 処理終了前
Application.Calculation = x|CalculationAutomatic
Application.ScreenUpdating = True

定期バッチを実行したい

以下をテキストファイルに記述する。
ここには処理が記載されているExcelブックとそのモジュール名・マクロ名を記載する。

Dim objXLS
Set objXLS = WScript.CreateObject("Excel.Application")
objXLS.Visible = True
 
' 以下は実行したい処理内容で異なる
' ファイルパス
objXLS.Workbooks.Open("C:\Users\test\test1.xlsm")
' 実行するモジュール名とマクロ名
objXLS.Application.Run "Module1.macro"
' ここまで

objXLS.Application.Quit
Set obj = Nothing

以下のように上記のファイルを実行するバッチを記述する。これをWindowsのタスクスケジューラーに登録する。

echo off

cscript C:\Users\test\test.vbs

マクロを自動で実行する

Excelファイルを開いた時、セーブする時、ファイルを閉じる時に勝手に実行できる。

検索処理を行うINSTR

一致するものがあると0を超える数字を返すらしいよ。

If InStr( ThisWorkbook.Sheets("List").Cells(ix1,6), ThisWorkbook.Sheets("Master").Cells(ix2,11) ) > 0 Then
 ' 何かしらの処理
 Exit Do
End If

Outlookも動作させれるらしい。

メールを送信したい時に使えるテンプレート。

Dim OutlookApp As Object
Dim MailItem As Object
Dim ws As Worksheet
Dim i As Integer
Dim lastRow As Long

Set OutlookApp = CreateObject("Outlook.Application")
Set ws = ThisWorkbook.Sheets(1)

lastRow = ws.Cells(Rows.Count, 1).End(x|Up).Row

For i = 2 To lastRow
    Set MailItem = OutlookApp.CreateItem(0)
    With MailItem
        .To = ws.Cells(i, 1).Value
        .Subject = "自動送信メール"
        .Body = "VBAによる自動送信"
        .Send
    End With
Next i

Outlookも動作させれるらしい。

詳しくは知らん!

Dim ws As Worksheet, newWs As Worksheet
Dim lastRow As Long

' コピー元データ
Set ws = ThisWorkbook.Sheets(1)
lastRow = ws.Cells(Rows.Count, 1).End(x|Up).Row

' フィルターして、コピー
Set newWs = ThisWorkbook.Sheets.Add
ws.Range("A1:D" & lastRow).AutoFilter Field:=2, Criteria1:="重要"
ws.Range("A1:D" & lastRow).SpecialCells(x|CellTypeVisible).Copy newWs.Cells(1,1)

ws.AutoFilterMode = False

バグを見つける!

変数の中身を確認できるよ。

DEBUG.PRING

関数を入力したい

鍵となるのは”R1C1形式”です。

Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)

' ".FormulaR1C1"を使って、R1C1形式で入力する。
' "R1C1" -> "A1", "R1C1:R10C2" -> "A1:B10", "RC[-1]" -> "A"
ws.Range("B2:B10").FormulaR1C1 = ws.Range("B2:B10").= "=VLOOKUP(RC[-1], MASTER!R1C1:R10C2, 2, FALSE)"

数式を値に変換する(値のコピー)

式じゃなくて値をコピーしたい時に使う。
“.Value”を付ける事が大事!

Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)

ws.Range("B2:B10").FormulaR1C1 = ws.Range("B2:B10").= "=VLOOKUP(RC[-1], MASTER!R1C1:R10C2, 2, FALSE)"
' 値のコピー
ws.Range("B2:B10").Value = ws.Range("B2:B10").Value

重複データの削除

方法は他にもあるらしい。

Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)

ws.Range("A1:B1000").RemoveDuplicates Columns:=1, Header:=x|Yes

処理中のセル位置の変更

Ctrlキー+矢印キー(←↑→↓)の移動方法と挙動は同じはず。
引数に指定できるものは以下の通り。

  • xlUp : ↑上へ
  • xlDown : ↓下へ
  • xlToLeft : ←左へ
  • xlToRight : →右へ
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)

' "A1"位置から下方向に移動。ただし、そのデータの途中に空のセルがあった場合はその直前まで移動
ws.Range("A1").Cells(1,1).End(x|Down)

' (データの一覧の中で)一番下のデータに移動。
ws.Range("A1").Cells(Rows.Count,1).End(x|Up)

日時の操作

変数の中身を確認できるよ。

' 現在の日時
Range("A1") = Date ' -> "2024/6/4"
Range("A2") = Time ' -> "8:45:23 AM"
Range("A3") = Now ' -> "2024/6/4 8:45"

' 年月日を抽出
Range("A4") = Year(Date) ' -> "2024"
Range("A5") = Month(Date) ' -> "6"
Range("A6") = Day(Date) ' -> "4"

' 年初めから現在が第何週かを取得する
Range("A7") = DatePart("ww", Date) & "週目" ' -> "4"

' 今月の月末日を調べる
Range("A8") = DateSerial(Year(Date), Month(Date)+1, 1) - 1

' 指定した月の月末日を調べる
Dim sDate
Dim sLast
Dim sLastday

sDate = "2025/2/1"
sLast = DateSerial(Year(sDate), Month(sDate) + 1, 0)
sLastday = Format(sLast, "d")

' 現在からの時間加算
' "ww" ->週, "y" ->年, "m" ->月, "d" -> 日
Range("A10") = DateAdd("ww", 2, Date)

' 日付間隔
Dim mDate As DatemDate = #1/1/2023#
Range("A11") = "経過年数" & DateDiff("yyyy", mDate, Date)
Range("A12") = "経過年数" & DateDiff("m", mDate, Date)
Range("A13") = "経過年数" & DateDiff("d", mDate, Date)

' 日付に型変換
Range("A14") = DateValue("令和6年12月10日")

ファイル操作に関するもの

他のExcelブックを選択させて操作する

以下は条件分岐してないけど、多分Excelブック以外も選択できるから、その時はエラーになる。

Dim wws As Worksheet, wb As Workbook
Dim fDialog As FileDialog
Dim filePath As Variant
Dim lastRow As Long, pasteRow As Long
Dim mainWb As Workbook

Set main Wb = ThisWorkbook
Set ws = mainWb.Sheets(1)
pasteRow = ws.Cells(Rows.Count, 1).End(x|Up).Row + 1

' ファイル洗濯ダイアログを開く
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
fDialog.AllowMultiSelect = True ' 複数選択を許可
fDialog.Title = "入力するExcelファイルを選択してください。"

' ファイルが選択されたときの挙動
If fDialog.Show = -1 Then
    For Each filePath In fDialog.SelectedItems
        Set wb = Workbooks.Open(filePath)
        ' ...
    Next
End If

コメントを残す