コロナの影響で今日は自宅待機。
テレワーク端末は支給されなかったので、家のパソコンで作ろうとしてるVBAツールの予習をする。
テレワーク(準テレワーク)って雑音が入らなくってすてき。
ああ、あこがれのテレワーク。
ExcelVBAで請求書作成ツールを作成。
例に使うのは変な請求書だけれども、本チャンの作ろうとしてるツールに近いものなのでご容赦ください。
データシートに取引先と請求単価、件数を入力しておき、1行ずつ請求書を起こしていくもの。取引先によって「請求書はこうゆう形にしてほしい」とわがままを言う先があるので、一律の形にならないものあり。その対処も入れています。(ツールの書式4の場合)
標準モジュールとクラスモジュールを使っています。
なぜクラスを使うかというとクラスを使うのが「VBAできる人っぽい」から、無理矢理に使おうとしている。
実際どうゆうときに使うべきなのか、クラスの利用に限らず「これでよかったのだろうか。もっとベストな素敵な方法があったのではないか」といつもいつも完成後も迷いは消えません。
コード
■クラス cData こちらを構造体(?)として使います
‘構造体(取引先毎)
Public no As String
Public name As String
Public tanka1 As Long
Public tanka2 As Long
Public tanka3 As Long
Public ken1 As Long
Public ken2 As Long
Public ken3 As Long
Public kijitu As Date
Public syosiki As Long
Public flag As Boolean
Sub getdata(ByVal r As Long) ’データ取得メソッド
With wsData
no = .Cells(r, colA).Value ‘取引先ID
name = .Cells(r, colB).Value ‘取引先名
tanka1 = .Cells(r, colC).Value ‘単価1
tanka2 = .Cells(r, colD).Value ‘単価2
tanka3 = .Cells(r, colE).Value ‘単価3
ken1 = .Cells(r, colF).Value ‘件数1
ken2 = .Cells(r, colG).Value ‘件数2
ken3 = .Cells(r, colH).Value ‘件数3
kijitu = .Cells(r, colM).Value ‘支払期日
syosiki = .Cells(r, colN).Value ‘書式区分
’金額が0の場合flagはFalse
If .Cells(r, colL).Value = 0 Then
flag = False
Else
flag = True
End If
End With
End Sub
■クラス cInput 構造体cDataを利用して請求書作成するメソッドとして使います
Private wsSyosiki2 As Worksheet
Private wsSyosiki3 As Worksheet
Private wsSyosiki4 As Worksheet
Private sakuseibi As Date
Private tanto As String
Private tel As String
‘クラス立ち上げ時に書式シートをセット
Set wsSyosiki1 = Worksheets(“書式1”)
Set wsSyosiki2 = Worksheets(“書式2”)
Set wsSyosiki3 = Worksheets(“書式3”)
Set wsSyosiki4 = Worksheets(“書式4”)
‘書式シート表示
wsSyosiki1.Visible = True
wsSyosiki2.Visible = True
wsSyosiki3.Visible = True
wsSyosiki4.Visible = True
‘固定データセット
Me.getDataKotei
End Sub
‘クラスの破棄時に走る
‘書式シート非表示
wsSyosiki1.Visible = False
wsSyosiki2.Visible = False
wsSyosiki3.Visible = False
wsSyosiki4.Visible = False
End Sub
Sub getDataKotei()
‘固定データを取得
With wsData
sakuseibi = .Range(“B2”).Value
tanto = .Range(“B4”).Value
tel = .Range(“B5”).Value
End With
End Sub
Function pMain(ByVal r As Long) As Long
‘該当行のデータ取得
Set cd = New cData ※クラスcData使用する
cd.getdata r
‘書式によって場合分け
Select Case cd.syosiki
Case 1 To 3
pMain = Me.prnt(r, cd) ※1呼び出し
Case 4
pMain = Me.prnt4(r)
End Select
Set cd = Nothing ※クラスcData破棄
End Function
Function prnt(ByVal r As Long, cd As cData) As Long
‘flagがTrueの場合if以下の★請求書作成処理★
‘flagがFalseの場合(請求金額ゼロ)★請求書作成処理★飛ばして☆へ進む
If cd.flag = True Then
‘★請求書作成処理★
‘syosikiに応じで書式シートをwsにセット
Dim ws As Worksheet
Select Case cd.syosiki
Case 1
Set ws = wsSyosiki1
Case 2
Set ws = wsSyosiki2
Case 3
Set ws = wsSyosiki3
End Select
‘書式をコピー。endシートの前に挿入
ws.Copy Before:=wsEnd
With ActiveSheet
‘シート名を取引先IDとする
.name = cd.no
‘固定データインプット
Me.inpKotei
Me.inpData 16, cd.ken1, cd.tanka1 ’16行目に件数1、単価1を入力
If cd.syosiki = 2 Then
Me.inpData 20, cd.ken2, cd.tanka2 ’20行目に件数2、単価2を入力
ElseIf cd.syosiki = 3 Then ‘書式3の場合18・22行目も入力
Me.inpData 20, cd.ken2, cd.tanka2 ’20行目に件数2、単価2を入力
Me.inpData 24, cd.ken3, cd.tanka3 ’24行目に件数3、単価3を入力
End If
End With
End If
‘☆行数を返す。★請求書作成処理★しなくても行数は+1する
prnt = r + 1
End Function
‘書式4の場合
‘もうひとつクラスcDataインスタンス作成
‘cdに1行目データ
‘cd2に2行目データ
Dim cd2 As cData
Set cd2 = New cData
cd2.getdata r + 1
‘作業の場合分け
‘書式4の場合は2行処理が必要
‘1行目、2行目とも金額ゼロの場合、flag2=False(=何もしない処理へ進む)
‘1・2行目いずれかが金額ゼロでない場合は、★請求書作成処理★へ進む
Dim flag2 As Boolean
flag2 = True ‘初期値はTrue
If cd.flag = False And cd2.flag = False Then
‘1行目、2行目とも金額ゼロの場合、flag2=False(=★請求書作成処理★飛ばして☆へ) flag2 = False
End If
‘★請求書作成処理★
‘書式4をコピー。endシートの前に挿入
If flag2 = True Then
wsSyosiki4.Copy Before:=wsEnd
With ActiveSheet
‘シート名を取引先IDとする
.name = cd.no
‘固定データインプット
Me.inpKotei
‘1行目データインプット
.Range(“C14”).Value = cd.no ‘書式4の場合は取引先IDを入力
Me.inpData 17, cd.ken1, cd.tanka1 ’17行目に件数1、単価1を入力
‘2行目データインプット
Range(“C19”).Value = cd2.no ‘書式4の場合は取引先IDを入力
Me.inpData 22, cd2.ken1, cd2.tanka1 ’22行目に件数1、単価1を入力
Me.inpData 26, cd2.ken2, cd2.tanka2 ’26行目に件数2、単価2を入力
End With
End If
Set cd2 = Nothing ‘もうひとつクラスcDataインスタンス破棄
‘☆一行飛ばした行数を返す
prnt4 = r + 2
End Function
‘固定データインプット
With ActiveSheet
.Range(“G2”).Value = sakuseibi ‘請求日入力
.Range(“G5”).Value = tanto ‘担当者入力
.Range(“G6”).Value = tel ‘電話番号入力
.Range(“B8”).Value = cd.kijitu ‘支払期日入力
.Range(“A3”).Value = cd.name ‘取引先名入力
End With
End Sub
Sub inpData(ByVal rTrg As Long, ByVal ken As Long, tanka As Long)
‘rTrg行に件数、単価を入力
With ActiveSheet
.Cells(rTrg, colB).Value = ken
.Cells(rTrg, colE).Value = tanka
End With
End Sub
コメント