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

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

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

3回答

19754閲覧

VBA データクラスのようなものを作りたい

Alice0225

総合スコア206

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

2クリップ

投稿2015/11/24 02:18

現在VBAを使用してマクロを作成しています。
そこで、数値の変わらない変数を宣言するだけのクラス(モジュール?)を作成したいのですがうまくいきません。
良い方法などございましたらご教授頂けませんでしょうか。
イメージとしては

VBA

1Sub Data() 2 3 Public A As Integer 4 Public B As String 5 Public C As Integer 6 7 A = 50 8 B = "リンゴ" 9 C = 780 10 11End Sub

のようなクラスを作って各変数を宣言し、

VBA

1Sub Main() 2 3 Call Data 4 5 Msgbox A 6 Msgbox B 7 Msgbox C 8 9End Sub

といった感じでメインクラスで呼び出して使いたいのです。
現在は上記のように実装し実行すると
「Sub、 Function、 またはProperty が必要です。」
とコンパイルエラーが表示され、思ったとおりの動作になりません。
初心者故に考え方自体が間違っているような気がしないでもないのですが、
どうにか実現する方法はございませんでしょうか。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

VBAエディタで挿入→クラスモジュールでクラスを追加できます。
クラスでは以下のようにメンバを定義します。

VBA

1Public a As String 2 3Private Sub Class_Initialize() 4 5 a = "リンゴ" 6 7End Sub

Class_Initializeがコンストラクタなので、こちらで変数の初期化を行います。
(VBAでは変数の宣言と同時に初期化ができないので)

モジュールでは以下のように記述してクラスのインスタンス化およびメンバの呼び出しを行います。

VBA

1Public Sub test() 2 3 Dim class As Class1 4 5 Set class = New Class1 6 MsgBox class.a 7 8End Sub

なお、クラスだけは以下のように宣言とインスタンス化を同時に行うこともできます。

VBA

1Dim class As New Class1

また、扱う値に数値が多いのであれば列挙型を利用するのも一つの手です。

VBA

1Enum EnumName 2 Member1 = 10 3 Member2 = 20 4End Enum 5 6Public Sub test() 7 Msgbox EnumName.Member1 8 Msgbox EnumName.Member2 9End Sub

投稿2015/11/24 03:42

編集2015/11/24 04:02
lilithchan

総合スコア249

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Alice0225

2015/11/24 04:27

わかりやすいご解説ありがとうございます。 期待する動作が実現できました!
hatena19

2015/11/24 05:40

Public で宣言してしまっては、外部から自由にアクセスできてしまいますので、クラスにする意味がないような。 > 数値の変わらない変数を宣言するだけのクラス(モジュール?)を作成したい とのことなので、ここは、Property Get のみ宣言して、読み取り専用にすべきと思います。 Public Property Get a() As String a = "りんご" End Property 書き込み専用なら、Property Let のみ。 読み書きできるようにするなら、Property Get と Property Let と両方宣言する、というように使い分けることができるのがクラスのメリットの一つです。
lilithchan

2015/11/24 07:14

きっちり書くのであればhatena19さんのおっしゃる書き方がベストです。 が、VBAでのクラスはオブジェクト指向に必要な機能がかなり削られており、他の言語のクラスと同様に扱う必要は個人的にはないと思っています。 特に今回のように単なる値の列挙であれば、メンバ変数に外部から値を書き込まないというルールさえ設けていればpublicで宣言しても別に問題はないと思います。 ここまで書いた上であれですが、個人的には数値はEnumで宣言、他はマスタシートを設けるかConstで素直に宣言するのがベストだと思います。
guest

0

VBAではクラスを作れないと思います。

定数を定義するならモジュール内で
Public Const A As Integer = 50
Public Const B As String = "リンゴ"
Public Const C As Integer = "780"
と記述すればよいかと思います。

ユーザー定義型というものを使えばクラスのような使い方もできるかと。
http://officetanaka.net/excel/vba/variable/12.htm

投稿2015/11/24 02:42

tomo.ina

総合スコア357

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Alice0225

2015/11/24 03:25

定義すべき定数の数が結構多くなりそうな為、それだけを記述したものを切り離して作りたかったのですが無理なのですね。。。
tomo.ina

2015/11/24 04:01

そうでしたら、定数記述用の標準モジュールを作成すればよいですよ。
tomo.ina

2015/11/24 04:05

すいません。VBAでもクラスは作れるみたいですね。 勉強不足でしたm(_ _)m
Alice0225

2015/11/24 04:29

いえいえ、ご回答いただけただけでも嬉しいです。 貴重なお時間を割いて頂きありがとうございました!
guest

0

VBAでもクラスは作成できます。

質問の例が、クラスのサンプルとして適切かどうかは別にして、そのままクラスにすると下記のようになります。

VBAウィンドウで、[挿入]-[クラスモジュール]をクリックします。
下記のコードを記述します。

vba

1Option Explicit 2 3Public Property Get A() As Integer 4 A = 50 5End Property 6 7Public Property Get B() As String 8 B = "りんご" 9End Property 10 11Public Property Get C() As Integer 12 C = 780 13End Property

コンパイル後、名前を clsData として保存します。
標準モジュールに下記のコードを記述します。

vba

1Public Sub clsDataTest() 2 Dim Data As New clsData 3 4 MsgBox Data.A 5 MsgBox Data.B 6 MsgBox Data.C 7 8End Sub

クラスでは値はプロパティで取得するといのが原則です。

プロパティが読み取り専用では、あまり使いみちがないので、もう少し有用なサンプルを。
上記の clsData のコードを下記に修正します。

vba

1Option Compare Database 2Option Explicit 3 4 Private pA As Integer 5 Private pB As String 6 Private pC As Integer 7 8Public Property Get A() As Integer 9 A = pA 10End Property 11 12Public Property Let A(ByVal vA As Variant) 13 pA = vA 14End Property 15 16Public Property Get B() As String 17 B = pB 18End Property 19 20Public Property Let B(ByVal vNewValue As Variant) 21 pB = vB 22End Property 23 24Public Property Get C() As Integer 25 C = pC 26End Property 27 28Public Property Let C(ByVal vNewValue As Variant) 29 pC = vC 30End Property

これで、プロパティの設定ができるようになります。

使用例としては、

標準モジュール

vba

1Public Sub clsDataTest() 2 Dim Data(1 To 3) As clsData 3 Dim i As Long, kei As Long 4 5 6 Set Data(1) = New clsData 7 With Data(1) 8 .A = 50 9 .B = "りんご" 10 .C = 780 11 End With 12 13 Set Data(2) = New clsData 14 With Data(2) 15 .A = 51 16 .B = "みかん" 17 .C = 600 18 End With 19 20 Set Data(3) = New clsData 21 With Data(3) 22 .A = 52 23 .B = "バナナ" 24 .C = 500 25 End With 26 27 For i = 1 To 3 28 kei = kei + Data(i).C 29 Next 30 31 MsgBox "合計は" & kei 32End Sub

このようにクラスモジュールは New で複数のインスタンスを生成できます。

ここまでなら、ユーザー定義型でもできますが、クラスだとさらにメソッドを持たせたり、いろいろ拡張性があります。

投稿2015/11/24 03:54

hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Alice0225

2015/11/24 04:28

そのような方法もあるのですね…勉強になります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問