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

こんにちは!大阪市を拠点に活動している『縁紡ぐ』の稲垣です。
SWELLを使ったホームページ制作や、Excel、ACCESS、RPAなどのシステム開発を行っています。
また、Excel、Word、Outlookの研修や、情報セキュリティ研修も行っています。身近なITの相談相手になりたいと思っています。
お気軽にお問い合わせください。
Rubberduckのおすすめ機能をご紹介
VBAを開発するための、VBEは、Visual Studio Codeやその他のコードエディタに比べて、機能面で劣っているところが多いです。
そんな、VBEをパワーアップしてくれツールがあります。

VBEを使い役する機能アップしてくれるのが、Rubberducだよ!
今回は、Rubberducで実際に縁紡ぐが使っている機能をご紹介します。
インストール方法は、下記の記事でご紹介しています。


コードの整形



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



初心者の方は、よくインデントを付け忘れるのでRubberducのインデント機能を使えば、一瞬で解決できますよ!
コードが乱れがちな場合、Rubberduckの「Indent」機能を使って、自動的に整形することができます。これで読みやすいコードに一瞬で変わります。
整形前


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


整形後





すごく読みやすくなったわ!
簡単に整形することができます。インデントは可読性をあげますので、ぜひ使ってくださいね!
フォルダ分け機能



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



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




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









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



すごく探しやすくなっていい感じ!
ユニットテスト



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



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



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








追加されるコードに説明を追記しました。
'@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
'@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








テストの期待値を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





今回のは簡単なテストなので、テストが間違っていることが発見しやすいですが、複雑な処理になるとテストが間違っているのか、実際の処理するコードが間違っているか発見が難しくなるので、テストの期待値は間違いないようにしましょう!
Assertで使える種類
検証メソッドの種類です。
メソッド名 | 説明 |
AreEqual | 2つの指定されたオブジェクトが等しいかどうかを確認します。もし等しくない場合、アサーションは失敗します。 |
AreNotEqual | 2つの指定されたオブジェクトが等しくないかどうかを確認します。もし等しい場合、アサーションは失敗します。 |
AreNotSame | 2つの指定されたオブジェクト変数が異なるオブジェクトを参照しているかどうかを確認します。もし同じオブジェクトを参照している場合、アサーションは失敗します。 |
AreSame | 2つの指定されたオブジェクト変数が同じオブジェクトを参照しているかどうかを確認します。もし異なるオブジェクトを参照している場合、アサーションは失敗します。 |
Fail | 条件をチェックせずにアサーションを失敗させます。 |
Inconclusive | アサーションが確認できないことを示します。 |
IsFalse | 指定された条件が false(偽)であるかどうかを確認します。もし条件が true(真)である場合、アサーションは失敗します。 |
IsNothing | 指定されたオブジェクトが Nothing(無)であるかどうかを確認します。もしそうでない場合、アサーションは失敗します。 |
IsNotNothing | 指定されたオブジェクトが Nothing(無)でないかどうかを確認します。もしそうである場合、アサーションは失敗します。 |
IsTrue | 指定された条件が true(真)であるかどうかを確認します。もし条件が false(偽)である場合、アサーションは失敗します。 |
リネーム機能



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



VBEでは、置換で行うしかなかったリネームですが、Rubberduckではリネーム機能を提供してくれています。
Option Explicit
Function TriangleArea(base As Double, height As Double) As Double
TriangleArea = 0.5 * base * height
End Function






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


Todoの管理



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



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


Todo Explorerが拓く


Option Explicit
Function ComputerArea(base As Double, height As Double) As Double
ComputerArea = 0.5 * base * height
End Function
'TODO 四角形の面積を求める関数




インターフェースの作成



ここからは、オブジェクト指向開発する際に便利な機能です!
Rubberducのインターフェース作成機能は、実際の処理コードを作成➡インターフェース作成の流れになります。
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




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


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


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





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



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




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.
- 業務フロー図の作成や業務時間分析を通して、効率化ポイントを探る人
- お客様にとって本当に良いことかを第一に考える人
コメント