出産前後の痔にはご注意!

エクセル、アクセスでvbaを利用しています。
現在はすべて標準モジュールに記載しているのですが
「クラスモジュールを使わないとできないこと」もあるのでしょうか?
クラスモジュールの使い方、必要性がいまいちわかりません。
まだ初心者な為複雑なコードは作っていません。
よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (5件)

こんにちは。



私は以前勉強がてらクラスモジュールを使ってドラクエのような
ゲーム(戦闘シーンのみ)を作りました。
これで他の方の回答にもあったインスタンスというのが
分かった気がしました。

クラスモジュールを使う私なりの解釈では
Excelに存在しない何かをExcelで使いたいときにクラスモジュールを
使います。
たとえば、Excelのオブジェクトに「車」というオブジェクトは
存在しません。
ExcelのプログラムでExcel上に車を存在させるには
車オブジェクトが必要になるので
それをクラスモジュールで定義します。
ここで車種や色、大きさといったプロパティを定義します。
そして進む、止まる、バックするといったメソッドを定義します。

これでオブジェクトができるので後は標準モジュールなどから
このオブジェクトを使います。
その時、オブジェクトをそのまま使うのではなく
オブジェクトのコピーのようなもの(インスタンス)を使います。
、、、と話は長くなるのですが、私はこんな形で解釈しています。
    • good
    • 1
この回答へのお礼

私も勉強がてらゲームを作ってみたいと思います。
大変参考になりました。ありがとうございます。

お礼日時:2009/07/16 20:35

最近、クラスモジュールを使った回答を2件しています。


http://okwave.jp/qa5087647.html
のNo.3ですが、一秒間に一度起こるイベントを定義しています。これは、クラスモジュールを使わないとできないと思います。

http://okwave.jp/qa5070895.html
のNo.3ですが、これはクラスモジュールを使うことで、データの管理が楽になっている事例です。この質問者は、関数に10個のデータを渡す時、シート間にまたがるデータ、列間にまたがるデータを渡すアルゴリズムに苦労されたのだと思いますが、クラスモジュールを使うと、データをオブジェクトが保持していますので、ところてん式にデータを1個ずつ渡していくだけで、単純移動平均の計算ができています。まあ、こんな簡単な事例ですのでモジュールレベルの配列にデータを入れて、普通の手続き型?プログラミングでも出来ると思いますが。
    • good
    • 1
この回答へのお礼

ありがとうございます。
よく読んでみます!

お礼日時:2009/07/09 22:34

こんにちは。



初心者に教えるようなことはないとは思いますが、簡単に言えば、クラスモジュールは、プログラムの設計図のようなものです。それを実行して、それで、インスタンスが作られるわけです。ある人は、鯛焼きの型と鯛焼きの関係だと言いましたが、私は、設計図と実体(化)(英語からの発想)だと考えています。

ユーザー定義関数などは、個別のブックで使うなら、あえてクラスで作る必要はありません。コントロール配列も、コントロール・ツールをクラスで設定するのは、好みに近いと思います。

Excel VBAでは、ひとつだけないものは、Application イベントです。でも、物知りで皮肉な人は、ThisWorkbook モジュールでも作れるのではないか、というかもしれませんが、クラス側のほうが楽だと思います。その点、Word VBAになると、標準モジュールでエラーが発生したりするので、Class を使わざるを得ない場面が出てきます。
    • good
    • 0
この回答へのお礼

Wordならクラスモジュールを使う機会が多いのですね。
参考になりました。

お礼日時:2009/07/08 21:50

コントロール配列を使うような場面では、以下が参考になると思います。



http://www.h3.dion.ne.jp/~sakatsu/Breakthrough_P …
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2009/07/08 20:48
    • good
    • 0
この回答へのお礼

もろクラスモジュールのことが書かれていますね!
よく読んでみます!

お礼日時:2009/07/08 20:46

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QEXCELファイルのカレントフォルダを取得するには?

EXCELファイルのカレントフォルダを取得するには?

C:\経理\予算.xls

D:\2005年度\予算.xls

EXCEL97ファイルがあります。

VBAで
  カレントフォルダ名
(C:\経理\,D:\2005年度\)
を取得する事は可能でしょうか?

CURDIRでは上手い方法が見つかりませんでした。

Aベストアンサー

こんばんは。
Excel97 でも、同じですね。以下で試してみてください。

Sub test()
'このブックのパス
a = ThisWorkbook.Path
'アクティブブックのパス
b = ActiveWorkbook.Path
'Excelで設定されたデフォルトパス
c = Application.DefaultFilePath
'カレントディレクトリ
d = CurDir
MsgBox "このブックのパス   : " & a & Chr(13) & _
   "アクティブブックのパス: " & b & Chr(13) & _
   "デフォルトパス    : " & c & Chr(13) & _
   "カレントディレクトリ : " & d & Chr(13)
End Sub

QSub ***( ) と Private Sub ***( ) の違い

初歩的な質問で申し訳ありませんが・・・

自分でコードを書いていても、イベントが発生したりした時の処理で、コードのウィンドウで上のドロップダウンリストで選択できる時の処理などは自動的に[Private Sub Command1_Click( )]などと出てくるのでそのまま使っています。自分で別途プロシージャーを作成する時は[Sub ****( )]としています。
ですがその違いを理解しないまま、自分で作成する時は[Private Sub]ではなくて[Sub]を使っています。

Sub ***( ) と Private Sub ***( ) の違いは何なんでしょうか?
どなたか説明頂けませんか?
よろしくお願いします。

Aベストアンサー

「Sub」の部分にカーソルを置いて[F1]を押せばヘルプが起動します。
「指定項目」のところに「Public」と「Private」の説明がありますよ。
省略して「Sub hogehoge()」とした場合は「Public」とみなされます。

Publicは「すべてのモジュールから呼び出せるプロシージャ」ということになります。
Privateとすると「同じモジュールの中からしか呼び出せないプロシージャ」となります。

もしExcelをお持ちでしたらExcelのVBEで標準モジュールを追加し、「Sub Test1()」と「Private Sub Test2()」を作成してみてください。
そしてExcelの[ツール]-[マクロ]-[マクロ(Alt+F8)]でマクロ実行のダイアログを表示させてみるとわかります。
ここには実行できるプロシージャの一覧が表示されますが、Test1は表示されているけれどTest2は表示されません。
Test1はPublicで、Test2はPrivateだからです。

QEXCEL VBAで計算値を四捨五入、切り上げ、切捨てする方法

ネットで探してみたのですが、計算結果を四捨五入して特定のセルを
返すにはどうしたらいいのでしょうか?

Sub hokangosa()

Dim ZPS As Double
Dim ZPOS As Double
Dim DMN As Double
MsgBox (" >>> 補間誤差自動計算 <<< ")
MsgBox (" >>> 初期値入力します <<< ")
ZPS = InputBox(">>> ステップを入力してください<<<")
ZPOS = Sheet1.Cells(22, 4).Value
DMN = ZPOS / ZPS
Sheet1.Cells(23, 6).Value = DMN
End Sub

ここでDMNの値を四捨五入したいです。

またこれとは別に切上げ、切捨ても教えていただけるとありがたいです。

Aベストアンサー

DMN = Application.WorksheetFunction.Round(ZPOS / ZPS, 0)
で、四捨五入
DMN = Application.RoundDown(ZPOS / ZPS, 0)
で切り捨て
DMN = Application.RoundUp(ZPOS / ZPS, 0)
で切り上げです。

引数で、対象桁を変更できます。

Q標準モジュールとクラスモジュールの違い

マイクロソフトのAccess2000でVBAプログラミングを行なっておりますが、
基本的なことを教えてください。

「標準モジュール」と「クラスモジュール」の違いはなんですか?
例えば、どこからでも使えるプロシージャ

Public Function getSum( i1 as integer, i2 as interger )

getSum = i1 + i2

End Function


を定義したとして、標準モジュール内に書くのとクラスモジュール内に
書くのとでは、何が違ってきますか?その他とにかく「標準モジュール」
とクラスモジュールの違いを教えてください。

Aベストアンサー

Public Function getSum( i1 as integer, i2 as interger )
getSum = i1 + i2
End Function

のような関数なら、標準モジュールに書いた方がいい(使い勝手がいい)です。
クラスモジュールに書くと、
Set c1 = New ClassName1
c1.getSum(1, 2)
のように、オブジェクト ( c1 ) を作ってからメソッド ( getSum() ) を呼び出さなければなりません。
クラス/オブジェクトを使用すると、今までの中央集権的なプログラムが独立分散型のプログラムになります。要は、細かいことはなるべくおのおののオブジェクトにさせるということです。

簡単なクラス/オブジェクトの例ですが、

'-----------------------------------
'CRectangle.cls
'Class:CRectangle ( 長方形 )
'-----------------------------------
Public Width As Integer
Public Height As Integer

Public Function GetArea() As Long
GetArea = CLng(Width) * CLng(Height)
End Function
'-----------------------------------

'-----------------------------------
'フォームなど、どこか適当なところ
'-----------------------------------
Private Sub コマンド1_Click()
  Dim c1 As CRectangle
  Dim c2 As CRectangle

  Set c1 = New CRectangle
  c1.Height = 100
  c1.Width = 200

  Set c2 = New CRectangle
  c2.Height = 150
  c2.Width = 250

  '面積の計算は各オブジェクトがやってくれる。
  Debug.Print c1.GetArea
  Debug.Print c2.GetArea

End Sub

↑これだけでは、あまりクラス/オブジェクトの恩恵が得られていませんが、とりあえず、こんな感じです。

クラスについて、ここで全てを語ることはできませんので、詳しいことは書籍などを参考にされた方がいいと思います。クラス/オブジェクトの根本的なことについては、Visual Basic でも Excel VBA でも Access VBA でも同じだと思いますので、クラスについて取り扱っているなら、Excel VBA の書籍でも構わないと思います。
ただ、VB/VBA のクラスは、C++ や Java のクラスとは全然違うというか、かなりチャチなので、C++ や Java の書籍は、「 VB/VBA のクラスがいかにチャチなのかを知る」にはいいと思いますが、VBA のクラスを勉強するには適さないと思います。最初はやはり VB/VBA 用のものを参考にされた方がよいでしょう。

Public Function getSum( i1 as integer, i2 as interger )
getSum = i1 + i2
End Function

のような関数なら、標準モジュールに書いた方がいい(使い勝手がいい)です。
クラスモジュールに書くと、
Set c1 = New ClassName1
c1.getSum(1, 2)
のように、オブジェクト ( c1 ) を作ってからメソッド ( getSum() ) を呼び出さなければなりません。
クラス/オブジェクトを使用すると、今までの中央集権的なプログラムが独立分散型のプログラムになります。要は、細かいことはなるべくおのおののオブジェ...続きを読む

Qモジュールとクラスの違いってなんなんですか?

モジュールとクラスの違いってなんなんですか?

本などをみてもいまいち分かりません。

Aベストアンサー

端的かつ正確に言うと、クラスはオブジェクトで、標準モジュール(質問内でモジュールと呼んでいるのは標準モジュールのことだと思いますが)はオブジェクトではありません。
(もし、質問内でモジュールと呼んでいるのが、本当にモジュールという意味で言っているのであれば、クラスはクラスモジュールですし、フォームはフォームモジュールです。クラスはモジュールの一種です、という答えです)
使用方法で言うと、クラスはインスタンス作成時、破棄時にそれぞれイベントが発生するため、変数等の初期化や終了処理などをオブジェクト内で自動化できます。
オブジェクト内で自動化されるため、初期化手続き、参照の開放などクラスを使用する際には内部の動作を意識することなく使用することができます。
つまり、再利用性が高いと言いかえることができます。
また、VB5/6ではAddressOf演算子が標準モジュール内の関数以外には使用できないという制限があるが、それを使用しない前提では、標準モジュールで実現できることはクラスで書きかえることができます。
逆に、クラスではできる事でも、標準モジュールではできないことは山のようにあります。
#1さんが書いたように、複数のインスタンスを作成することもそうですが、当方の利用方法では、コレクションに追加できるという点を挙げたいと思います。他には、自己再起定義(造語)です。ClassA内でClassAオブジェクトを作成するような動作です。ClassA内でClassAを定義した場合、中に作成されたClassAの中にさらにClassAが定義可能で、さらにその内部にClassAが、さらにその内部に・・・と、スタックの許す限り無限に定義されます。
ポリモーフィズム、関数の引数や返り値にクラスを渡すなど、いろいろと標準モジュールには不可能な点が多くあります。

端的かつ正確に言うと、クラスはオブジェクトで、標準モジュール(質問内でモジュールと呼んでいるのは標準モジュールのことだと思いますが)はオブジェクトではありません。
(もし、質問内でモジュールと呼んでいるのが、本当にモジュールという意味で言っているのであれば、クラスはクラスモジュールですし、フォームはフォームモジュールです。クラスはモジュールの一種です、という答えです)
使用方法で言うと、クラスはインスタンス作成時、破棄時にそれぞれイベントが発生するため、変数等の初期化や終了処...続きを読む

QVBA オブジェクトが空かどうか判定する

皆様のお知恵を拝借させてください。

エクセルVBAでオブジェクトを入れる変数を定義し、その変数にオブジェクト
が入っているかどうか検査したいのですがどうしたらいいでしょうか。

例えば---
Dim a As Workbook
If a <> nothing then ←この部分が分からない。このままだとエラー。
処理
End if
---------
環境
エクセル2003
WinXPsp1

Aベストアンサー

もし、aが空だったら
If a Is Nothing Then 

もし、aが空じゃなかったら
If Not a Is Nothing Then

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

QVBA モジュールで共通に使う変数の宣言方法

VBAにてプログラミングを覚えている者です。

現在、いくつかのモジュールがあり、それぞれDimにて宣言している共通の変数があります。
いくつものプロシージャに毎回宣言せず、どこかでひとまとめにしたいと思い、色々と調べています。

例えば、

Dim pic1 As Picture
Dim cell1 As String
Dim pass1 As String
Dim pic2 As Picture

などです。


Dimのほかに、Publicの宣言などがありますが、いま一つ使い方がピンときません。

共通宣言する変数をひとつのモジュールとして登録し、活用できると、いざ変更となったときに
その内容だけ置き換えればいいと思うのですが、みなさんはどのように宣言をしていますか?
(例えば、Stringなどは各モジュールで変更するのが大変だと思うのですが・・・)

ヒントを教えていただければと思います。よろしくお願いします。

Aベストアンサー

>モジュールで共通に使う変数の宣言方法

モジュールの先頭に書いたdimで宣言すると,そのモジュールの中だけ(に記入されている各プロシジャ)でパブリックになります。
モジュールの先頭に書いたpublicで宣言すると,全モジュール(に記入されている各プロシジャ)に対してパブリックになります。

「変数宣言モジュール」のようにモジュールを越えて参照させたいという事なので,DimではなくPublicで宣言します。


Module1:
public x as variant


Module2:
sub macro1() ’先に実行する
x = "abc"
end sub


Module3:
sub macro1()
msgbox x
end sub

Qエクセル VBA ユーザーフォームを閉じる

ユーザーフォームを開く時は
UserForm1.Showですが
閉じる時は?
UserForm1.Close
だとコンパイルエラーになります。
End
にするしかないですか?

Aベストアンサー

Unload Me とか Unload UserForm1 でユーザーフォームを閉じることができます。

QVBA コレクションに2次元配列を追加して取り出す方法

2次元配列を作成し、コレクションにAddし、
ループで処理をしたいと考えています。

Addしたものの、取り出す方法がわかりません。
ローカルウインドウで確認すると、値が表示されているので、 test に 2次元配列は追加されているようです。


  Dim test As Collection
Set test = New Collection
Dim tmp(0, 9) As String

tmp(0, 0) = "test"
tmp(0, 1) = "56"


test.Add tmp

tmp(0, 0) = "test2"
tmp(0, 1) = "tttt"

test.Add tmp

この後 test の中の2次元配列の値をループで取り出したいです。
取り出して、セルに代入する予定です。

どうかアドバイスをお願いいたします。

Aベストアンサー

こんな感じですかね。
Sub Sample()
  Dim test As Collection
  Dim tmp(0, 9) As String
  Dim ary As Variant
  Dim i As Integer

  Set test = New Collection

  tmp(0, 0) = "test"
  tmp(0, 1) = "56"
  test.Add tmp

  tmp(0, 0) = "test2"
  tmp(0, 1) = "tttt"
   test.Add tmp

  tmp(0, 0) = "test3"
  tmp(0, 1) = "zzz"
  test.Add tmp

  Debug.Print "データ数 : " & test.Count

  For Each ary In test
    Debug.Print ary(0, 0)
    Debug.Print ary(0, 1)
  Next

  Worksheets.Add Before:=Worksheets(1)

  For i = 1 To test.Count
    Range(Cells(i, 1), Cells(i, 10)) = test(i)
  Next

  Worksheets.Add Before:=Worksheets(1)

  For i = 1 To test.Count
    ary = test(i)
    Range(Cells(1, i * 2), Cells(10, i * 2)) = WorksheetFunction.Transpose(ary)
  Next
End Sub

こんな感じですかね。
Sub Sample()
  Dim test As Collection
  Dim tmp(0, 9) As String
  Dim ary As Variant
  Dim i As Integer

  Set test = New Collection

  tmp(0, 0) = "test"
  tmp(0, 1) = "56"
  test.Add tmp

  tmp(0, 0) = "test2"
  tmp(0, 1) = "tttt"
   test.Add tmp

  tmp(0, 0) = "test3"
  tmp(0, 1) = "zzz"
  test.Add tmp

  Debug.Print "データ数 : " & test.Count

  For Each ary In test
    Debug.Print ary(0, 0)...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング