VBA Microsoft Accessでクラスを作ってみた

#VBA Microsoft Accessにおけるクラス

いつもはSwiftを勉強していますが、今回はMicrosoft Accessの手直しを少ししまして、ついでにクラスを作って組み込みました。

基本的にはクラスの記述はSwiftと同じような感じでしたが、やはり細い記述文法は違いました。あとは入力補完機能はswiftの方が便利に感じました。

今回の手直しで付加した機能は、対象の取引先について支払金額が〇〇万円以上になると、割引率をかけて、その金額を差し引いた金額を支払い金額にする機能です。
こういうの売上割引とか仕入割引とかって言うんですかね。
これを今までは紙で取引先を確認して手で計算していたそうで、今回はそれを自動化します。



###　　


##今回の簡単な流れ

####① 割引のクラスを作成する。

####② VBの中に①を組込む。

####③ 割引先マスターを作成する。

####④ フォーム、プロシージャに②、③を結びつける。
###　　

##① 割引のクラスを作成する
割引クラスの目的は割引関する情報(金利、入力された金額、割引日数、1年間の日数)を元に金利割引の計算をすることです。
クラスの中身はとてもシンプルで、変数宣言、イニシャライズ 、関数が一つで完成です。

```vb

Option Compare Database

Public current As Double '計算結果を返す変数です
Public InterestRates As Double  '利率を表す変数です
Public Money As Double '金額を表す変数です
Public DaysNumerator As Double '割引日数を表す変数です
Public DaysDenominator As Double '割引日数の分母を表す変数です

Private Sub class_initialize() '初期化しています
    current = 0
    InterestRates = 0
    Money = 0
    DaysNumerator = 0
    DaysDenominator = 0
End Sub

Public Sub InterestRatecal() '仕事で使うようなので、NULL値に対してのエラーコードも書きました。
 
   If IsNull(Money) Then
        Err.Raise 80000, , "エラー：金利の利率がNULL値です。"
        Exit Sub
        
    ElseIf IsNull(InterestRates) Then
        Err.Raise 80001, , "エラー：金額がNULL値です。"
        Exit Sub
            
    ElseIf IsNull(DaysNumerator) Then
        Err.Raise 80002, , "エラー：計算日数がNULL値です。"
        Exit Sub
            
    ElseIf IsNull(DaysDenominator) Then
        Err.Raise 80003, , "エラー：計算日数がNULL値です。"
        Exit Sub
    
    Else
        current = Round(Money * (InterestRates / 100) * DaysNumerator / DaysDenominator, 0)
        
    End If
   
End Sub
```


###　　
    
##② VBの中に①を組込む。

####クラスのインスタンス化
①で作成したクラスを取引先の金額を入力した後のイベントプロシージャに入力します。

まずクラスをインスタンス化して、使えるようにします。
クラスの宣言は　Dim 変数名 As New クラス名　でできます。

```vb
Dim instanceRate As New interestRate
```

それに対しての関数の呼び出しは　 Call インスタンス名.関数名　で呼び出すことができます。

```vb
Call instanceRate.InterestRatecal
```

###　



##③ 割引先マスターを作成する。
今回は既存の取引先マスターがあったので、そこに、金利率と割引日数をフィールドとして追加しました。
金利率は今回の計算の対象ではない取引先は0としました。

ここはこれだけで終わりです。


###　



##④ フォーム、プロシージャに②、③を結びつける。

とりあえず分岐は全てif文を組みました。また、クラス内の関数の計算は引数ではなく、クラス内の変数を計算に使いました。

if文は
金利率が0かどうか(取引先が計算対象かどうか)　→ 金額は条件通りか　となっています。その他のif文はエラー対策です。

取引先マスターテーブルに追加した金利率と割引日数についてはDLookup関数を用いて、検索した取引先コードのレコードから金利率と割引日数を値として返して、それを変数に代入しています。


```vb

    Dim instanceRate As New interestRate 'クラスのインスタンス化
    Dim msgA As String 'YES NOのダイアログで使用する変数
    Dim pickUpRate As Double 'YES NOのダイアログで使用する変数
    Dim search As String 'DLookupで使用する変数　取引先コードを入れる
    Dim payment As Long '支払金額を入力したテキストボックスの値を入れる変数
    Dim dayCount As Double '日数計算の分子となる部分　利息計算なので、とりあえずダブル型にしました
    
    payment = テキストボックス(支払金額) '割引計算発生のタイミング
    search = [取引先コード] '取引先マスターテーブルにある金利と割引日数の金額を持ってくる前準備
    pickUpRate = Nz(DLookup("[金利率]", "取引先マスターテーブル", "[取引先コード] ='" & search & "'"), 0)
  
    If pickUpRate = 0 Then '金利率が0なら何も起こらないようにしています
        Exit Sub
    Else
        If payment >= 100000 Then '割引計算発生のタイミング　今回は仮で、100000円以上なら機能が動くようにしました

            dayCount = Nz(DLookup("[日数]", "取引先マスターテーブル", "[取引先コード] ='" & search & "'"), 0)
            instanceRate.DaysNumerator = dayCount
            instanceRate.InterestRates = pickUpRate
            instanceRate.DaysDenominator = 365 '変数にしようと思ったのですが、計算の分母は常に365日で計算するみたいです。
    
            If IsNull(payment) Then
                Err.Raise 80001, , "エラー：金額がNULL値です。"
                Exit Sub
            Else
                instanceRate.Money = payment
            End If

            Call instanceRate.InterestRatecal 'ここでクラスの関数計算を行なっています
            Me.テキストボックス(金利計算) = instanceRate.current '計算結果をここで金利計算のテキストボックスに返します。
            MsgBox "割引金額を計算しました。"
    
        Else
            If テキストボックス(金利計算) > 0 Then
                msgA = MsgBox("金額が割引計算の条件を満たしていません。訂正しますか？", vbYesNo)
                If msgA = vbYes Then
                    Me.テキストボックス(金利計算) = 0
                    MsgBox "金額を訂正しました。"
                Else
                    Cancel = True
                End If
            Else
                Exit Sub
            End If
        End If
    End If
End Sub
```

これで完成です。