見出し画像

【Ecxel VBA】標準モジュールから、クラスモジュールへ移動

クラスモジュールについて、イマイチ理解できない部分がある人なら、読んでほしいです。
今回は、標準モジュールから、クラスモジュールへコードを実際に移行します。

標準モジュールから、クラスモジュールへ移動

こんにちは。伊川(@naonaoke)です。
ご視聴者様から、頂いたコードをもとに説明をしたいと思います。
今回は、ご提供ただいたコードなので、そのまま記載します。
但し、全部を用意はできないので、ブログで、確認しながら、作成してみてください。
ネット上の、情報は、沢山ありますが、標準モジュールから、クラスモジュールへ実際に移行する情報は、ほとんどないと思います。
また、実際に実務で利用しているコードです。
ぜひ参考にしていただければと思います。

このブログはこんな人にお勧め

クラスモジュールを勉強している人
標準モジュールから、クラスモジュールへコードを移行したい人
クラスモジュールをネットで調べてもい理解できない人

このブログを、読み終わるころには・・・・

恐らくは、クラスモジュールを完全に理解はできないと思います。
クラスモジュールを理解したい人は、コードをExcelへ転記して、眺めてください。
理解できななくてもいいので、とりあえず、眺めてください。
なにか、大きなヒントがあるかもしれません。

クラスモジュール

前回の記事で、クラスモジュールには、2つの側面があると説明しました。
キャラクター設定と、辞書機能です。
今回は、まさに、コードを移行してきます。
理解できなくても、完成のコードは眺めてください。

標準モジュールから、クラスモジュールへ 作業手順 その1 移行する前の準備

その前の、前提条件が必要となります。

画像1

同一フォルダ内に、格納フォルダと、私が今回説明するファイルを置いてください。
さらに、格納フォルダにExcelファイルを置いてください。

画像2

ファイルの名前は、何でもいいです。
そして、そのファイルに、下図のように2列に数字を記入してください。

画像3

これで、準備完了です。

標準モジュールから、クラスモジュールへ 作業手順 その2 標準モジュールを確認する

Sub Normal転記_A社用()
   Dim i As Integer '転記先の行数を取得
   Dim strPath, strFile As String 'ファイルのパス(フォルダ)/転記元のファイル名
   Dim Ws_this, Ws_that As Worksheet '転記先のシート/転記元のシート名
   Dim Lastrow As Long '最終行を取得
   
   With Application
   .ScreenUpdating = False '画面表示更新止める
   .Calculation = xlCalculationManual '計算を手動
   
   Set Ws_this = ThisWorkbook.Worksheets("集計用") 'このファイル集計用シートを記憶
   strPath = ThisWorkbook.Path 'ファイルPathを取得
   
   i = 2 '集計用シートの2行目をデフォルト値に設定
   Do While Ws_this.Cells(i, 1) <> "" 'このファイルの集計用シートA列の未行を調べる
       i = i + 1
   Loop
   '##見つける対象ファイルの格納場所##
   strFile = Dir(strPath & "\格納フォルダ\" & "*")
   
   Do While strFile <> ""  '対象ファイルが無くなるまで処理をループ
   Workbooks.Open strPath & "\格納フォルダ\" & strFile '対象ファイル開く
   Set Ws_that = Workbooks(strFile).Worksheets("データ") '対象ファイルの「データ」シートを記憶
   Lastrow = Ws_that.Cells(Rows.Count, 1).End(xlUp).Row
   
   Ws_this.Cells(i, 1).Value = Ws_that.Cells(Lastrow, 1).Value
   Ws_this.Cells(i, 2).Value = Ws_that.Cells(Lastrow, 2).Value
   Ws_this.Cells(i, 3).Value = Ws_that.Cells(Lastrow, 3).Value
   Ws_this.Cells(i, 4).Value = Ws_that.Cells(Lastrow, 4).Value
   Ws_this.Cells(i, 5).Value = Ws_that.Cells(Lastrow, 5).Value
   Ws_this.Cells(i, 6).Value = Ws_that.Cells(Lastrow, 6).Value
   Ws_this.Cells(i, 7).Value = Ws_that.Cells(Lastrow, 7).Value
   Ws_this.Cells(i, 8).Value = Ws_that.Cells(Lastrow, 8).Value
   Ws_this.Cells(i, 9).Value = Ws_that.Cells(Lastrow, 9).Value
   Ws_this.Cells(i, 10).Value = Ws_that.Cells(Lastrow, 10).Value
   Ws_this.Cells(i, 11).Value = strFile 'ファイル名記載
   Ws_this.Cells(i, 12).Value = Now() '日時記載

   Application.DisplayAlerts = True
   Workbooks(strFile).Close '閉じる
   Application.DisplayAlerts = False
   strFile = Dir()
   i = i + 1
   Loop

   .ScreenUpdating = True '画面表示を更新する
   .Calculation = xlCalculationAutomatic '計算自動
   End With
   
   Set Ws_this = Nothing: Set Ws_that = Nothing
   MsgBox "作業完了"
End Sub

このようなコードになります。

画像4

実行すると、格納フォルダ内のExcelのJ列までの情報が、転記されます。
その転記情報の横に、転記元のファイル名と、日時が追記されます。

このコードをクラスモジュールへ移行します。

標準モジュールから、クラスモジュールへ 作業手順 その3 変数系をクラスモジュールへ移行

画像5

変数の名前が、若干異なっています。
ここでは、説明は割愛しますが、後々理解できます。

標準モジュールから、クラスモジュールへ 作業手順 その4 プロパティをセットする


画像6

画像7


標準モジュールから、クラスモジュールへ 作業手順 その5 参照設定

画像8

標準モジュールから、クラスモジュールへ 作業手順 その6 付属品をクラスモジュールへ移行

画像9

Class_Initialize  Class_Terminate は、インスタンス作成時に、自動で実行されます。
Initialize⇒初期化
Terminate⇒終了させる
Terminaterは終了させる人、つまり殺し屋ですね。
ちなみに、Under Takerは、下で運ぶ人、つまり、葬儀屋ですね。請負人等の意味もあります。

標準モジュールから、クラスモジュールへ 作業手順 その7 メイン部分をクラスモジュールへ移行


画像10

標準モジュールから、クラスモジュールへ 作業手順 その8 標準モジュールのコード

画像11

標準モジュールのコードは、たった6行です。

標準モジュールから、クラスモジュールへ 作業手順 その9 クラスモジュールの完成コード

Option Explicit
 Private ii As Integer '標準モジュールからiの行数を受け取る変数
 Private Path As String '標準モジュールからファイルPathを受け取る変数
 Private Wsthis As Worksheet '標準モジュールこのファイルのシート情報を受け取る変数
 Private File As String '標準モジュールから対象ファイルの情報を受け取る変数
 Private Wsthat As Worksheet 'ClassモジュールのSubプロシージャー内で値を使い回すための変数
 Private Lastrow As Long '最終行取得用
Property Let i(arg As Integer) '標準モジュールのiの値を取り込む
   ii = arg
End Property
Property Let strPath(arg As String) '標準モジュールのstrPathの値を取り込む
   Path = arg
End Property
Property Get strPath() As String   '【共有】標準モジュール側からstrPathの値を参照できるようにする設定
   strPath = Path
End Property
Property Set Ws_this(argSheet As Worksheet) '標準モジュールのWs_thisの値を取り込む
   Set Wsthis = argSheet
End Property
Property Let strFile(arg As String) '’'Public Sub tenkikaishiのLrowの値を定義する
   File = arg
End Property
Property Get strFile() As String '【共有】標準モジュール側からstrFileの値を参照できるようにする設定
   strFile = File
End Property
Property Set Ws_that(argSheet As Worksheet) 'ClassモジュールのSubプロシージャのstrFileの値を取り込む
  Set Wsthat = argSheet
End Property
Property Let Lrow(arg As Long) '標準モジュールのstrFileの値を取り込む
   Lastrow = Wsthat.Cells(Rows.Count, 1).End(xlUp).Row
End Property
Private Sub Class_Initialize() 'Classインスタンス生成時に初期設定
   Application.ScreenUpdating = False '画面表示更新をストップ
   Application.Calculation = xlCalculationManual '計算手動
End Sub
Private Sub Class_Terminate() '後片付け
   Set Ws_that = Nothing
   Set Ws_this = Nothing
   Application.ScreenUpdating = True '画面表示更新
   Application.Calculation = xlCalculationAutomatic '計算自動
   MsgBox "作業完了", vbInformation
End Sub
Public Sub TenkiKaishi()

   Do While Wsthis.Cells(ii, 1) <> "" 'データ貼り付けするシート、A列の空欄を調べる
       ii = ii + 1
   Loop
   
   Do While File <> ""   '対象フォルダ内のファイルが無くなるまで繰り返す
       Workbooks.Open Path & "\格納フォルダ\" & File 'Pathから対象ファイルを開く
       Set Wsthat = Workbooks(File).Worksheets("データ")
       Lrow = Lastrow
       Wsthis.Cells(ii, 1).Value = Wsthat.Cells(Lastrow, 1).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 2).Value = Wsthat.Cells(Lastrow, 2).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 3).Value = Wsthat.Cells(Lastrow, 3).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 4).Value = Wsthat.Cells(Lastrow, 4).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 5).Value = Wsthat.Cells(Lastrow, 5).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 6).Value = Wsthat.Cells(Lastrow, 6).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 7).Value = Wsthat.Cells(Lastrow, 7).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 8).Value = Wsthat.Cells(Lastrow, 8).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 9).Value = Wsthat.Cells(Lastrow, 9).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 10).Value = Wsthat.Cells(Lastrow, 10).Value  '貼り付け対象セル=コピー対象セル
       Wsthis.Cells(ii, 11).Value = File 'ファイル名を記載
       Wsthis.Cells(ii, 12).Value = Now() '日時を記載

       Application.DisplayAlerts = False
       Workbooks(File).Close 'コピーし終わったファイルは閉じる
       Application.DisplayAlerts = False
  
       File = Dir()
       ii = ii + 1 'データ貼り付け行が重複しないよう一つ下の行を参照するために1を加算
   Loop

       
End Sub
Sub Classモジュールにて転記_A社用()
   Dim ten As tenki: Set ten = New tenki
   Set ten.Ws_this = ThisWorkbook.Worksheets("集計A社用")             '【Classへ渡す】転記するシート名
   ten.strPath = ThisWorkbook.Path                                 '【Classへ渡す】このExcelファイルのPath
   ten.i = 2: ten.strFile = Dir(ten.strPath & "\格納フォルダ\" & "*") '【Classへ渡す】開く対象ExcelファイルのPathとファイル名
   Call ten.TenkiKaishi 'Classモジュールへ作業命令
   Set ten = Nothing
End Sub


ここがポイント

コード自体は、難しくないと思います。
しかし、Letだの、Getだの、クラスモジュール特有の表現がありますね。
これは、コードを見て、自分で書いて覚えるものです。
このコードを見て、Excelへ転記して、わからないことは、ネットで検索してください。
きっと、違うクラスモジュールの世界が見えると思います。

まとめ

クラスモジュールのコードを提供してくださったご視聴者様に、改めて、感謝申し上げます。
本当にありがとうございました。
このコードを何度も写経して、勉強したいと思います。
サンプルファイルを購入していただいている方には、コード提供者様の解説もファイルに記載しているので参考にしてください。
今回も最後まで読んでいただきありがとうございました。



よろしければサポートをお願いします。いただいたお金に関しては、書籍の購入に充て、より良い情報を皆様に提供します。