家計簿アプリ

ExcelVBAで家計簿アプリを作ろう その4-2

家計簿アプリ
スポンサーリンク

●今までプログラミングなんかに触れたことが無くて
  「今更そんなの使いこなせるわけない」と思っている方
●小学校でプログラミングが必修科目になり、
  子どもに「ここ分からないから教えて~」と言われても
 「無理!!」と言うしかなくて困ったお父さん・お母さん

そんなプログラミング全くの初心者に向けて
 「こうやったら自動で動くソフト(Excelマクロ)が作れるんだ!」
というのを理解していただくように、
ゼロからソフトを作っていく過程を紹介していきたいと思います。

Windowsのパソコンがあれば大抵標準装備されているExcelを使って紹介しますので、
この投稿のシリーズを最後まで読んでいただければ、
また、投稿を読みながら実際に一緒にソフトを作っていっていただければ、
 「自分で実際にソフトを作ることができて、プログラミングに少し自信がついた!
と思ってもらえるかと思いますので、是非とも一緒に手を動かしてみてください。

【本記事の目標】

シート複製時の注意点と対策について知ろう

前回の記事でシートの複製・操作について記載しました。

しかし、前回の記事の最後に記載したコードでは、実際に動かしたときに困ったことが起こります。

今回はその原因と対策について記載していきます。

前回の記事をまだ見られていない方は、前回記事をご確認いただいた後の方が理解が早いかと思います。



シート複製時の課題とは?

実際に動かして確認してみましょう

それでは、現時点でのコードで起こる困ったことというのはどういうことでしょうか。

それは実際に一度動かしてみていただけると分かると思います。

例えば、2022年9月、10月、11月のシートを複製してみてください。
そうすると、下記のようにそれぞれの年/月が書かれた複数のページが作られます。

この作られたシートを見ていくと、「入力」のシートと同じ配置になっているはずです。

同じ配置になっているということは、『リストに追加』や『シートの複製・初期化』のボタンも同じように、各シートに存在しており、
それぞれのシートでこのボタンを押すと、同じようにマクロが起動します。

じゃあ、例えば、「2022年9月」を作った後に9が鵜tの追加支出があることがわかって、後からこのシートに記入したい、となったときに、
「2022年9月」のシートの『リストに追加』をクリックしたらリストに追加されるのか、
というと、そうはなりません。

実際にクリックしてみていただくと分かりますが、何も変化が起こらないように見えるはずです。

じゃあ単純にマクロが動かなくなったのか、というとそうではなく、確かに動いているのです。
どこが動いているのかというと、
「入力」のシートのリストが増えているはずです。

これが、現時点でのコードで起こる困ったことです。

 



なぜこんなことが起こる?

「2022年9月」のシートにあるボタンを押したのに、なぜ「入力」のシートが動いてしまうのか?

それはこのボタンに登録したマクロを見ればわかります。

このボタンに登録したマクロは下記の通りです。

Option Explicit

Sub KamokuInput_1()
'リストに追加をクリック

Dim Kingaku1 As Double

Kingaku1 = ThisWorkbook.Sheets("入力").Range("B1").Value


Dim Syushi1 As String
Dim Kamoku1 As String

Syushi1 = ThisWorkbook.Sheets("入力").Range("D1").Value

If Syushi1 = "収入" Then
    Kamoku1 = ""
Else
    Kamoku1 = ThisWorkbook.Sheets("入力").Range("E1").Value
End If



Dim EndRow1 As Integer

With ThisWorkbook.Sheets("入力")

EndRow1 = .Cells(.Rows.Count, 1).End(xlUp).Row
EndRow1 = EndRow1 + 1


.Cells(EndRow1, 1).Value = Syushi1
.Cells(EndRow1, 2).Value = Kamoku1

If Syushi1 = "収入" Then
    .Cells(EndRow1, 3).Value = Kingaku1
Else
    .Cells(EndRow1, 4).Value = Kingaku1
End If

End With

Call Jisaku_SUM

End Sub

これを見て、何か違和感を感じられた方は、マクロに慣れてきた証拠です!

違和感の正体は、要所要所で何回か出てくる

  ThisWorkbook.Sheets(“入力”)

というコードです。
これは、「このExcelファイルの、「入力」というシート」を操作するときに使うコードです。

「入力」シートを操作しているときはこのコードで問題がなかったですが、
シートを複製して「2022年9月」のシートを作り、そのシートを操作したい場合は、
例えばこれを

  ThisWorkbook.Sheets(“2022年9月”)

という形に書き換えないといけないのです。
しかし、そのような書き換えをするようになっておらず、
「入力」シートに固定されてしまっているので、
このマクロをどのシートから動かしても、必ず「入力」シートが動いてしまうのです。

なので、この部分を書き直して、各シートのボタンを押すと、各シートで動くようにする必要があります。



各シートで動くようにするには?

Sheets(“入力”) を Activesheet に入れ替える

じゃあ、この部分をどう書き直せば各シートで動くようにできるのか?

一番簡単な方法は、
  ThisWorkbook.Sheets(“入力”)
これを全て、
  ThisWorkbook.Activesheet
に書き換えてしまうことです。

文の途中にあろうと、文の最後にあろうと気にせず、
とにかく全てを書き換えてしまえば、各シートごとに動くようにできます。

実際に書き換えたバージョンのコードは下記の通りです。

Option Explicit

Sub KamokuInput_1()
'リストに追加をクリック

Dim Kingaku1 As Double

Kingaku1 = ThisWorkbook.ActiveSheet.Range("B1").Value


Dim Syushi1 As String
Dim Kamoku1 As String

Syushi1 = ThisWorkbook.ActiveSheet.Range("D1").Value

If Syushi1 = "収入" Then
    Kamoku1 = ""
Else
    Kamoku1 = ThisWorkbook.ActiveSheet.Range("E1").Value
End If



Dim EndRow1 As Integer

With ThisWorkbook.ActiveSheet

EndRow1 = .Cells(.Rows.Count, 1).End(xlUp).Row
EndRow1 = EndRow1 + 1


.Cells(EndRow1, 1).Value = Syushi1
.Cells(EndRow1, 2).Value = Kamoku1

If Syushi1 = "収入" Then
    .Cells(EndRow1, 3).Value = Kingaku1
Else
    .Cells(EndRow1, 4).Value = Kingaku1
End If

End With

Call Jisaku_SUM

End Sub

また、このコードは【Jisaku_SUM】というプロシージャも呼び出しているので、
そちらのコードにも
  ThisWorkbook.Sheets(“入力”)
が入っていれば、これらも全て、
  ThisWorkbook.Activesheet
に書き換える必要があります。

書き換えた後の【Jisaku_SUM】のプロシージャは下記の通りです。

Option Explicit

Sub Jisaku_SUM()
'自作の関数を使った集計

Dim SyunyuSyukei3 As Double
Dim ShisyutsuSyukei3 As Double
Dim i As Integer
Dim EndRow2 As Integer

Dim Koteihi As Double
Dim Hendouhi As Double

With ThisWorkbook.ActiveSheet

EndRow2 = .Cells(.Rows.Count, 1).End(xlUp).Row

For i = 4 To EndRow2

If IsError(.Cells(i, 3).Value) Then

Else

SyunyuSyukei3 = SyunyuSyukei3 + .Cells(i, 3).Value
ShisyutsuSyukei3 = ShisyutsuSyukei3 + .Cells(i, 4).Value

If .Cells(i, 2).Value = "固定費" Then

Koteihi = Koteihi + .Cells(i, 4).Value

End If

If .Cells(i, 2).Value = "変動費" Then

Hendouhi = Hendouhi + .Cells(i, 4).Value

End If


End If
Next i

.Range("G5") = SyunyuSyukei3
.Range("G6") = ShisyutsuSyukei3

.Range("G8") = Koteihi
.Range("G9") = Hendouhi

End With

End Sub

このコードに書き換えてもらえば、複製した各シートごとで『リストに追加』のマクロを動かすことができるようになります。

今回のように、決まった文言を入れ替えたい場合は、【置換】を使うと簡単に入れ替えることができます。

【置換】を行う場合は、
   Ctrl+H
のショートカットで【置換】ウィンドウを開いて行います

置換を行う場合は、入れ替えるの文字を「検索する文字列(F)」に入力し、
入れ替えたの文字を「置換後の文字列(W)」に入力します。

その後、置換を行いたい部分を選択して、『置換(R)』もしくは『すべて置換(A)』をクリックして置換を実行します。
(置換できる場所が複数あった場合、『置換(R)』はクリックするごとに1か所ずつ置換され、『すべて置換(A)』は1度クリックするだけで全箇所置換されます。)

今回の場合だと、コードが書いてあるすべての部分にある「Sheets(“入力”)」を置換したいので、コードのすべてを全て選択した後、置換ウィンドウを上記のように入力し『すべて置換(A)』をクリックします。
(コードを記載したモジュールを開いた状態でCtrl+Aすると全選択が可能です。)

 



Activesheetって何?

そもそもですが、今回のActivesheetというのは何なのでしょうか。

単純に、「現在アクティブになっているシート」という意味ですが、
では アクティブ というのはどういう状態かというと、
分かりやすく言うと、
  『今画面に表示されていて操作している場所』
というのがアクティブな場所です。

例えば、下記のように複数のシートがある場合、
今操作しているのは「2022年9月」のシートですので、「2022年9月」というのがActiveSheetになります。

この「アクティブ」というのは、
シートだけでなくセル(ActiveCell)ファイル自体(Activeworkbook)でも同じ意味になります。

今画面上に表示されている部分を操作したい、という場合によく使うコードですので、知っていると便利かと思います。



『シートの複製・初期化』のボタンはどうする?

シートの複製は「入力」シートだけ

『リストに追加』のボタンはシートを複製した後も使えると便利なので、マクロを修正して使えるようにしました。

じゃあ、『シートの複製・初期化』のボタンはというと、こちらは「入力」シートでしか複製しないですし、入力済みのシートで不用意にクリックしてしまって初期化してしまうと困るので、複製した後は無くなっていた方が使いやすいです。
なので、複製後のシートからこのボタンを消すコードを追加しましょう。

「シートの複製・初期化」のボタンを消す

それでは「シートの複製・初期化」のボタンを消すコードを書いていきましょう。

このボタンは、図形の「正方形/長方形」で作っています。
このような図形を操作する場合は Shape というコードを使います。

Shapeの使い方

今回の例だと、Shapeは下記のような使い方をします。

 ThisWorkbook.ActiveSheet.Shape(“正方形/長方形 5”).Delete

ThisWorkbook.ActiveSheet

ここで [ThisWorkbook.ActiveSheet] は、その図形がどこのシートにあるかを書いています。
この場合、このファイルのアクティブなシートを指します。

Shape(“正方形/長方形 5”)

Shapeの後ろのカッコには図形の名前、もしくは番号を入力します。
番号というのは、図形を作成したときに、作成した順番に自動的に付けられる番号です。
図形の名前というのも、図形を作成したときに、自動的に付けられます。

図形の名前を確認する方法は2つあります。
1つ目は、図形を選択したときに、シートの左上の欄に図形の名前が表示されます。

 



2つ目は、ツールバーにある「ホーム」⇒「検索と選択」⇒「オブジェクトの選択と表示(P)」をクリックし、「選択」のサイドウィンドウを開きます。
そこに表示されているのが、今のシートにある全ての図形の名前一覧で、
名前をクリックすると、その図形がどこにあるかがわかります。

どちらかの方法で図形の名前を確認できれば、その名前をShapeの後ろのカッコの中に書けば、その図形の操作ができます。

今回の『シートの複製・初期化』のボタンは、複製後のシートでは【正方形/長方形 5】という名前になっていたので、Shapeのカッコの後ろも Shape(“正方形/長方形 5”) にしています。

.Delete

Shapeの後ろのドット(.)以降はその図形に対する操作の部分です。
ここを色々書き換えることで、
図形自体が持っている情報(プロパティ)の抽出・書き換えや、
図形の操作(メソッド)を行うことができます。

今回の場合、図形を削除したいので .Delete というメソッドを記載しています。

図形を削除するコードを記載する

それではこのコマンドを実際のコードにも入れていきましょう。

図形を削除は、シートの複製を行った後に実行したいので、
シートの複製のコードの一番最後に記載します。

Option Explicit

Sub SheetCopy1()
'シートの複製

Dim YearInput As Integer
Dim MonthInput As Integer

With ThisWorkbook.Sheets("入力")

YearInput = .Range("I1").Value
MonthInput = .Range("K1").Value

End With


ThisWorkbook.Sheets("入力").Copy After:=ThisWorkbook.Sheets("入力")

ActiveSheet.Name = YearInput & "年" & MonthInput & "月"


ThisWorkbook.Sheets("入力").Range("A4:D10000").ClearContents


ThisWorkbook.ActiveSheet.Shapes("正方形/長方形 5").Delete


End Sub

これで実行すると、複製後のシートから『シートの複製・初期化』のボタンが消えているはずです。

今回は図形の名前が「正方形/長方形 5」でしたが、各々が操作した順番によってこの名前が変わる可能性があります。
必ず自分のファイルでの「シートの複製・初期化」のボタンの名前を確認しましょう。

また、「入力」のシートと複製後のシートでは「シートの複製・初期化」のボタンの名前が変わっている可能性もあります。
その場合は、複製後のシートにある図形の名前を使いましょう。

これでシートを複製した後も問題なく使えるようになりました。
次は複製したシートの情報を集約していきます。
家計簿アプリもいよいよ大詰めです!頑張りましょう!

コメント

タイトルとURLをコピーしました