Quantcast
Channel: いつも隣にITのお仕事
Viewing all articles
Browse latest Browse all 2094

宣言もセットも不要!エクセルVBAでワークシートをオブジェクト名で取り扱う方法

$
0
0
name

photo credit: jacobchristensen Table card via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

エクセルVBAで請求データ一覧から請求書を自動で作成する方法をシリーズでお伝えしています。

前回はこちらの記事でした。

エクセルVBAでDateAdd関数を使って年月を条件としてSumIfs関数を使う方法
エクセルVBAで請求データ一覧から請求書を自動で作成するシリーズです。Excel関数でおなじみのSumIfs関数を使って年月の判定をします。DateAdd関数という日付に追加する便利な関数も紹介しますよ。

これで請求書を作るVBAプログラムとしては、まあまあ形になってきたと思いますが、ちょっとコードが長くなってきましたよね。

今回から何回かはちょっと趣向を変えて、今の機能はそのままで書き方をスッキリするテクニックをいくつかお伝えします。

まず注目したいのは、ワークシートです。

実は、ワークシートを取り扱う方法として、これまでは「Worksheet型」のオブジェクト変数を使ってきたのですが、別の方法として「オブジェクト名」で指定する方法というのがあります。

オブジェクト名による方法でワークシートを取り扱うと

  • 変数の宣言やセットが不要
  • プロシージャやモジュールをまたいでオブジェクト名で指定できる

というメリットがあり、結果としてスッキリ書くことができます。

ということで、今回はエクセルVBAでワークシートをオブジェクト名で取り扱う方法です。

では、いってみましょう!

ワークシートをオブジェクト変数で取り扱う方法

エクセルVBAでワークシートを取り扱う場合、これまでお伝えしてきた方法はこのようなものでした。

Sub シートの取得()

Dim wsData As Worksheet
Set wsData = ThisWorkbook.Worksheets("請求データ")

Debug.Print wsData.Name

End Sub

  1. DimでWorksheet型のオブジェクト変数を宣言
  2. Setでオブジェクト変数にWorksheetオブジェクトをセット

という流れですね。以下記事でも詳しくお伝えしている通りです。

【初心者向けエクセルVBA】データ一覧から請求書を自動で作る
初心者向けVBAの実用的な使い方について、請求データ一覧から請求書を自動で作成するを目標に進めます。初回はシートを取り扱うためのWorksheetオブジェクトの準備とセルの値の操作についてお伝えします。

複数のプロシージャで同じワークシートを取り合う使う方法

複数プロシージャで同じワークシートを取り扱いたいとき、どのようにすれば良いでしょうか?

オブジェクト変数へのセットをする方法をベースとするのであれば、いくつかの選択肢があります。

各プロシージャでワークシートをセットする

まず、最もスタンダードな方法ですが、各プロシージャでワークシートオブジェクトをセットする方法です。

例えば、このような形です。

Sub シートの取得()

Dim wsData As Worksheet
Set wsData = ThisWorkbook.Worksheets("請求データ")

Debug.Print wsData.Name

Call シートのセルの値を出力

End Sub

Sub シートのセルの値を出力()

Dim wsData As Worksheet
Set wsData = ThisWorkbook.Worksheets("請求データ")

Debug.Print wsData.Range("A1").Value

End Sub

単純ではありますが、何度も同じことを書くのは無駄がある気がします。

また、シート名が変更になったときなどは、二か所とも変更しないといけないので面倒ですよね。

Public変数にワークシートをセットする

次にワークシートを格納するオブジェクト変数をPublic変数とする方法です。

例えば、このようなプログラムです。

Option Explicit
Public wsData As Worksheet

Sub シートの取得()

Set wsData = ThisWorkbook.Worksheets("請求データ")

Debug.Print wsData.Name

Call シートのセルの値を出力

End Sub

Sub シートのセルの値を出力()

Debug.Print wsData.Range("A1").Value

End Sub

Public変数は、どのモジュールまたはプロシージャからでも、同一のものとして使用することができます。

こうすると、最初にセットしてしまったものは、他のモジュールまたはプロシージャに処理が移っても、連続して操作することができるんですね。

以下記事でも説明をしている通りです。

【初心者向けエクセルVBA】Public変数の宣言とSubプロシージャの呼び出し
請求データ一覧から請求書を自動で作成するシリーズも第6回目となりました。Public変数の宣言、別のSubプロシージャの呼び出しなどによりプログラムをスッキリしつつ、うっかり発見した不具合を直していきます。

しかしこの方法にもデメリットがあります。

上記のような単純なプロジェクトなら良いのですが、たくさんのコード、たくさんのプロシージャから成るような複雑なプロジェクトになると、そのPublic変数がどんな状態なのかを追いかけるのが大変になってきちゃうのです。

ワークシートを引数として渡す

さて、別の方法としてワークシートを引数として渡すという方法があります。

例えばこのような形です。

Sub シートの取得()

Dim wsData As Worksheet
Set wsData = ThisWorkbook.Worksheets("請求データ")

Debug.Print wsData.Name

Call シートのセルの値を出力(wsData)

End Sub

Sub シートのセルの値を出力(ByVal ws As Worksheet)

Debug.Print ws.Range("A1").Value

End Sub

プロシージャを呼び出すときに、wsDataを引数として渡します。そして受け取るときに、そのオブジェクトをwsというオブジェクト変数で受け取っているということですね。

ワークシートを渡してのプロシージャ呼び出しが一回なら良さそうです。

ただ、あちこちのプロシージャを呼び出すと考えると、毎回のようにワークシートを引数に入れるのは、スッキリしないですよね。

ワークシートのオブジェクト名とは

そこで登場する別の方法が「オブジェクト名」です。

オブジェクト名はワークシートに定められている定数のようなもので、どのモジュールまたはプロシージャからでもその名称でワークシートにアクセスすることができます。

オブジェクト名を確認する方法

では、試しに「請求データ」シートのオブジェクト名を確認してみましょう。

まず、プロジェクトエクスプローラーで「Sheet1(請求データ)」を選択した状態で、VBEメニューから「表示」→「プロパティウィンドウ」を選択します。または F4 キーでもOKです。

VBEでプロパティウィンドウを開く

すると、「請求データ」シートのプロパティウィンドウが開きます。

ウィンドウ内には「(オブジェクト名)」という項目があり、これがまさにオブジェクト名です。

この例では「Sheet1」と設定されていますね。

VBEでワークシートのオブジェクト名を確認

実は、プロパティウィンドウを開かなくても、オブジェクト名を確認できます。

というのも、プロジェクトエクスプローラーに「Sheet1(請求データ)」と記載されていますね。

まさに、ここでの表示が

オブジェクト名(シート名)

となっているので、こちらで確認するほうが簡単です。

のあ、オブジェクト名は、シート名つまりWorksheetオブジェクトのNameプロパティとは全く別モノですので注意して下さいね。

オブジェクト名を使ったプログラム

では、実際にオブジェクト名を使って操作をしてみましょう。

冒頭で紹介したプログラムと同様のことを、オブジェクト名による取り扱いとすると、こんなプログラムになります。

Sub シートの取得()

Debug.Print Sheet1.Name

Call シートのセルの値を出力

End Sub

Sub シートのセルの値を出力()

Debug.Print Sheet1.Range("A1").Value

End Sub

…たったこれだけです…!

オブジェクト名は、それこそオブジェクト変数と同じような使い方となります。

そして変数ではないので、宣言もセットも不要なのです。

これは便利ですよね!

オブジェクト名を変更する

さて、オブジェクト名ですがデフォルトでは「Sheet1」とか「Sheet2」といった無味乾燥な名称となっていますが、任意の名称に変更をすることができます。

オブジェクト名を変更するのは簡単で、プロパティウィンドウで「オブジェクト名」の欄にカーソルを当てて編集をするだけです。

VBEでオブジェクト名を編集

これで変数を用いるときと同様に、意味のあるオブジェクト名でシートを取り扱うことができますね。

オブジェクト名を使用した請求書作成プログラム

では、シリーズでお伝えしてきた請求書作成プログラムを、オブジェクト名を使用して書き換えてみましょう。

Option Explicit
Sub 請求書作成()

Dim i As Long, j As Long, k As Long, n As Long 'For~Nextカウント用整数型変数
Dim dayData As Date '納品日格納用変数
Dim dayCutoff As Date '締月入力用変数
Dim strClient As String '取引先格納用変数
Dim strFile As String 'コピー先パス&ファイル名

Dim rowsData As Long '「請求データ」の行数
Dim rowsClient As Long '「取引先マスタ」の行数
rowsData = wsData.Cells(Rows.Count, 2).End(xlUp).Row '「請求データ」の最後の行数を取得
rowsClient = wsClient.Cells(Rows.Count, 1).End(xlUp).Row  '「取引先マスタ」の最後の行数を取得

Dim wsInvoice As Worksheet 'ひな形は別ファイルなのでオブジェクト変数を使う

dayCutoff = InputBox("締月を入力してください(例:2015/5)")

For n = 2 To rowsClient
    With wsData
        If WorksheetFunction.SumIfs( _
            .Range("F:F"), _
            .Range("A:A"), ">=" & dayCutoff, _
            .Range("A:A"), "<" & DateAdd("m", 1, dayCutoff), _
            .Range("B:B"), wsClient.Cells(n, 1).Value _
            ) > 0 Then
            strFile = ThisWorkbook.Path & "\" & Format(dayCutoff, "yyyymm") & "_" & wsClient.Cells(n, 1).Value & ".xlsx" 'コピー先ファイル名
            FileCopy ThisWorkbook.Path & "\請求書ひな形.xlsx", strFile  'ファイルをコピー

            Workbooks.Open strFile  'コピーにて作成したファイルを開く
            Set wsInvoice = ActiveSheet  '開いたファイルのワークシートをセット

            k = 21 '請求書ひな形シート用カウント変数、スタートは21行目

            For i = 2 To rowsData 'iは請求データ用のカウント変数、最終値の設定にrowsDataを使う

                strClient = .Cells(i, 2).Value '現在の行のクライアント名を取得
                dayData = .Cells(i, 1).Value '現在の行の納品日を取得

                If strClient = wsClient.Cells(n, 1).Value Then
                    If Year(dayData) = Year(dayCutoff) And Month(dayData) = Month(dayCutoff) Then '年が2015でかつ月が5の場合は処理を実行

                        For j = 1 To 3
                            '請求データの2+i行目を請求書ひな形の21+i行目に転記
                            wsInvoice.Cells(k, j).Value = .Cells(i, j + 2).Value
                        Next j

                        k = k + 1

                    End If
                End If
            Next i

            wsInvoice.Rows(k & ":50").Hidden = True 'データがない行を隠す
            wsInvoice.Calculate '「請求書ひな形」シートを再計算する
            wsInvoice.Range("A18").Value = "ご請求金額:" & Format(wsInvoice.Range("D54").Value, "#,##0") & " 円"
            wsInvoice.Range("D15").Value = DateSerial(Year(dayCutoff), Month(dayCutoff) + 1, 0) '請求日
            wsInvoice.Range("D16").Value = DateSerial(Year(dayCutoff), Month(dayCutoff) + 2, 0) 'お支払期限
        End If
    End With
Next n
End Sub

オブジェクト名を使用することで

  • ワークシート用のオブジェクト変数をPublicで宣言
  • ワークシートオブジェクトのセット
  • シートの初期化をするSubプロシージャ

を削除して書いてみました。このほうが、全体としてスッキリ書けているかと思います。

まとめ

以上、エクセルVBAでワークシートをオブジェクト名で取り扱う方法についてお伝えしました。

シートをオブジェクト名で取り扱うことで

  • シートをプロジェクト全体で定数のように一意で指定できる
  • 宣言やセットなどのステートメントを省ける

といったメリットがあります。

ワークシートを使用する際は、ぜひこの選択肢も利用できるようにしておいてくださいね。

連載目次:データ一覧から請求書を自動で作る

お仕事において特定のデータ一覧から必要な情報を抽出するということは頻繁にありうると思います。ここではデータ一覧から請求書を作るということを目標に、実務で使えるスキルをまっすぐに身に着けることを目的としています。
  1. 【初心者向けエクセルVBA】データ一覧から請求書を自動で作る
  2. 【初心者向けエクセルVBA】For~Next文で簡潔にプログラムを書く
  3. 【初心者向けエクセルVBA】行の数をカウントする&不要な行を隠す
  4. 【初心者向けエクセルVBA】文字列の連結&Format関数での書式変更
  5. 【初心者向けエクセルVBA】If~Thenを使った条件分岐の超入門
  6. 【初心者向けエクセルVBA】Public変数の宣言とSubプロシージャの呼び出し
  7. 【初心者向けエクセルVBA】InputBoxでの日付入力と月末日の自動算出
  8. 【初心者向けエクセルVBA】Worksheetのコピーを活用して複数の請求書を作る
  9. 【初心者向けエクセルVBA】ファイルのコピーを使って取引先別の請求書を作る
  10. エクセルVBAでDateAdd関数を使って年月を条件としてSumIfs関数を使う方法
  11. 宣言もセットも不要!エクセルVBAでワークシートをオブジェクト名で取り扱う方法

Viewing all articles
Browse latest Browse all 2094

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>