- ベストアンサー
配列方法とCall文とFor文について
VB(A)について勉強中なのですが、わからない所があるので、分かりやすく教えていただけらたと思っています。 まず配列方法に関してですが、 Dim aaa() As Long という方法を見かけるのですが、調べてみると要素が不定と書いて有りました。 そこで、もし2次元配列、3次元配列で要素が不定の場合はどう書いたらよいのですか? もし、要素が確定しているなら Dim aaa(10,10) As Long Dim aaa(10,10,10) As Long とかけますよね。 次にCall文なのですが、 Call文はサブプロシージャを呼び出すための物と認識しています。 そこで、 Call BBB(...) とあれば Sub BBB(... As ○○○) と書いてある物を見ました。 ここで、(... As ○○○)とはどういう意味なのでしょうか? それと、Call文を使った場合は、戻り値などの設定は無いのでしょうか? つまり、Call文を使ったら一方通行にSubを呼び出すだけと言う物なのでしょうか? あと、For文に関してですが、 ある例題を見たら For Each ... In ××× と書いて有りましたが、どういう意味なのでしょうか? 色々書かせていただきましたが、分からない事だらけで困っています。 アドバイス宜しくお願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#1 Wizard_Zeroです。 おおよそご理解はしていると思われますが、念のためいくつかツッコミ入れます。 > つまりDim Sld As SlideをTestの括弧の中で定義してしまう事ですね。 Sub Test(Sld As Slide) End Sub と定義するのと Sub Test() Dim Sld As Slide End Sub と定義するのでは全く異なります。プロシージャ定義の括弧内は、プロシージャの処理に必要なデータを受け取るためのもので「引数」と呼びます。プロシージャで使用する変数を定義するためのものではありません。 Sub Test(Sld As Slide) とは、Testを呼び出す際に引数がひとつ必要で、それがSlideオブジェクトでなくてはならない、という定義になります。 ご提示されたコードに間違いは見当たらないので、あとは理解の仕方の問題ですね。 ちなみに、Functionでは戻り値の型を指定することもできます。 Function AAA(x As Long, y As Long) As Long AAA = x + y End Function とすれば、関数AAAの戻り値は必ずLong型になります。戻り値の変数AAAをLong型のみにしてしまうわけです。 > Set Sld=ActiveWindow.Selection.SlideRange(1) > Sldに現在使用している開いているWindowのSlideの全体を選択します。 PowerPointのVBAは扱ったことないのですが、上記のコードだと「選択されているスライドのうち、先頭のスライドをSldに格納」という処理になっちゃったりしてませんか?? For Eachの役割はあくまでコレクションに含まれるオブジェクトの列挙です。まとめてどうのこうのという意味合いはありません。 For Each Shp In Sld.Shapes Next このようにした場合、SldのShapesコレクションに含まれるオブジェクト(この場合はShapeオブジェクト)を順番に列挙しするだけにすぎません。Shpに対して、TopやLeftなどのプロパティを操作すれば、結果的にまとめて処理する、ということになるだけです。 > 例えば、.Top や.Leftなどがあれば、本来 > Slide.Shapes.TopやSlide.Shapes.Leftという事になっているですか? 「Slide.Shapes.TopやSlide.Shapes.Leftというプロパティがないので、すべての要素にTop, Leftを設定するためにFor Eachを使う」という捉え方です。 For EachがSlide.Shapes.TopやSlide.Shapes.Leftの代わりとしてだけ存在するわけではない点に気をつけてください。
その他の回答 (2)
- imogasi
- ベストアンサー率27% (4737/17069)
エクセルVBAに限って独断と偏見で書いてみます。 (1)配列 エクセルのシートのセルそのものの構成が2次元配列と対応していると見ルことができます。だからエクセルVBAで2次元配列を使うという気になったら、難しく考えすぎて無いか、反省が必要。 ここの質問コーナーの回答でも使ったことが無い。 3次元配列など、知らなくても事務系の仕事でエクセルを使う場合は困らない。 (2)Call文 これも知らなくても、使わなくても一向に困らない。SUBプロシージャー名をそのまま書けば済むから。 >プロシージャ名だけが書かれているのでプロシージャを呼び出しているのかどうか一見すると分かりにくいです というご意見もあります。 http://www.officepro.jp/excelvba/sub/index2.html >Subを呼び出すだけと言う物なのでしょうか エクセルVBAの場合は、セルという、メモリ代替物が有るので、そこ(セルの値など)をVBAでいじくってしまう。 だからあまり議論の意味は無い。 例外的にと言うか道具的にユーザー関数(処理してセルの値を返す) などでFunctionプロシを使う。 もちろん本来のFunctionプロシを使う場面も作れると思うが。エクセルVBAでは別プロシージャにがんがん分けるというほどの規模にはならないように思う。本質的にそうだと言うのではないが。 (4)戻り値 これは有名な話で、SUBプロシージャーとFunctionプロシとある。 http://www.officepro.jp/excelvba/sub/ Googleで「vba プロシージャ」で照会すること。 (5)For Each これは便利なもので、良く使います。 Googleで「Fpr Each」で照会すれば、たくさん記事が出ます。 エクセル関連では 範囲の全セルを順につかみたい ブックの全シートを順につかみたい フォルダの全ファイルを順につかみたい シートのShapeなどを前部順につかみたい 配列の要素を全て順につかみたい。 これをForNextでやると、そのコレクションの全個数を掴み For i=1 to obj.count (objは実際のコレクション名。従ってその数の意味) iでobjを掴む Next i のような形になる。 ==== 質問を見ていて (1)なぜGoogleを活用しないのか これやヘルプやMSDNの記事など活用しないと。 ほとんどWEB照会で詳しく判る話題。 (2)エクセルVBAに限れば、ピントハズレの話題を気にしているなと言う感じ。もっとほかに大切なことがあると思うと言う感じ。VBAはアプリケーションに密着したものなので、もっと個別のメソッドやプロパティで、「そういうのあったな」という勉強(一種の暗記)などが必要と思う。 VBではそういうことは少なくなると思う。しかしコントロールなどの面ではそういう面が強い。もっと他のオブジェクトを使いこなすなどの必要があるし。 また処理ロジック(極端な場合はアルゴリズムを利用)の思考力を鍛えることが必要。 この質問も、自分が今はどちらに重点を置いて勉強しているかに「よって、VBかVBAに限って質問するほうが良い。VB(A)とカッコつきの(A)で両者かねられる世界ではない。 この質問の話題は両方ともありえる課題だが、実際の利用では、ウエイト付けがVBとVBAで起こってくると思う。 それとVBはVB6のことを言っていると思うが、VB.NET系との淘汰の問題が気になる。VBがVB6のことなら、いまさら>VB(A)について勉強中、でよいものかどうか。VBAもVSTO http://d.hatena.ne.jp/keyword/VSTO に、いつMSが踏み切るか、そのままで行くのか。
お礼
ありがとうございました。 グーグル等の検索もしましたが、イマイチわからない事があり、以前ここで質問させていただいた時に、理解を深める事が出来たためです。 昔はFORTRANを勉強し、使っていたので、アルゴリズムの思考力はそれなりにあると思っています。
- うぃず(@Wizard_Zero)
- ベストアンサー率69% (344/495)
・多次元配列について 多次元配列でも宣言は同じで、ReDimで配列の次元数を決めます。 Dim A() As Long, B() As String ReDim A(2,2) ReDim B(2, 3, 4) ・CallとAsについて Subプロシージャに戻り値はありません。変数で戻り値を取ろうとするとエラーになります。戻り値を返すのはFunctionです。 CallはSubプロシージャの呼び出しだけでなく、戻り値を受け取らないFunctionの呼び出しでも使用できます。 Functionの戻り値を受け取る時にCallは利用できません。 Call hogehoge() ' 戻り値がいらない場合 strA = hogehoge() ' 戻り値が要る場合 Call strA = hogehoge() 'これはできない Function hogehoge() hogehoge = "戻り値" End Function SubプロシージャやFunctionプロシージャの引数にある As~ は引数の型を指定するためのものです。決められた型(厳密には暗黙的に変換できる型)以外は引数に指定することが出来なくなります。 例えば、 Sub hoge(A As Long) と宣言されているプロシージャに対して Call hoge("ABC") を呼び出すとエラーになります。(文字列はLongにできない) ・For Eachについて オブジェクトが列挙可能な他のオブジェクトやデータ型を持っている場合に、それらを列挙するためのステートメントです。 フォルダ内のファイルを列挙したり、辞書コレクションの内容を列挙したりする際に使用します。
お礼
大変わかりやすいご説明ありがとうございました
補足
ありがとうございます。 かなり理解が深まりました。 ・多次元配列に関しては 不定要素で規定したら必ず後できちんと配列を切らないと行けない事ですね。 だから Dim A() As Long としたら、必ずこの後で、 ReDim A(10,30) と配列を切らないといけないという事ですね。 ・CallとAsに関しては Dim Sld As Slideと書かれていたら、SlideというオブジェクトをSldと規定するという事ですね。 今手持ちの例があるので、少し書かせていただきます。 Sub Main() Dim Sld As Slide … Call Test(Sld) … End Sub Sub Test(Sld As Slide) … End Sub とありましたら、Mainの中でSlideというオブジェクト(?)をSldと定義しています。 その後CallでTestというサブプロシージャを呼び出します。このとき、Sldと定義したオブジェクトをTestに移動させます。このとき、サブプロシージャの中でもSldを定義しておかないと行けないから Test(Sld As Slide)として定義します。 つまりDim Sld As SlideをTestの括弧の中で定義してしまう事ですね。 またFunctionに関しては Sub Main() Dim y As Long, x As Long … z=AAA(y,x) … End sub Function AAA(y As Long, x As Long) AAA=… End Function でよろしいでしょうか? ・For Eachに関して 少々イメージが出来なかったので、例文を持っているので、それを書いて私なりの解釈を書かせていただくので、もし誤解しているようならご指摘いただければと思います。 (ちなみにこれはPowerPointの為のVBです) Sub Main() Dim Sld As Slide Dim Shp As Shape Set Sld=ActiveWindow.Selection.SlideRange(1) For Each Shp In Sld.Shapes With Shp … End With Next … End Sub この場合、それぞれSlideとShapeというオブジェクト(?)をそれぞれSldとShpと定義し、Sldに現在使用している開いているWindowのSlideの全体を選択します。 Slideの下層のShapesをまとめてShpとして考えてNextまでそれを定義しておくという事です。 だから、WithからEnd Withの間に色々なオブジェクト(?)があれば全てくっついていくという事です。 例えば、.Top や.Leftなどがあれば、本来 Slide.Shapes.TopやSlide.Shapes.Leftという事になっているですか? きちんと表現できていないかも知れませんが、ご指摘よろしくお願い足します。
お礼
ありがとうございます。 なんとなく、イメージが出来た気がします。 また、お世話になる事がありますので、よろしくお願いいたします。