• ベストアンサー

エクセルVBAの次のコードの意味教えて下さい。

Sub macro1() Dim a As Integer, b As Integer a = 1 b = 5 macro2 a, b MsgBox a + b End Sub Sub macro2(c As Integer, d As Integer) c = c * 10 d = d * 5 End Sub 答えは35と出ます。 よろしくお願いします。

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんにちは。 そのサンプルは、どこかの本に載っていたものではありませんか? そういうことは、段階的にVBAとしては、応用コースに出てくるものです。ある程度、自分でマクロを書くようになれば、自然に覚えます。 書籍では、「値渡しと参照渡し」というタイトルなどが付いています。 ただ、サンプルコードとしては、以下のように書き換えたほうが分かりやすいです。 '「参照渡し」ByRef Sub macro2(a As Integer, b As Integer) a = a * 10 b = b * 5 End Sub このサブプロシージャは、「参照渡し」になっていますから、値は、サブプロシージャの中で計算されて、元のMacro1 側に戻されます。 それに対比するのが、「値渡し」という方法です。 '「値渡し」ByVal Sub macro3(ByVal a As Integer, ByVal b As Integer) a = a * 10 b = b * 5 End Sub こちらの比較してみてください。引数の前に何もつけないと、自動的に、サブプロシージャでは、「参照渡し」になります。 >Sub macro2(c As Integer, d As Integer) >のようにサブプロシージャの後の()の中に入れるのと >改行してDim・・・と書くのは同じことなのでしょうか? ()の中は、引数(アーギュメント)といいます。引数を取るものと、引数を取らないものでは、引数を取らないものは、自己完結しますが、引数を取るものは、他のプログラム等から呼び出しが必要になります。 まず、ローカルウィンドウや、ウォッチウィンドウの使い方を覚えてください。そこで変数がどう変化するか見てください。

NEWYORKERS
質問者

お礼

ご指導ありがとうございます。 単に回答だけでなく、なにを勉強すればいいのかも 教えていただけてよかったです。 おしえてもらった事はすべて初耳のことばかりでしたので、 びっくりしました。本当にありがとうございました。

その他の回答 (3)

  • marbin
  • ベストアンサー率27% (636/2290)
回答No.3

#2です。 質問文およびokormazdさんのレスをよく見てませんでした。 失礼しました。 私のレスはスルーしてください。

  • marbin
  • ベストアンサー率27% (636/2290)
回答No.2

参考になると思います。 Sub testb(ByVal a As String, b As String) MsgBox a & b End Sub Sub testa() Dim c As String Dim d As String c = "本日は" d = "晴天なり" Call testb(c, d) End Sub

NEWYORKERS
質問者

お礼

回答ありがとうございます。 ()内にいれるのは、出だしでもいいんですね。 なぜか文字だと少し理解できた気がしました。

  • okormazd
  • ベストアンサー率50% (1224/2412)
回答No.1

Sub macro1() macro1という名前のサブプロシージャです。引数はありません。 Dim a As Integer, b As Integer a,bは整数ですよ。どんな変数を使うか(コンピュータ) に知らせています。 a = 1 aは1です。 b = 5 bは5です。 macro2 a, b macro2というサブプロシージャを実行してください。実行するのに必要なaとbをつけてお願いします。 MsgBox a + b a+bを表示してください。 End Sub これでmacro1は終わりです。 Sub macro2(c As Integer, d As Integer) macro2という名前のサブプロシージャです。実行するには、整数の引数cとd 2つ必要です。 macro1で、a=1,b=5で実行するように頼まれています。これがcとdにはいります。だから、c=1,d=5になります。 c = c * 10 c×10を計算してその結果を新しいcにしてください。 c=1×10=10になります。これが頼まれたmacro1のaとしてもどります。 d = d * 5 d×5を計算してその結果を新しいdにしてください。 d=5×5=25になります。これが頼まれたmacro1のbとしてでもどります。 End Sub これでmacro2は終わりです。macro2の実行を頼まれたmacro1に戻ります。aは10、bは25になっています。 macro1に戻ってa+bを表示するのですから、 10+15=35が表示されます。

NEWYORKERS
質問者

お礼

ご指導ありがとうございました。

NEWYORKERS
質問者

補足

Sub macro2(c As Integer, d As Integer) のようにサブプロシージャの後の()の中に入れるのと 改行してDim・・・と書くのは同じことなのでしょうか? aがcに、はいり、bがdに、はいるところですが、 なぜaがdで、bがcになったりしないのでしょうか? どうか教えて下さい。

関連するQ&A

  • VBAのプロシージャーと変数の名前の区別について

    VBAの初心者です。教えてください。 Sub ex() Dim a As Integer Dim b As Integer a = 2 a a, b MsgBox b End Sub Sub a(a As Integer, b As Integer) b = a End Sub 上記のプログラムを実行するとうまくいきません。VBAのプロシージャーと変数って同じ名前を使うとだめなのですか?教えてください。

  • セル番地をvbaで探したい

    エクセルのセルに A1→あ B1→い C1→う がはいっています。 この状態で Sub Macro1() Dim mystr1 As String mystr1 = "c1" MsgBox mystr1 & "の値は、" & "です。" End Sub を実行した時に、mystr1のアドレスを探して、msgboxに表示させたいのですが、 どのような方法があるのでしょうか? アドバイスよろしくお願いします。

  • エクセルのVBAコードにつてい

    以下のコードについて、その内容をまだ自分の知識では理解できず困っておりまして、アドバイスいただければと思いまして書き込みました。 『コード』 Sub Test() Dim Lc As Integer Dim Ct As Integer Dim MyR As Range Dim C As Range Dim D As Range Lc = Range("A1").End(xlToRight).Column - 2 For Each C In Range("B2", Range("B65536").End(xlUp)) Ct = WorksheetFunction.Count(C.Offset(, 1).Resize(, Lc)) If Ct > 0 Then Set MyR = C.Offset(, 1).Resize(, Lc).SpecialCells(2, 1) For Each D In MyR With Sheets("Sheet2").Range("A65536").End(xlUp) .Offset(1).Value = C.Value .Offset(1, 1).Value = Cells(1, D.Column).Value End With Next Set MyR = Nothing End If Next With Sheets("Sheet2") .Columns("A:B").AutoFit .Activate End With End Sub 『質問』 1.「Lc = Range("A1").End(xlToRight).Column - 2」の部分の解釈は「A1から右方向に一番最後のセルまでを範囲指定し、その一番右のセルの列番号を取得する」変数という解釈でいいのか 2.「Ct = WorksheetFunction.Count(C.Offset(, 1).Resize(, Lc))」の部分の変数はどういった値の整数を取得する変数なのか 以上2点についてアドバイスいただけると幸いです。

  • VBA 標準モジュールとフォーム

    ある標準モジュール内で生成した変数の値をフォームのコマンドボタンをクリックしたら表示されるプログラムはどうやってつくるのですか? 標準モジュール sub test() dim a as integer dim b as integer dim sum as string a=5 b=1 sum=a+b End sub フォームのコマンドボタンクリック Sub CommandButton1_Click() MsgBox sum End Sub 標準モジュールで計算した答えがフォームのコマンドボタンをクリックしたら答え6が表示されるようにしたいのですが、どうしたらできますか?

  • エクセル VBA

    A1,A2,A3→RAND()*99+1 B1→MAX(A1:A3) Sub test() Worksheets("sheet1").Calculate Dim x As Integer x = Range("B1") Range("C1").Value = x End Sub このように記述すると、B2とC2で結果が変わってしまうのですが、どうしてでしょうか?結果を同じにするにはどうすればいいですか?

  • エクセルvbaに関する質問です

    ExecuteExcel4Macroを使った際について質問があります。 別ブックのセルを参照したいために、ExecuteExcel4Macroを使いました。 1つ目のmsgboxではパスを変数で、二つ目のmsgboxではパスを直書きしています。 下記のサンプルプログラムで2つとも同じものを表示させたいのですが、別の結果が表示されます。 =====サンプルプログラム===== Sub Sample1() Dim name As String Dim path As String Dim sheet As String path = "C:\Users\USER\Desktop\シフト表\新しいフォルダ\" name = "book1.xls" sheet = "Sheet1" Application.DisplayAlerts = False MsgBox ExecuteExcel4Macro("'" & path & "[" & name & "]" & sheet & "'!R1C1") MsgBox ExecuteExcel4Macro("'C:\Users\USER\Desktop\シフト表\新しいフォルダー\[book1.xls]Sheet1'!R1C1") Application.DisplayAlerts = True End Sub ===ここまで===== 実際のbook1.xlsのA1セルには「1」が入っているのですが、変数で書いた場合のみ「aaaaaa」が表示されます。 どうかご教授いただけたら幸いです。

  • vba boolean変数を開放する方法

    エクセルのセルに「○○○○○○○○○○××××××××××」と入っているものをランダムに並べ代えるマクロを探してみました。 Sub macro2() Dim i, m As Integer Dim b, c As String Dim flg(1 To 20) As Boolean b = Cells(1, 1).Value Randomize For i = 1 To 20 Do m = Int(20 * Rnd + 1) If flg(m) = False Then flg(m) = True Exit Do End If Loop c = c & Mid(b, m, 1) Next i Cells(1, 2).Value = c End Sub これはうまく動くのですが、10行分やろうとして、以下のように変更すると暴走(終わらない)します。 Sub macro2() Dim i, m, n As Integer Dim b, c As String Dim flg(1 To 20) As Boolean For n = 1 To 10 b = Cells(n, 1).Value Randomize For i = 1 To 20 Do m = Int(20 * Rnd + 1) If flg(m) = False Then flg(m) = True Exit Do End If Loop c = c & Mid(b, m, 1) Next i Cells(n, 2).Value = c next n End Sub 一行目が終わってもboolean変数の値がそのまま残っているのが原因らしいのですが開放する方法がわかりません。 取りあえずもう一つマクロを追加してやりたいことはできたのですが、 Sub macro1() Dim n As Integer For n = 1 To 10 Call macro2(n) Next n End Sub Sub macro2(n As Variant) 以下略 なんかスッキリしません。 boolean変数を開放し、マクロひとつですます方法を教えて頂きたくお願いします。 flg(m) = Falseを挿入してもダメでした。

  • 単純【エクセルVBA】なぜオーバーフローになる?

    環境 Excel2003 Win7 64bit -------------- Const C as Currency = 50000000 Sub Test()   Dim A as Currency   Dim B as Currency   B = 6823695200   A = B \ C '←ここでオーバーフロー End Sub --------------- 「A = B \ C」 ↑この式はオーバーフロー時、ウォッチ式上では、 型: Integer と表示されますが、これも不思議。 また、「A = B \ C」を、 A = CCur(B) \ CCur(C) としても、オーバーフロー。 それと、 「Const C as Currency = 50000000」を、 「Const C = 50000000」 としても、同様にオーバーフロー。 Currency型は、 -922,337,203,685,477.5808~922,337,203,685,477.5807 のはず。 このオーバーフローは、一体なぜ?

  • エクセルVBA・完全一致の情報

    既に出ているかもしれませんが… 文字列の完全一致で、セルの座標を取得が上手くいきません。 現在は完全一致した場所を塗りつぶしています。 A B C 1 2 AAA 3 Sub Find_moji() Dim a As Integer Dim b As Integer Dim c As Object For Each c In Worksheets("特産品素材").Range("a1:a3") If c.Value Like "AAA" Then c.Interior.ColorIndex = 3 '赤 End If Next c End Sub 求めたい結果としては、AAAが入っているA2を塗りつぶして、AAAの座標(X座標1、Y座標)の情報を取得したいのです。 お願い致します。

  • エクセルVBAを教えて下さい

    エクセルの表で -AB C D E F 1年月--1801 2------ 3------ 4------ (-)は空欄でセルE1=18、F1=1とします。 コントロールボックスをつかって Private Sub Command登録_Click() Dim d1 As Long Dim d2 As Long Dim ret As Variant Dim FindValue As String Dim TotalAddress As String If Range("E1").Value = "" Or Range("F1").Value = "" Then MsgBox "該当する場所にデータが入っていません。", vbCritical Exit Sub End If d1 = Range("A65536").End(xlUp).Offset(1).Row d2 = Range("B65536").End(xlUp).Offset(1).Row FindValue = """" & Range("E1").Value & Range("F1").Value & """" TotalAddress = Range("A1").Resize(d1).Address & "&" & Range("B1").Resize(d1).Address ret = Evaluate("MATCH(" & FindValue & "," & TotalAddress & ",0)") If IsError(ret) Then Cells(d1, 1) = Range("E1").Value Cells(d2, 2) = Range("F1").Value Else MsgBox "既に同じ組み合せがあります。", vbInformation End If End Sub というものを作ったのですが、E1=18、F1=1及びコマンドボタンを別シートに作成し、上記の表への登録をできるようにしたいのですが、なにかいい方法はありませんか?

専門家に質問してみよう