質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.12%

vbaでのオブジェクト指向について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 2,362

K.T_build

score 26

エクセルのvbaで1つのCSVデータを基に、「営業所別」「営業別」、「得意先別」,etc
の帳票を出力する処理を組もうかと考えています。
この案件にあたり、今までのmoduleのみの手続き型での実装から、オブジェクト指向での
プログラムをやってみようと思い立ちました。

いくつかサイトを参考にして作ろうとしているのですが、クラスの生成から
つまずいてしまっています。
クラスにworksheetオブジェクトを持たせたいのですが、下記のエラーが出ます。
「コンパイルエラー:
オブジェクトモジュールにはインターフェース'WS'用の'absClass'が必要です」

string型などでは上手くいったので、オブジェクトを持たせる場合に何か方法があるのかと思いますが、ググっても上手く出てきませんでした。
最悪、シート名だけ持たせてmodule側で処理してもいいのですが、他に便利な方法があれば試してみたいです。

'スーパークラス:absClass.cls

Option Explicit

'プロパティ
Public WS As Worksheet

Public Sub msgName(vdata As Worksheet)
End Sub
'サブクラス:centerToMonth.cls

Option Explicit
'---コンパイルエラー:
'---オブジェクトモジュールにはインターフェース'WS'用の'absClass'が必要です。
Implements absClass

'プロパティ
Private WS As Worksheet

Private Property Get absClass_WS() As WorkSheet
    absClass_WS = WS
End Property
Private Property Let absClass_WS(ByVal RHS As WorkSheet)
    WS = RHS
End Property

Private Sub absClass_msgName(vdata As Worksheet)
    Debug.Print vdata.name
End Sub
'module.bas

Sub test()
    Dim objabs As absClass
    Dim objcon As centerToMonth

    Set objcon = New centerToMonth
    Set objabs = objcon

    With objabs
        MsgBox .WS

        'MsgBox ActiveWorkbook.Worksheets("営業所別売上修正一覧表(月間)").name
        .WS = ActiveWorkbook.Worksheets("営業所別売上修正一覧表(月間)")
        .msgName
    End With
End Sub

参考:https://sites.google.com/site/compositiosystemae/home/vbaworld/upper/interface

以上、ご教授いただければと思います。
よろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

VBA でのスーパークラスには、必要なプロパティ、メソッドすべてのインターフェイスが必要になるとのことです。
参考 

これをもとに、提示されたクラス、モジュールを以下のように変更してみました。

(1) absClass

'スーパークラス:absClass.cls

Option Explicit

'プロパティ
'Public WS As Worksheet

'' プロパティのインターフェイスを用意する。
Public Property Get WS() As Worksheet
End Property

'' オブジェクトの場合は、Let ではなく Set
Public Property Set WS(ByVal RHS As Worksheet)
End Property

Public Sub msgName(vdata As Worksheet)
End Sub

(2) centerToMonth

'サブクラス:centerToMonth.cls

Option Explicit
'---コンパイルエラー:
'---オブジェクトモジュールにはインターフェース'WS'用の'absClass'が必要です。
'' -> WS オブジェクトの「プロパティ」のインターフェイスがないので、出てきて当然のエラーです。

Implements absClass

'' クラス内で保有数 WS の宣言。
'プロパティ
Private WS As Worksheet

'' プロパティの実装
'' それぞれ、オブジェクトなので set する。
Public Property Get absClass_WS() As Worksheet
    Set absClass_WS = WS
End Property
Public Property Set absClass_WS(ByVal RHS As Worksheet)
    Set WS = RHS
End Property

Public Sub absClass_msgName(vdata As Worksheet)
    Debug.Print vdata.Name
End Sub

(3) Module1

Option Explicit

'module.bas

Sub test()

    ' スーパークラスで宣言したあと、派生クラスで New する。
    Dim objabs As absClass
    'Dim objcon As centerToMonth
    Set objabs = New centerToMonth
    'Set objabs = objcon

    With objabs
        'MsgBox .WS
        'MsgBox ActiveWorkbook.Worksheets("営業所別売上修正一覧表(月間)").name
        Set .WS = ActiveWorkbook.Worksheets("営業所別売上修正一覧表(月間)")
        .msgName .WS

    End With
End Sub

Excel 2013 では動作しました。
以上、ご参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/16 17:36

    ありがとうございます。
    頂いたプログラムで動作できました。
    オブジェクトをクラスに実装する場合は、スーパークラスにインターフェースを宣言する必要があるのですね。
    勉強になりました。

    キャンセル

0

'プロパティ
Private WS As Worksheet

Private Property Get absClass_WS() As String
    absClass_WS = WS
End Property
Private Property Let absClass_WS(ByVal RHS As String)
    WS = RHS
End Property

「Get absClass_WS() As String」→「Get absClass_WS() As Worksheet」
「ByVal RHS As String」→「ByVal RHS As Worksheet」
ではないでしょうか?

■追記
StringをWorksheetに変更
LetをSetに変更

absClass

Option Explicit

'プロパティ
Public WS As Worksheet

Public Sub msgName(vdata As Worksheet)
End Sub


centerToMonth

Option Explicit
'---コンパイルエラー:
'---オブジェクトモジュールにはインターフェース'WS'用の'absClass'が必要です。
Implements absClass

'プロパティ
Private WS As Worksheet

Private Property Get absClass_WS() As Worksheet
    absClass_WS = WS
End Property
Private Property Set absClass_WS(ByVal RHS As Worksheet)
    WS = RHS
End Property

Private Sub absClass_msgName(vdata As Worksheet)
    Debug.Print vdata.Name
End Sub


Modules1

Sub test()
    Dim objabs As absClass
    Dim objcon As centerToMonth

    Set objcon = New centerToMonth
    Set objabs = objcon

    ''' このあたりはエラーになるのでコメントアウト
    With objabs
        'MsgBox .WS 

        'MsgBox ActiveWorkbook.Worksheets("営業所別売上修正一覧表(月間)").name
        '.WS = ActiveWorkbook.Worksheets("営業所別売上修正一覧表(月間)")
        '.msgName .WS
    End With
End Sub

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/16 17:06

    Setで試してみましたが、こちらでも同様にエラーが発生しました。
    試しにスーパークラス(absClass)からプロパティを抜いたら動作するようになりました。
    原因は不明ですが、、、

    キャンセル

  • 2017/08/16 17:08

    試した操作説明があいまいすぎる回答だったので、再度回答します。
    正)試しにabsClassから「Public WS As Worksheet」 をコメントアウトしたところ、正常に動作しました。

    キャンセル

  • 2017/08/16 17:14

    当方では特にエラーなく動作しました。Excelのバージョンは2010です。
    一応、動いたソースを追記します。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる