• ベストアンサー

配列方法と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 ××× と書いて有りましたが、どういう意味なのでしょうか? 色々書かせていただきましたが、分からない事だらけで困っています。 アドバイス宜しくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.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の代わりとしてだけ存在するわけではない点に気をつけてください。

sumaabe
質問者

お礼

ありがとうございます。 なんとなく、イメージが出来た気がします。 また、お世話になる事がありますので、よろしくお願いいたします。

その他の回答 (2)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.2

エクセル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が踏み切るか、そのままで行くのか。

sumaabe
質問者

お礼

ありがとうございました。 グーグル等の検索もしましたが、イマイチわからない事があり、以前ここで質問させていただいた時に、理解を深める事が出来たためです。 昔はFORTRANを勉強し、使っていたので、アルゴリズムの思考力はそれなりにあると思っています。

回答No.1

・多次元配列について 多次元配列でも宣言は同じで、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について オブジェクトが列挙可能な他のオブジェクトやデータ型を持っている場合に、それらを列挙するためのステートメントです。 フォルダ内のファイルを列挙したり、辞書コレクションの内容を列挙したりする際に使用します。

sumaabe
質問者

お礼

大変わかりやすいご説明ありがとうございました

sumaabe
質問者

補足

ありがとうございます。 かなり理解が深まりました。 ・多次元配列に関しては 不定要素で規定したら必ず後できちんと配列を切らないと行けない事ですね。 だから 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という事になっているですか? きちんと表現できていないかも知れませんが、ご指摘よろしくお願い足します。

関連するQ&A

  • 配列方法と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 ××× と書いて有りましたが、どういう意味なのでしょうか? 色々書かせていただきましたが、分からない事だらけで困っています。 アドバイス宜しくお願いいたします。

  • 多次元配列とfor文について

    javascriptの配列について質問です。 例えば: var arrXXX = new Array(); function samplefunc{ //3次元配列の種類の作成 for (m = 0; m < aaa.length ; m++) { //連想配列作成 arrXXX .push(aaa[m]); } for (j = 0; j < bbb.length; j++) { for (i = 0; i < ccc.length; i++) { arrXXX[aaa[j]] = new Array(ccc.length); arrXXX[aaa[j]][i] = new Array(ccc.length); for (k = 0; k < ddd.length; k++) { arrXXX[aaa[j]][i][k] = eee;     ここでは配列を適切に使える・・・ } } } ここでarrXXXを使いたいが、3次元配列でなくなっている?!  arrXXX[~][0][0]はnullまたはオブジェクトではありません・・・がでます。 } 結局、for文を完全にでてしまうと、せっかくつくった配列がダメになってしまいます。どうすればfor文外で配列を使用できるのか教えてください!

  • 二次元配列のVBA

    二次元配列のVBAの書き方がよくわからないのですが、 私が作ったサンプルプログラムのSub 二次元()において 二次元配列で表すにはどうすればいいのでしょうか? Sub 二次元()では 配列を格納する変数はtmpしか使っていませんが もう一つ配列を格納する用の変数を作ればいいのでしょうか? 数字とアルファベットは別々に取り出したいです。 ----------------------------------------------------- Sub 一次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub Sub 二次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i & "と" & Chr(64 + i) Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub

  • 構造体配列の特定のメンバーをFor~Eachで

    みなさんこんにちは。昔Vb6を少々やっていましたが ここ数年遠のいていました。 必要に迫られ最近Vb2010を勉強しはじめた50歳です。 サンプルの通り3つのメンバーを持つ構造体配列があり、 メンバーData3の合計を得るのに、ループで回して 計算してましたが、これを For~Next ではなくFor~Each で やれないかと考えておりました。配列の要素の個数が不定 な場合に便利だと思ったからです。 サンプルの ???_1が「型」で ???_2が「コレクション」と なるように記述するのだということまではわかりますが、 具体的な記述がわかりません。For~NetでもDo~Loopでも 他にも方法があるのは知っています。勉強の為に、For~Eachでの やりかたを知りたいのです。また、構造体配列ではなく、多次元配列での 特定の次元要素を同様に処理する方法も知りたいです。 どなたかご教授お願いできれば幸いです。 ネット上でそれなりに調べましたが、目的に沿う情報は みつけることができません。 Public Class Form1 Structure STR Dim Data1 As Double Dim Data2 As Double Dim Data3 As Double End Structure Private Sub Button1_Click(sender As System.Object, _ e As System.EventArgs) Handles Button1.Click Dim Str_1(10000) As StR Dim Rn As New System.Random() For i = 0 To 9999 Str_1(i).Data3 = Rn.Next(100) Next '以降いろんな処理をやる ' ' 'このあと For~Nex ではなくFor Each をつかってメンバーDat3の合計を得るには? Dim sum As Double For Each X As ???_1 in ???_2 '???_1 と ???_2 の記述がわからない sum += X Next Label1.Text = sum.ToString End Sub End Class

  • VBAの動的配列について

    いつもお世話になっております。 エクセルVBAを学習中の者です。 動的配列についてお伺いします。 添付資料を見て頂きたいのですが、 シート名1~4に同一レイアウトの表があります。 これらの表をを2次元配列に格納し、その後、同一レイアウトのシートに一括転記したいと考えています。 転記の事を考えて、条件としては、 シート1から2行目以降のデータを配列『data』に格納、変数『dataCnt』が転記先の行番号と同じになるように考えています。 当初は、配列の定義を『Dim data(100,3) As Variant』と、多めに要素数を定義して、コードを記述していました。 正直、凄く気持ちが悪い感じでした・・・ 最近、動的配列を学習しまして、 シートごとにデータの行数を変数『lastRow』に格納して、配列を再定義して【データ数=要素数】とならないか? と思い、下記のようなコードを書いてみました。 が、『ReDim Preserve~』で実行エラーが発生してしまいます。 原因がなぜかわかりません! そもそも、動的配列はこのような使い方は出来ないのでしょうか? Sub テスト() Dim data() As Variant Dim x As Long Dim i As Long Dim ii As Long Dim lastRow As Long Dim dataCnt As Long dataCnt = 2 For x = 2 To 5 Worksheets(x).Activate lastRow = Cells(Rows.Count, 1).End(xlUp).Row If x = 2 Then ReDim data(2 To lastRow, 3) Else ReDim Preserve data(2 To dataCnt + lastRow - 1, 3) End If For i = 2 To lastRow For ii = 1 To 3 data(dataCnt, ii) = Cells(i, ii) Next ii dataCnt = dataCnt + 1 Next i Next x End Sub どなたかご指導をよろしくお願いいたします。

  • 配列

    エクセルvbaなのですが Sub test() ' 配列 Dim arr() As Integer= {0, 1, 2, 3, 4, 5} ' 抜き出した要素を格納するための変数 Dim i As Integer ' すべての要素について繰り返す For Each i In arr Console.WriteLine (i) Next End Sub これって何でエラーになるのでしょう? Dim arr() As Integer= {0, 1, 2, 3, 4, 5} でエラーになりますが、なぜだかわかりません。

  • For文と配列

    下のFor文でセルに0から9999の数字を入力しようとしたのですが 「forで指定された変数は既に使用されています」というエラーがでます。 Dim i As Integer Dim Num(3) As Integer For Num(0) = 0 To 9 For Num(1) = 0 To 9 For Num(2) = 0 To 9 For Num(3) = 0 To 9 Cells(i, 1) = Num(3) + Num(2) * 10 + Num(1) * 100 + Num(0) * 1000 i = i + 1 Next Num(3) Next Num(2) Next Num(1) Next Num(0) 他には何にも書いていないマクロなので他所で使用しているとも思えないですが うまくゆきません。 続きの作業でNum()を配列として作業したいのでこの形を変えたくありません。 何がいけないのでしょう?

  • 配列を関数に渡す方法

    VB6.0のプログラムで質問があるのですが 下のプログラムのように配列num、num1を関数AAAに 渡したいと思うのですがどうすればいいのでしょうか? よろしくお願いいたします。 Option Explicit Private num(10) As Integer Private num1(10) As Integer Private Sub Write_Click()    AAA(num)    AAA(num1) End Sub Private Function AAA(???)    Dim i As Integer    For i = 1 To 10       ???(i) = i    Next i End Function

  • 拡張for文について質問

    以下は、拡張for文と配列に関するソースコードの一部を抜粋したものです。 それを見た上で、私の質問に答えてください。 int[]a={10,5,8,4,3}; for(int n:a){ System.out.print(n+" "); } int[][]a={{1,2},{4,5,6}}; for(int[]n:a){ for(int k:n){ System.out.print(k+" "); } System.out.println(""); } 質問1:何故、前者の配列は、『for(int n:a)』のように[]がついてなくても配列要素が取り出せるのに、後者の多次元配列は『for(int[]n:a){』のように『[]』がついた拡張for文を書いた上で、下にも拡張for文を書いた2重構造でないと配列要素を取り出せないのですか? 後者について『for(int n:a){』の文だけで多次元配列aの要素全て取り出せると思ってました。 因みに、配列変数には配列要素が入ってるのではなくて「参照」が入ってるのはわかってます。 このことと、何か関係があるのか、、?

    • ベストアンサー
    • Java
  • エクセル VBA Call

    VBA初心者です。 callというのを知ったのですが、 ------------------------------- sub aaa() Dim z As Integer For z = 1 To 30 Step 1 Dim y As String y = Cells(2 + z, 3).Value Dim x As String x = Cells(2 + z, 2).Value ・ ・ call m1 call m2 call m3 call m4 ・ ・ next z end sub という記載があって呼び出し元に sub m1 sheet(y).select と書きたいです。この y とか x を先に記載した内容と同じ 認識にするにはどうしたら良いですか。 ど素人に分かるようにお願いします。教えてエクセル大先生。

専門家に質問してみよう