だるまのエクセルVBA掲示板

申し訳ございません。HPの引越しに伴い、掲示板はやめました。
過去の書き込みの表示のみできるようにしてありますが、新規の投稿は出来ません。
なお、各ページへのリンクは引越し後のHPのアドレスに変更してあります。

■

更新がストップ

 だるま

URL

データNo:186

2010年04月11日(Sun) 12:31

 

だるまです。

とある事情により、更新がストップします。
すいません。

え?そもそも、最近更新なんてしてないって?
そんなことないです。
http://darumaexcel.uijin.com/en/history.html
を見てください。


■

インタフェースの使い方

 o8qqqq

E-mailURL

データNo:180

2010年03月24日(Wed) 05:23

 

オブジェクト指向プログラミングに関して、VBAで出来ないこと->2.インタフェースのみの継承に問題がある

上記の記述に関して、インターフェースの使い方がおかしい気がしたので・・・

以下の記述があります。

1>以下のようにする必要があります。
2>  Dim Obj1 As new Class1
3>  Dim Obj2 As Class2
4>  Set Obj2 = Obj1
5>  Call Obj2.aaa
6>
7>■感想:
8>面倒くさい・・・。
9>(行数が長くなりソースが読みにくくなります。)

本来の記述方法であれば、以下のようになるのでは?

Dim Obj2 As Class2
Set Obj2 = new Class1
call obj2.aaa

問題点
1.必要のない変数「obj1」を宣言している。
2.使用するかどうかもわからん「Class1」のインスタンスを、宣言時に生成している。

あと、感想として「9>(行数が長くなりソースが読みにくくなります。)」とありますが、
逆のような気がするのですが?

以下、「Class2」がインターフェース
「Class1」、「Class3」、「Class4」、「Class5」が実装クラスとしての話

Dim Obj2 As Class2

select case InsSelect
case 1
Set Obj2 = new Class1
case 3
set obj2 = new Class3
case 4
set obj2 = new Class4
case 5
set obj2 = new Class5
case else
' Err.Raise
end select

call obj2.aaa

上記は、InsSelect変数ごとに、生成するインスタンスを変更し、「aaa」処理を実行する想定のコードです。

行数が長くなるとはとても思えないのですが?
逆に、行数を圧縮?していると思っているのですが、いかがでしょうか?

■

Re:インタフェースの使い方

だるま

データNo:181

2010年03月24日(Wed) 23:21

 

http://darumaexcel.uijin.com/aboutooa/vba_limit.html#implements
の説明が悪すぎるのかも。

call obj2.aaa
ができるのはいいのです。
(Class2のオブジェクト変数.aaa はできる)

Class1のオブジェクトをClass2としてしか使用しない場合はClass2型の変数を使ってプログラムできるのでいいのですが、場合によってはClass1のオブジェクトとして使用したい(Class1で定義したメソッドを使用したい)場合があります。その場合は当然Class1型の変数を使ってプログラムすると思いますが、そうするとClass2で定義したメソッドは呼び出せませんという話です。(どうしても呼びたかったらClass2型の変数に代入してから行う必要がありますが面倒だという話です。)

面倒と言う話ですが、個人的には余計な変数を定義するのが嫌です。なぜかというと、C/C++,Javaだと変数のスコープは{から}まで(メソッド内であっても{から}まで)なので、余計に変数が必要になっても、{}でくくれば外には影響しないので良いのですが、しかし、VBだとそんなのないから(メソッドの終わりまで有効になってしまうから)、余計な変数が追加されると、メソッドの終わりまでソースが読みにくくなってしまうためです。

■

Re:インタフェースの使い方

o8qqqq

E-mail

データNo:182

2010年03月25日(Thu) 19:45

 

なるほど〜

私なら、Class1だけで使用したいメソッドがあった場合には、そのメソッドをインターフェースに含めてしまいます。
で、Class1で実装を行い、ほかの実装クラスでは空実装、もしくはErr.Raiseさせます。

もしくは、Class1用の特別関数用インターフェースを作ります。
インターフェースの多重継承はできるようなので。

以下は例です・・・

[SampleIF]
Public Sub CallFunc()

end sub

[SampleIF2]
Public Sub CallSpecialFunc()

end sub

[Imp1]
Implements SampleIF
Implements SampleIF2

Public Sub CallFunc()
debug.print "ガチャピンでっす!"
end sub

Public Sub CallSpecialFunc()
debug.print "実はムックだったんですzo!"
end sub


[Imp2]
Implements SampleIF
Public Sub CallFunc()
debug.print "ガッチャマンでっす!"
end sub

[main]
Dim if as SampleIF
Dim if2 as SampleIF2

Set if = new Imp1
Call if.CallFunc

'''set if2 = new Imp2 'ニューしなくてもOK?
set if2 = if
Call if2.CallSpecialFunc

'特別な関数を実装していない実装クラス
Set if = new Imp2
Call if.CallFunc


実行環境を持っていないので確認はできませんが・・・
このような感じになるのでは?



ただ単に、実装クラスに対してCodingとしているのに変な感じがしただけです。

実装は、抽象的なものに対してしろ。と、教わったもので・・・

■

Re:インタフェースの使い方

だるま

データNo:183

2010年03月27日(Sat) 00:11

 

一応修正すると、
====================================
[Imp1]
Implements SampleIF
Implements SampleIF2

Public Sub CallFunc()
debug.print "ガチャピンでっす!"
end sub

Public Sub CallSpecialFunc()
debug.print "実はムックだったんですzo!"
end sub
====================================

====================================
[Imp1]
Implements SampleIF
Implements SampleIF2

Private Sub SampleIF_CallFunc()
Debug.Print "ガチャピンでっす!"
End Sub

Private Sub SampleIF2_CallSpecialFunc()
Debug.Print "実はムックだったんですzo!"
End Sub
====================================
となります。[Imp2]も同じです。
(また、なんかjavaやC++と違う部分が…。はぁ…。)

> 私なら、Class1だけで使用したいメソッドがあった場合には、そのメソッドをインターフェースに含めてしまいます。
> で、Class1で実装を行い、ほかの実装クラスでは空実装、もしくはErr.Raiseさせます。


 それでもいいですが(※だるまも実際にそうしたこともあるかもしれない)、不要なメソッドはそもそも極力定義しない(空実装もErr.Raiseもしない)方が良いと思ってます。理由は動的テスト(単体テストなど)よりも静的テスト(コンパイルチェックなど)の方が圧倒的に楽なので、それによるチェックをより多くしたいためです。

> もしくは、Class1用の特別関数用インターフェースを作ります。
(略)
> ただ単に、実装クラスに対してCodingとしているのに変な感じがしただけです。
>
> 実装は、抽象的なものに対してしろ。と、教わったもので・・・

 可能であれば、もう少し詳しく教えてほしいです。具体的には、モジュールの強度、結合度、ISO/IEC9126(JIS X 0129)、工数(経済的な面)などの面から、わかる範囲でいいので、メリットを教えてもらえないでしょうか(※デメリットも教えてください。でないとHPには載せられませんので。)

■

Re:インタフェースの使い方

o8qqqq

E-mail

データNo:184

2010年03月27日(Sat) 03:42

 

>不要なメソッドはそもそも極力定義しない
>(空実装もErr.Raiseもしない)方が良いと思ってます。

私もそう思います。
時間のない、やっつけ時にはやってしまうかも・・・
Err.Raiseさせるのは、最低限の防御策ですね。

なので、「もしくは」以降が本命です。

> ただ単に、実装クラスに対してCodingとしているのに変な感じがしただけです。
> 実装は、抽象的なものに対してしろ。と、教わったもので・・・

厳密には「なるべく」が抜けていましたね。
これはDIコンテナの影響ですかね。
オブジェクト間の関係を疎に保つ。とかなんとか...

インターフェースを引数にして、何かをする関数をつくると、実装クラスが何かに関係なく処理を行える。
実装クラスが何なのか、なんて知らないっす!
知りたくもないっす!!
みたいなやつです。
Public Sub doSomeThing(ByRef if as Imp1)
 '何かやりマッスル
end Sub

Dim if as SampleIF

Set if = new Imp1
call doSomeThing(if)

Set if = new Imp2
call doSomeThing(if)

こんな感じです。
doSomeThing関数は実装クラスがなんだろうが、インターフェースに準拠したものであれば、受け入れ、処理を実行します。
いちいち、クラス毎に何かを実行する関数等を作る必要がなくなります。
確かに、単体、そのインスタンスだけの処理を実行するのであれば、たいした意味はないのですが、連携する?場合に意味をなしてくると思っています。

Public Function DoValid(ByRef mif as MastIF _
,ByRef tif as TranIF)
'キーの存在チェックをします
end Function

Dim as mif as MastIF
Dim as tif as TranIF
Dim as blnRst as Boolean

set mif = new Book
set tif = new BookSale
blnRst=DoValid(mif,tif)

set mif = new Drug
set tif = new DrugSale
blnRst=DoValid(mif,tif)

という記述ができます。
DoValidはインターフェースに対して実装がなされています。
実装クラスが本だろうが、薬だろうが気にしません。


>可能であれば、もう少し詳しく教えてほしいです。
>具体的には、モジュールの強度、結合度、ISO/IEC9126(JIS X 0129)、
>工数(経済的な面)などの面から、わかる範囲でいいので、
>メリットを教えてもらえないでしょうか

上記がその答えのつもりなのですが、「モジュールの強度、結合度、ISO/IEC9126(JIS X 0129)」とかは何を言っているのか分かりません。
所詮は、趣味でやっている素人プログラマー?なので底が見えてしまいますね...
多分「結合度」に関していえば、なるべく軽くするべし!!ってなるんでしょうか。

まあ、私の言いたかったことはインターフェースがあれば最低限OOP出来るだろ!
それにインターフェースを使った実装方法の恩恵を受けられるだろ!

それにつけてもStaticな変数、関数がないのがいたいっすね〜
これがあれば、もう少しましなことが出来るとは思うのですが。

まあ、私の発言は気にしないでください。すいませんでした。

■

Re:インタフェースの使い方

だるま

データNo:185

2010年03月27日(Sat) 13:58

 

DIコンテナですか。すいません。知りませんでした。(勉強になりました。)

↓以下は参考ページ
http://www.ulsystems.co.jp/technology-topic025-01.html
http://www.ulsystems.co.jp/technology-topic025-02.html


■

VBDOX日本語化

 だるま

URL

データNo:179

2010年01月30日(Sat) 09:43

 

だるまです。

 だるまが作成したツールでVBDOX用のもの(ヘッダコメントの挿入、モジュールの取込み、書出し、削除)がありますが、この度、VBDOXの画面の日本語化をおこないました。
 ダウンロードを以下から行ってください。
http://sourceforge.jp/projects/vbdox-forjp/


■

ささやかなことですが

 Taka2

データNo:174

2010年01月18日(Mon) 11:51

 

「エクセルVBAやVB6.0のRedimによる動的配列とCollectionによる動的配列の違い」について

「Function,Property Getプロシージャの返り値の型に指定する事」はDim/ReDimでも可能です。


Private Function GetArray() As String()

Dim ret() As String
ReDim ret(2)

ret(0) = "test1"
ret(1) = "test2"
ret(2) = "test3"

GetArray = ret

End Function

Public Sub Test()

Dim a() As String
a = GetArray

Debug.Print a(0)
Debug.Print a(1)
Debug.Print a(2)

End Sub

のような感じでご確認ください。

■

Re:ささやかなことですが

だるま

データNo:175

2010年01月18日(Mon) 22:01

 

だるまです。

教えてくれて、本当に、ありがとうございます。

実際に確認しました。
Excel 2003の場合:実行できました。
Excel X for macの場合:実行できませんでした。(コンパイルエラー)

 もしかしたら、VBAのバージョンが関係しているのかもしれません。HPへの更新はもうしばらくお待ちください。(平日は時間が取れないので。)
 ちなみに、今回のようにVBAのバージョンによって動作する・しないという情報は本当に貴重な情報だと思っています。

■

Re:ささやかなことですが

だるま

データNo:176

2010年01月18日(Mon) 22:12

 

だるまです。

Visual Basic for Applications 6.0 の機能
http://www.microsoft.com/japan/msdn/vba/prodinfo/features.htm
にある表の中に「可変サイズの配列の代入が可能」というのがあり、VBA6.0にて出来るようになったのだと思います。

■

Re:ささやかなことですが

Taka2

データNo:177

2010年01月19日(Tue) 09:16

 

> Excel 2003の場合:実行できました。
> Excel X for macの場合:実行できませんでした。(コンパイルエラー)
なるほど、バージョン間の違いだったのですね。
調査と補足、ありがとうございます。

VBAではなくVBですが、確かにVB4.0にはなかった仕様と記憶しています。
#手元に5.0系のVBがないのでそちらは未確認

そしてMac版でも、Excel2008なら最新だからさすがにVB6.0系列だろう、と思ったらExcel2008にはそもそもVBAが搭載されてないようですね。
後方互換を全力で切り捨てる、なんというマイクロソフトの斜め上っぷり・・・。

■

Re:ささやかなことですが

だるま

データNo:178

2010年01月24日(Sun) 13:43

 

だるまです。

修正しました。
URL:
http://darumaexcel.uijin.com/info/redim_or_collection.html


■

UMTPの合格体験記

 だるま

URL

データNo:173

2009年12月12日(Sat) 14:55

 

だるまです。

UMTPのサイトにだるまの合格体験記が載りました。
■URL
http://www.umtp-japan.org/modules/examination3/index.php?id=18&tmid1=21

※すいません。上記リンクをクリックしても合格体験記のページにジャンプしません。URLをWebブラウザのアドレスバーにコピペしてください。

■ページ内の場所
3つめ(投稿者 宮崎 崇さん)です。

参考になればと思います。よろしくお願いします。


<< 前のページ

次のページ >>