• ベストアンサー

VBAに関する種々の質問

VBAに関していくつか質問させて下さい。 ・ファンクションプロシージャでは Function Fun(x) ・・・ End Function という形で関数を定義しますが、この関数の中でこれとは別の関数を定義して使いたい場合にはどうすれば良いのでしょうか? Function Fun(x) ・・・ Function Fun2(x) ・・・ End Function ・・・ End Function みたいに入れ子状にすれば良いのでしょうか? ・Range()を使って、 Range(A1)*Range(A2)+Range(B1)*Range(B2)+・・・ ということは出来ないのでしょうか?こういうのはCellsを使うしかないのでしょうか? ・Int()で整数であるということ定義出来ますが、浮動小数点であるdouble()というのが効かないのはなぜなのでしょうか? Dim as doubleだと効くのですが。 何卒よろしくお願い致します。

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

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.5

#前回の質問などがあるならばその後始末などもきちんとしましょう http://oshiete1.goo.ne.jp/qa4507211.html 関数の入れ子は出来ませんが関数内にサブルーチンを作成することは可能です # 以下はプロシージャの例ですが関数でも同様に出来ます Sub Test1()   dim n as integer, m as integer   for m = 0 to 5    gosub TestSub   next   exit sub TestSub:   n = n + 1   debug.Print n   return End Sub ただしこの方法では Testプロシージャの中なので サブルーチンTestSubと変数を共有してしまいます Rangeについては 法則が決まっているなら Offsetでオブジェクト自身を移動することでループ処理が可能です Dim objR1 as Range, objR2 as Range dim x as double, n as integer Set objR1 = Range("A1") Set objR2 = Range("A2") x = 0 ' A1*A2 + B1*B2 + C1*C2 + D1*D2 + E1*E2 for n = 1 to 5   x = x + objR1.value * objR2.Value   ' 1列右へ移動する   Set objR1 = objR1.Offset( 0, 1 )   Set objR2 = objR2.Offset( 0, 1 ) next といった具合です

その他の回答 (5)

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.6

>For, Nextでこれをしたいのですが、Rangeでは列に対して連番することは出来ないのでしょうか? For i=1 to 100 X1=X1+Range("A1").Offset(,i-1) * Range("A2").Offset(,i-1) X2=X2+Range("A1").Offset(,i-1) * Range("A1").Offset(1,i-1) X4=X4+Range(Cells(1,i)) * Range(Cells(2,i)) X5=X5+Cells(1,i) * Cells(2,i) Next A~Z列の範囲であればこんな方法も可能。 X3=X3+Range(Chr(64+i) & 1 ) * Range(Chr(64+i) & 2 ) Cells() で指定する場合は、数値座標で指定できるので位置指定がしやすいのです。 要は使い分けの問題なので、特定の方法に拘る必用はありません。

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.4

>この関数の中でこれとは別の関数を定義して使いたい場合 プロシージャーは一つのプログラムとして完結している必用があるので、プロシージャーの中にプロシージャーを書くことはできません。 別のプロシージャーを呼び出して使います。 Function Fun1(x) Fun1=Fun2(x)/2 End Function >Range(A1)*Range(A2)+Range(B1)*Range(B2)+ 意味がわかりませんが・・・。 X=Range("A1")*Range("A2")+Range("B1")*Range("B2")・・・ のように書きます。 >・Int()で整数であるということ定義出来ますが 定義するのではなく、INT関数では小数点を含む値から整数部だけの値に変換するのです。 >浮動小数点であるdouble()というのが効かないのはなぜなのでしょうか? VBAでは自由に型変換する機能は持っていません。 どのような使い方をしているのか解りませんが、そのような関数は無いからです。

motarou
質問者

お礼

ありがとうございます。 X=Range("A1")*Range("A2")+Range("B1")*Range("B2")・・・ に関してなのですが、このような簡単な場合は良いのですが、難しい式の場合には For, Nextでこれをしたいのですが、Rangeでは列に対して連番することは出来ないのでしょうか? 何卒よろしくお願い致します。

  • korin_
  • ベストアンサー率69% (46/66)
回答No.3

#2です。 ・Range()の件は、質問の意図を読み違えていたようです。 失礼しました。

  • korin_
  • ベストアンサー率69% (46/66)
回答No.2

こんにちは。 ・ファンクションプロシージャ Function Fun(x) ・・・ End Function この関数の中で別の関数(Fun2)を使いたい場合は、 Call Fun2(x) で使用出来ます。 よって、関数の途中で定義する必要がありません。 ・Range() Range(A1)*Range(A2)+Range(B1)*Range(B2)+・・・ は、Range("A1", "指定したい最終セル")で良いと思います。 仮に Range("A1", "B2").Select とすると、A1、A2、B1、B2のセルが選択されます。 ・Int() Int()は、型の定義ではありません。小数部を切り捨てる関数です。 文字列を入れてもうまくいくのは、暗黙的に型変換されているだけです。 文字列型から数値型へ型変換する際には、Cint、Cdbl、Clng などの関数を使用してください。

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

関数だけでなく、プロシージャは入れ子にできません。 以下のように別々に記述します。 Function Fun(x) ・・・ X = Fnc2(Y) End Function Function Fun2(x) ・・・ End Function Fnc2を外部で参照させたくない場合はPrivate属性にします。 Private Function Fnc2(X) Cells(Y,X)はRangeオブジェクトの一種です。 Range("A1").Value は Cells(1,1).Value と同じです。 Valueプロパティで値を参照するようにしましょう。 Int()という関数はありますが、double()という関数はありません。 Int()は型定義ではなく、関数です。Dim Z As Int は構文エラーです。 型変換関数にはCLng(Long型に変換)、CDbl(Double型に変換)、などが あります。

関連するQ&A

  • エクセル VBAで関数を定義したけれどもうまくいかない

    以前ここで教えていただいた方法ですが、 セルB1からB100までのいずれかを変更した際に プロシージャが起動する方法として まず VBAで標準モジュールに 関数を定義して Function mykansu(dum As Range) for i=1 to 100 if cells(i,2)=1 then cells(i,6)="yes" next i End Function そしてexcelシートでセルA1に =mykansu(B1:B100) とやれば、B列の変更を加えたらプロシージャが起動する と教えていただきました。 しかし A1に #Value と出たきりでVBAのプロシージャが動かないのはなぜでしょうか。教えてください。

  • EXCEL VBAのRangeプロパティについて

    EXCEL VBAのRangeプロパティについて 下の2つのプログラムで表示されるメッセージは、 プロシージャAは"$B$1" プロシージャBは"$A$1" なのですが、Rangeプロパティはどういう使われ方をしているのでしょうか? お教えくださいませ。 ・プロシージャA Sub test1() Cells(1, 2).Activate MsgBox ActiveCell.Range("A1").Address End Sub ・プロシージャB Sub test2() Cells(1, 2).Activate MsgBox ActiveSheet.Range("A1").Address End Sub

  • Excel2003 VBA Functionの定数に関して教えて下さい

    Excel2003 VBA Functionの定数に関して教えて下さい。 例えば、 Function test(x, y) test = A * x + B * y + C End Function という数式を定義し、プログラム中で使用したいとします。 数式を見て分かる通り、xとyは変数でA, B, Cは定数です。 そして、これらA, B, Cの値を A = Cells(3,5) B = Cells(3,6) C = Cells(3,7) のようにシート上の値を使用したいのですが、 上記のようにプログラム中で宣言してもFunctionの中では値が入っていないものとみなされてしまいます。 この問題の回避のため、、 Function test(x, y) A = Cells(3,5) B = Cells(3,6) C = Cells(3,7) test = A * x + B * y + C End Function のようにFunctionの中に、定数を宣言を入れてしまうか、 Function test(x, y, A, B, C) test = A * x + B * y + C End Function のようにA, B, Cも定数ではなく、変数として扱う方法があります。 しかしながら、一つ目の方法では、こういったFunctionの数が増えてくると、 同じ定数を複数の場所で宣言することになり、後からプログラムを書き直そうとしたときに 極めて不便です。 一方で、2つめの方法では、test(x, y, A, B, C)のように、 一つのFunctionを呼び出すためにごちゃごちゃしてスペースをとり、 後から見たときに見にくくなります。 後、Constとして定義する方法もありますが、 A = Cells(3,5) のように、シート上のデータを代入する方法をとりたいと考えています。 上記以外の方法以外でもっとスマートな方法がありましたら 教えて頂けますでしょうか?

  • Excel VBA ユーザー定義関数をイベントマクロで使用する

    Excel VBA ユーザー定義関数をイベントマクロで使用する Excel2003を使用しています。 あるセルと同色に塗りつぶされたセルの値を合計したく、下記1のユーザー定義関数を作成しました。 このユーザー定義関数を下記2のイベントプロシージャ内で呼び出して使用したいのですが、可能でしょうか? 可能であれば、どのようにコードを書いたらいいでしょうか? Call を使用するのかな?と思い、コードを追加してみましたが、引数の型が一致しないといった内容のエラーメッセージが表示されてしまいました。 よろしくお願いします。 ------------------------------------------------------------- 1.ユーザー定義関数(同色セルの合計) Function SumColor(hanni As Range, iro As Range) As Double   Dim myrng As Range   SumColor = 0    For Each myrng In hanni     If myrng.Interior.ColorIndex = iro.Interior.ColorIndex Then      SumColor = SumColor + myrng.Value     End If    Next myrng End Function 2.イベントマクロ(C列3行目以下ダブルクリックで塗りつぶし) Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)   If Target.Column = 3 And Target.Row >= 34 Then    Range(Cells(Target.Row, 3), Cells(Target.Row + 1, 38)).Interior.ColorIndex = 36   End If End Sub

  • VBA上で定義された関数のワークシート上での実行

    Ecxel2003 のマクロ上で、複素数の構造体を以下のように定義しました。 Public Type Complex R As Double I As Double End Type 2つの実数(引数)を複素数に変換する関数を、以下のように定義しました。 Public Function setComplex(x As Double, y As Double) As Complex setComplex.R = x setComplex.I = y End Function 複素数の絶対値を計算する関数を以下のように定義しました。 Public Function absComplex(A As Complex) As Double absComplex = Sqr(A.R * A.R + A.I * A.I) End Function これらの定義式を用いて、ワークシート上の数値を参照して 計算しようとしても、なぜかうまくいくません。 うまくいかない例 → =absComplex(setComplex(B6,C6)) (セル"B6"には 2 、セル"C6"には 3 が格納済み) マクロ上で計算する場合はうまくいきます。 Public Function test() As Double Dim varC1 As Complex varC1 = setComplex(2, 3) test = absComplex(varC1) End Function 適当なセル上で、=test() と打ち込むと、√13に相当する少数が表示されます。 なぜ、=absComplex(setComplex(B6,C6)) では計算してくれないのでしょうか?。 そもそも、マクロ上で定義した構造体を、セル上で用いようとするのがいけないのでしょうか? どなたか、ご教授願います。

  • エクセルVBAのFunctionプロシージャの質問

    エクセルのFunctionプロシージャを使って以下のユーザー定義関数を作りたいのですが上手くいきません。 アドバイスお願いしますm(__)m やりたいこと エクセルのA列とB列に複数の(たとえば10行の)数字が並んでいます。 各行ごとに 0.5×[A列の値]×[B列の値の二乗] を算出し、その合計を求めたいです。 別の列(例えばC列)を使って上記の計算式を入力し、その合計を求めればよいのですが どうしてもFunctionプロシージャを使って1セルだけを使って求めたいのです。 自分はVBA(エクセルマクロ)はあまり詳しくないのですが 色々ネットで調べた結果、以下のようなプロシージャを書いてみたのですが 上手く計算できません。 Function KE(element As Range) Dim e As Range Dim m() As Variant Dim v() As Variant Dim ans As Integer i = 0 j = 0 For Each e In element If i = j Then m(i) = e.Value i = i + 1 Else m(j) = e.Value j = j + 1 End If Next e k = i i = 0 j = 0 While i < k + 1 ans = ans + 0.5 * m(i) * v(i) * v(i) i = i + 1 Wend KE = ans End Function もちろん、この形に拘りません Functionプロシージャを使ってうまく計算できる方法ありましたらご教示お願いします。

  • Excel : 関数内からセルを更新したい

    実行環境は Excel 2000 です。 新規ブックに、 標準モジュールを追加し、 Function Test()   Cells(2, 2) = "OK"   Test = 2 End Function という関数を追加します。 Sheet1 の、 セル「A1」に「10」を入れます。 セル「A2」に「=Test() + A1」 セル「A1」を変更すると、 関数「Test()」が呼び出されます。 このとき、コードのように、B2 のセルに「OK」を 表示させたいのですが、 「アプリケーション定義またはオブジェクト定義のエラーです。(1004)」 のエラーが発生してできません。 マクロやボタンなどのイベントプロシージャでは可能なのですが、上記のようにセルに組み込んだ関数が、 更新により実行された場合はできないのでしょうか? (Cells の指定を Workbooks(1).Worksheets(1).Cells(2, 2) としてもダメでした) (「書式」→「セル」→「保護」→「ロック」はチェックされていません) すみませんが、よろしくお願い致します。

  • VBAについて質問です。

    VBAについて質問です。 まとまったデータがあるところから検索したい月及び各項目のデータを検索し、項目シート事に抽出するという作業を行なっています。そこで問題がでました。6月にはデータはあるが、5月にはデータはない。 そうすると以下のコードの場合デバックが入り、他の検索が出来ません。 どうしたらよいのでしょうか? 分かる方がいらっしゃいましたらどうかお願い致します。 'シートの変更 Range("B30").Select Sheets("東京").Select '●Sheet2書込み行 Sheets("東京").Range("A5").CurrentRegion.Clear Sheets("東京").Range("A5:F5").Value = _ Array("依頼書No.", "受付日日", "担当者", "枚数", "工数", "備考") Row2 = 5 For R = 2 To Sheets("日報").Cells(Rows.Count, "A").End(xlUp).Row If Sheets("東京").Range("A2") = Sheets("日報").Cells(R, "A") And _ Sheets("東京").Range("B2") = Month(Sheets("日報").Cells(R, "C")) Then Row2 = Row2 + 1 Sheets("東京").Cells(Row2, "A") = Sheets("日報").Cells(R, "B") Sheets("東京").Cells(Row2, "B") = Sheets("日報").Cells(R, "D") Sheets("東京").Cells(Row2, "C") = Sheets("日報").Cells(R, "F") Sheets("東京").Cells(Row2, "D") = Sheets("日報").Cells(R, "I") Sheets("東京").Cells(Row2, "E") = Sheets("日報").Cells(R, "K") Sheets("東京").Cells(Row2, "F") = Sheets("日報").Cells(R, "L") End If Next R '●抽出結果を日付で並べ替え If Row2 = 5 Then MsgBox "該当データなし!" Else Sheets("東京").Range("A5:F" & Row2).Sort _ Key1:=Range("B6"), Order1:=xlAscending, _ Header:=xlYes, OrderCustom:=1, MatchCase:=False, _ Orientation:=xlTopToBottom, SortMethod:=xlPinYin End If Sheets("東京").Select Range("B5:B200").Select Selection.NumberFormatLocal = "yyyy/m/d"     Rows("5:5").Select With Selection .HorizontalAlignment = xlCenter .VerticalAlignment = xlBottom .WrapText = False .Orientation = 0 .AddIndent = False .ShrinkToFit = False .MergeCells = False End With このあとに式を入れて、罫線を入れてコピーして、というコードが入っています。 どうぞ宜しくお願い致します。

  • エクセルVBAでセル選択するコードが変

    エクセルのワークシートでVBAでセル選択するコードで理解に苦しむことがあります。 通常、Cells(2, 1)はセル番地で言えばA2セル Cells(4, 1)はセル番地で言えばA4セルです。 しかし、 With .Range("B5:B15")でくくれば  .Cells(2, 1)はセル番地で言えばB6セルだと思います。 .Cells(4, 1) はセル番地で言えばB8セルだと思います。 ところが下記のコードを動かすと、なぜかC10:C12が選択されてしまいます。 この理屈がわかりません。 Sub test02()   With Sheets("Sheet1")     With .Range("B5:B15")       .Range(.Cells(2, 1), .Cells(4, 1)).Select     End With   End With End Sub なお、 .Range(.Cells(2, 1), .Cells(4, 1)).Selectを .Range(“A2:A4”).Selectに書きかえると、希望のB6:B8が選択されます。

  • エクセル VBA セル範囲を指定

    functionプロシージャを作ろうとしてます。いわゆるユーザ定義関数です。 エクセルの関数でSUMが用意されており、SUM(セル範囲)のように書けば合計を返します。 同じようにセル範囲の指定を受けて計算結果を返すfunctionを作りたいのです。 function example(セル範囲 As double,・・・) As double 任意の範囲を指定して、その値を使って計算したいのです。 ・セル範囲の書き方というか、フォーマットの書き方 ・プロシージャ内で計算に使うために配列に読み込む方法