VBAの開発を便利にするRubberduckで使っている機能を紹介

こんにちは!大阪市住之江区に拠点を置く会社『縁紡ぐ』の稲垣です。

当社は、Excel、ACCESS、RPAなどのシステム開発や既存ツールを使った業務効率化の提案、また、ITスキルアップのための教育に力を入れています。効率的なビジネス運営を目指している企業様、ITスキルの向上を図りたい企業や個人の方に、最適なご提案をさせていただきます。業務プロセスの改善とITスキルアップをサポートし、共に成長するパートナーでありたいと考えています。

目次

Rubberduckのおすすめ機能をご紹介

VBAを開発するための、VBEは、Visual Studio Codeやその他のコードエディタに比べて、機能面で劣っているところが多いです。

そんな、VBEをパワーアップしてくれツールがあります。

縁紡ぐ

VBEを使い役する機能アップしてくれるのが、Rubberducだよ!

今回は、Rubberducで実際に縁紡ぐが使っている機能をご紹介します。

インストール方法は、下記の記事でご紹介しています。

コードの整形

初心者

インデントって、文頭を少しずらすことですよね?
あれ、よく忘れてしまいます💦

縁紡ぐ

初心者の方は、よくインデントを付け忘れるのでRubberducのインデント機能を使えば、一瞬で解決できますよ!

コードが乱れがちな場合、Rubberduckの「Indent」機能を使って、自動的に整形することができます。これで読みやすいコードに一瞬で変わります。

整形前

画像に alt 属性が指定されていません。ファイル名: ExcelVBA%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92%E6%94%B9%E5%96%84%E3%81%99%E3%82%8BRubberducks%E3%81%A7%E3%82%A4%E3%83%B3%E3%83%87%E3%83%B3%E3%83%88%E4%BF%AE%E6%AD%A3%E5%89%8D.png

整形の指示「右クリック」⇒「Runbberduck」⇒「Indent」⇒適用範囲今回は、「Current Module」を選択

画像に alt 属性が指定されていません。ファイル名: ExcelVBA%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92%E6%94%B9%E5%96%84%E3%81%99%E3%82%8BRubberducks%E3%81%A7%E3%82%A4%E3%83%B3%E3%83%87%E3%83%B3%E3%83%88%E4%BF%AE%E6%AD%A3%E7%AF%84%E5%9B%B2%E9%81%B8%E6%8A%9E.png

整形後

画像に alt 属性が指定されていません。ファイル名: ExcelVBA%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92%E6%94%B9%E5%96%84%E3%81%99%E3%82%8BRubberducks%E3%81%A7%E3%82%A4%E3%83%B3%E3%83%87%E3%83%B3%E3%83%88%E4%BF%AE%E6%AD%A3%E5%BE%8C.png
お客様

すごく読みやすくなったわ!

簡単に整形することができます。インデントは可読性をあげますので、ぜひ使ってくださいね!

フォルダ分け機能

お客様

標準モジュールやクラスモジュール、フォームが増えて、すぐに見つけれないよ💦

縁紡ぐ

Rubberduckには、フォルダ分けする機能があるから使ってみて!

STEP
Rubberduck ➡ Windows ➡ Code Explorerをクリック
STEP
モジュールに、アノテーションでフォルダ名を追加

階層型にしたい場合は、「.」で区切ってください。

STEP
Refeshボタンをクリック
STEP
Code Explorerにフォルダ形式で表示される
縁紡ぐ

簡単にフォルダ分けすることができるんだ!

お客様

すごく探しやすくなっていい感じ!

ユニットテスト

お客様

少し機能を修正したら、また、細かなテストをするのが面倒だなぁ💦

縁紡ぐ

そんな時には、Rubberduckのユニットテスト機能が便利だよ!

ユニットは、プログラムの最小単位で、通常は関数やメソッドを指します。例えば、計算を行う関数やデータを処理するメソッド単位で自動でテストできる仕組みがあります!

縁紡ぐ

ユニットテストを作成しておけば、機能変更によるテストの再実施の工数削減や、リグレッションを防ぐことが出来るよ!
最近の中規模以上のシステムではよく使われている手法ですね!

STEP
テストしたいプロシージャを作成
Function TriangleArea(base As Double, height As Double) As Double
    TriangleArea = 0.5 * base * height
End Function
STEP
Rubberduck ➡ Unit Tests ➡ Test Explorerを開く
STEP
Rubberduck ➡ Unit Tests ➡ Test Module でテスト用のモジュールを追加
STEP
コードの説明

追加されるコードに説明を追記しました。

'@TestModule
'@Folder("Tests")

Option Explicit  ' 変数を明示的に宣言することを要求します
Option Private Module  ' このモジュールをプライベートにします(他のモジュールからはアクセスできません)

Private Assert As Object  ' アサートオブジェクトを宣言
Private Fakes As Object    ' フェイクオブジェクトを宣言

'@ModuleInitialize
Private Sub ModuleInitialize()
    ' このメソッドはモジュールごとに一度だけ実行されます。
    ' Rubberduckライブラリのアサートクラスとフェイクプロバイダーを初期化します。
    Set Assert = CreateObject("Rubberduck.AssertClass")
    Set Fakes = CreateObject("Rubberduck.FakesProvider")
End Sub

'@ModuleCleanup
Private Sub ModuleCleanup()
    ' このメソッドはモジュールごとに一度だけ実行されます。
    ' 使用したオブジェクトを解放します。
    Set Assert = Nothing
    Set Fakes = Nothing
End Sub

'@TestInitialize
Private Sub TestInitialize()
    ' このメソッドはモジュール内の各テストの前に実行されます。
    ' ここに初期化コードを記述できます。
End Sub

'@TestCleanup
Private Sub TestCleanup()
    ' このメソッドはモジュール内の各テストの後に実行されます。
    ' ここでリソースの解放やクリーンアップを行います。
End Sub

'@TestMethod("Uncategorized")
Private Sub TestMethod1()  ' TODO: テスト名をリネームする
    On Error GoTo TestFail  ' エラーが発生した場合はTestFailラベルにジャンプします。
    
    ' Arrange:
    ' テストの前準備をここに記述します。
    
    ' Act:
    ' テスト対象のコードをここに記述します。
    
    ' Assert:
    ' 結果を検証するためのアサーションをここに記述します。
    Assert.Succeed  ' テストが成功した場合

TestExit:  ' テストの正常終了時の処理
    '@Ignore UnhandledOnErrorResumeNext
    On Error Resume Next  ' 以降のエラーを無視する設定
    
    Exit Sub  ' 正常に終了します

TestFail:  ' エラーが発生した場合の処理
    ' エラーメッセージをアサートに渡して失敗を記録します。
    Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
    Resume TestExit  ' 正常終了処理に戻ります
End Sub
STEP
テストコードを作成する
'@TestModule
'@Folder("Tests")

Option Explicit  ' 変数を明示的に宣言することを要求します
Option Private Module  ' このモジュールをプライベートにします(他のモジュールからはアクセスできません)

Private Assert As Object  ' アサートオブジェクトを宣言
Private Fakes As Object    ' フェイクオブジェクトを宣言

'@ModuleInitialize
Private Sub ModuleInitialize()
    ' このメソッドはモジュールごとに一度だけ実行されます。
    ' Rubberduckライブラリのアサートクラスとフェイクプロバイダーを初期化します。
    Set Assert = CreateObject("Rubberduck.AssertClass")
    Set Fakes = CreateObject("Rubberduck.FakesProvider")
End Sub

'@ModuleCleanup
Private Sub ModuleCleanup()
    ' このメソッドはモジュールごとに一度だけ実行されます。
    ' 使用したオブジェクトを解放します。
    Set Assert = Nothing
    Set Fakes = Nothing
End Sub

'@TestInitialize
Private Sub TestInitialize()
    ' このメソッドはモジュール内の各テストの前に実行されます。
    ' ここに初期化コードを記述できます。
End Sub

'@TestCleanup
Private Sub TestCleanup()
    ' このメソッドはモジュール内の各テストの後に実行されます。
    ' ここでリソースの解放やクリーンアップを行います。
End Sub

' テストケース1: 基本的なケース
'@TestMethod("Basic Case")
Private Sub TestTriangleAreaBasicCase()
    Dim result As Double
    Dim base As Double
    Dim height As Double
    
    base = 10
    height = 5
    result = TriangleArea(base, height)
    Assert.AreEqual 25#, result, "面積が正しく計算されていません。"  ' 25をDouble型として指定
TestExit:  ' テストの正常終了時の処理
    '@Ignore UnhandledOnErrorResumeNext
    On Error Resume Next  ' 以降のエラーを無視する設定
    
    Exit Sub  ' 正常に終了します

TestFail:  ' エラーが発生した場合の処理
    ' エラーメッセージをアサートに渡して失敗を記録します。
    Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
    Resume TestExit  ' 正常終了処理に戻ります
End Sub

' テストケース2: 高さが0の場合
'@TestMethod("Height Zero Case")
Private Sub TestTriangleAreaHeightZero()
    Dim result As Double
    Dim base As Double
    Dim height As Double
    
    base = 10
    height = 0
    result = TriangleArea(base, height)
    Assert.AreEqual 0#, result, "高さが0のとき、面積は0でなければなりません。"
TestExit:  ' テストの正常終了時の処理
    '@Ignore UnhandledOnErrorResumeNext
    On Error Resume Next  ' 以降のエラーを無視する設定
    
    Exit Sub  ' 正常に終了します

TestFail:  ' エラーが発生した場合の処理
    ' エラーメッセージをアサートに渡して失敗を記録します。
    Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
    Resume TestExit  ' 正常終了処理に戻ります
End Sub

' テストケース3: 負の底辺
'@TestMethod("Negative Base Case")
Private Sub TestTriangleAreaNegativeBase()
    Dim result As Double
    Dim base As Double
    Dim height As Double
    
    base = -10
    height = 5
    result = TriangleArea(base, height)
    Assert.AreEqual -25#, result, "負の底辺の場合、面積は負の値でなければなりません。"
TestExit:  ' テストの正常終了時の処理
    '@Ignore UnhandledOnErrorResumeNext
    On Error Resume Next  ' 以降のエラーを無視する設定
    
    Exit Sub  ' 正常に終了します

TestFail:  ' エラーが発生した場合の処理
    ' エラーメッセージをアサートに渡して失敗を記録します。
    Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
    Resume TestExit  ' 正常終了処理に戻ります
End Sub

' テストケース4: 負の高さ
'@TestMethod("Negative Height Case")
Private Sub TestTriangleAreaNegativeHeight()
    Dim result As Double
    Dim base As Double
    Dim height As Double
    
    base = 10
    height = -5
    result = TriangleArea(base, height)
    Assert.AreEqual -25#, result, "負の高さの場合、面積は負の値でなければなりません。"
TestExit:  ' テストの正常終了時の処理
    '@Ignore UnhandledOnErrorResumeNext
    On Error Resume Next  ' 以降のエラーを無視する設定
    
    Exit Sub  ' 正常に終了します

TestFail:  ' エラーが発生した場合の処理
    ' エラーメッセージをアサートに渡して失敗を記録します。
    Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
    Resume TestExit  ' 正常終了処理に戻ります
End Sub

' テストケース5: 両方が0の場合
'@TestMethod("Both Zero Case")
Private Sub TestTriangleAreaBothZero()
    Dim result As Double
    Dim base As Double
    Dim height As Double
    
    base = 0
    height = 0
    result = TriangleArea(base, height)
    Assert.AreEqual 0#, result, "両方が0のとき、面積は0でなければなりません。"
TestExit:  ' テストの正常終了時の処理
    '@Ignore UnhandledOnErrorResumeNext
    On Error Resume Next  ' 以降のエラーを無視する設定
    
    Exit Sub  ' 正常に終了します

TestFail:  ' エラーが発生した場合の処理
    ' エラーメッセージをアサートに渡して失敗を記録します。
    Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
    Resume TestExit  ' 正常終了処理に戻ります
End Sub
STEP
Test Explorerをリフレッシュする
STEP
作成したテストが表示される
STEP
Run ➡ AllTest ですべてのユニットテストを実施できる
STEP
ユニットテストの結果が表示される
STEP
失敗した場合の表示

テストの期待値を24にしてみます。関数の結果は、25が返ってくるのでテストが失敗します。

' テストケース1: 基本的なケース
'@TestMethod("Basic Case")
Private Sub TestTriangleAreaBasicCase()
    Dim result As Double
    Dim base As Double
    Dim height As Double
    
    base = 10
    height = 5
    result = TriangleArea(base, height)
    Assert.AreEqual 24#, result, "面積が正しく計算されていません。"  ' 24をDouble型として指定
TestExit:  ' テストの正常終了時の処理
    '@Ignore UnhandledOnErrorResumeNext
    On Error Resume Next  ' 以降のエラーを無視する設定
    
    Exit Sub  ' 正常に終了します

TestFail:  ' エラーが発生した場合の処理
    ' エラーメッセージをアサートに渡して失敗を記録します。
    Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
    Resume TestExit  ' 正常終了処理に戻ります
End Sub
STEP
テストが間違っていると問題解決に時間がかかる
縁紡ぐ

今回のは簡単なテストなので、テストが間違っていることが発見しやすいですが、複雑な処理になるとテストが間違っているのか、実際の処理するコードが間違っているか発見が難しくなるので、テストの期待値は間違いないようにしましょう!

Assertで使える種類

検証メソッドの種類です。

メソッド名説明
AreEqual2つの指定されたオブジェクトが等しいかどうかを確認します。もし等しくない場合、アサーションは失敗します。
AreNotEqual2つの指定されたオブジェクトが等しくないかどうかを確認します。もし等しい場合、アサーションは失敗します。
AreNotSame2つの指定されたオブジェクト変数が異なるオブジェクトを参照しているかどうかを確認します。もし同じオブジェクトを参照している場合、アサーションは失敗します。
AreSame2つの指定されたオブジェクト変数が同じオブジェクトを参照しているかどうかを確認します。もし異なるオブジェクトを参照している場合、アサーションは失敗します。
Fail条件をチェックせずにアサーションを失敗させます。
Inconclusiveアサーションが確認できないことを示します。
IsFalse指定された条件が false(偽)であるかどうかを確認します。もし条件が true(真)である場合、アサーションは失敗します。
IsNothing指定されたオブジェクトが Nothing(無)であるかどうかを確認します。もしそうでない場合、アサーションは失敗します。
IsNotNothing指定されたオブジェクトが Nothing(無)でないかどうかを確認します。もしそうである場合、アサーションは失敗します。
IsTrue指定された条件が true(真)であるかどうかを確認します。もし条件が false(偽)である場合、アサーションは失敗します。

リネーム機能

お客様

プロシージャ名や変数名を間違っていたから、一括で変更したい💦

縁紡ぐ

VBEでは、置換で行うしかなかったリネームですが、Rubberduckではリネーム機能を提供してくれています。

STEP
リネーム前のコード
Option Explicit

Function TriangleArea(base As Double, height As Double) As Double
    TriangleArea = 0.5 * base * height
End Function
STEP
リネームしたい場所をクリックして選択状態にする
STEP
右クリック ➡ Rubberduck ➡ Refactor ➡ Rename をクリック
STEP
新しい名前を入力し、OKボタン(今回は、TriangleAreaをComputerAreaに変更)
STEP
リネーム後

リネームは、このプロシージャを呼び出しているすべてのプロシージャ内の名前も、自動で変更してくれます。

Todoの管理

お客様

コードを書いている時に、あれも次につくらなくちゃ!って思っても、忘れちゃうことが多くて。。。タスク管理って難しい💦

縁紡ぐ

Rubberduckには、タスク管理をするための便利機能であるTodo機能があるよ!

STEP
Rubberduck ➡ Windows ➡ Todo Items をクリック

Todo Explorerが拓く

STEP
コードに、『’Todo 』の後に内容を書く
Option Explicit

Function ComputerArea(base As Double, height As Double) As Double
    ComputerArea = 0.5 * base * height
End Function


'TODO 四角形の面積を求める関数
STEP
リフレッシュボタンを押下
STEP
Todoが表示される

インターフェースの作成

縁紡ぐ

ここからは、オブジェクト指向開発する際に便利な機能です!

Rubberducのインターフェース作成機能は、実際の処理コードを作成➡インターフェース作成の流れになります。

STEP
インターフェースを作成したいコードを作成
Option Explicit

' Studentクラス
Private pName As String
Private pAge As Integer
Private pGrade As Double

' Nameプロパティ
Public Property Get Name() As String
    Name = pName
End Property

Public Property Let Name(ByVal value As String)
    pName = value
End Property

' Ageプロパティ
Public Property Get Age() As Integer
    Age = pAge
End Property

Public Property Let Age(ByVal value As Integer)
    If value < 0 Then
        Err.Raise vbObjectError + 1, "Student", "年齢は0以上でなければなりません。"
    End If
    pAge = value
End Property

' Gradeプロパティ
Public Property Get Grade() As Double
    Grade = pGrade
End Property

Public Property Let Grade(ByVal value As Double)
    If value < 0 Or value > 100 Then
        Err.Raise vbObjectError + 2, "Student", "成績は0から100の範囲でなければなりません。"
    End If
    pGrade = value
End Property

' 学生の情報を表示するメソッド
Public Function DisplayInfo() As String
    DisplayInfo = "名前: " & pName & vbCrLf & _
                  "年齢: " & pAge & vbCrLf & _
                  "成績: " & pGrade
End Function


STEP
右クリック ➡ Rubberduck ➡ Refactor ➡ Extract Interface をクリック
STEP
作成するインターフェースの内容を選択
STEP
作成後

まずは、作成されたインターフェースです。

実装クラスにImprementsが追加されます。

実装クラスにプロシージャの実装が追加されます。

縁紡ぐ

簡単にインターフェースを作成できるよ!
ぜひ、クラスを使える人は使ってみてくださいね!

インターフェースから実装クラスを作成

縁紡ぐ

インターフェースから実装クラスを作成するのもRubberduckには用意されているよ!

STEP
新しいクラスを作成し、Imprements インターフェース名を入力
STEP
Imprementの行を選択し右クリック ➡ Rubberduck ➡ Refactor ➡ Imprement Interfaceをクリック
STEP
実装が必要なプロシージャが追加される
Option Explicit

Implements IStudent

Private Property Get IStudent_Name() As String
    Err.Raise 5                                  'TODO implement interface member
End Property

Private Property Let IStudent_Name(ByVal value As String)
    Err.Raise 5                                  'TODO implement interface member
End Property

Private Property Get IStudent_Age() As Integer
    Err.Raise 5                                  'TODO implement interface member
End Property

Private Property Let IStudent_Age(ByVal value As Integer)
    Err.Raise 5                                  'TODO implement interface member
End Property

Private Property Get IStudent_Grade() As Double
    Err.Raise 5                                  'TODO implement interface member
End Property

Private Property Let IStudent_Grade(ByVal value As Double)
    Err.Raise 5                                  'TODO implement interface member
End Property

Private Function IStudent_DisplayInfo() As String
    Err.Raise 5                                  'TODO implement interface member
End Function

Todoも作ってくれるから、とっても便利です!ユニットテストのスタブやモック作成にとっても便利です!

まとめ

Rubberduckは、モダンな開発を実現してくれる便利な機能を提供してくれます。ぜひ使ってみてくださいね!

記事を書いた人

稲垣

  • Excel、ACCESSでのシステム開発が得意
  • ITスキルを共有し実践的に学びながら成長する人を見るのが幸せ
  • 自家焙煎するほどのコーヒー好き
  • 使用言語 VBA、Python、Javascript、Java、HTML、CSS etc.
  • 保有資格 Kintoneアソシエイト、日商簿記検定2級、マンション管理士、管理業務主任者、情報セキュリティマネジメント、ExcelVBA etc.
  • 業務フロー図の作成や業務時間分析を通して、効率化ポイントを探る人
  • お客様にとって本当に良いことかを第一に考える人
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次