こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

functionを含んだプログラムを作成したいのですが、上手くいきません

functionを含んだ計算をプロシージャで行い、返すプログラムを作りたいのですが上手くいきません。
具体的には
ある式に定められた値を代入(inputではなくEXCEL上に指定済み)し、
その定数の横にそれぞれ出力されるプログラムです。
function 内でforを用いた式を作成し、メインプログラムに出力する段階で、『引数は省略できません』と表示され起動することがありません。
一体なぜでしょうか? プログラムが間違っているだけでしょうが、治せません。

投稿日時 - 2009-12-19 19:46:57

QNo.5534116

すぐに回答ほしいです

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

間違い修正

Public Sub f()

Dim kekka As Single, i As Single, u As Single

For i = 1 To 10

u = 10 * i

Cells(i + 1, 1) = u

kekka = kyouryoku2(u)

Cells(1 + i, 2) = kekka

Next i
End Sub

Function kyouryoku2(u As Single) As Single

u = (u * 1000 / 3600) 'U(km/h)をU(m/s)にする

kyouryoku2 = 1.5 * 2 * u ^ 2

End Function

Dim u As Single を 削除してください。

投稿日時 - 2009-12-20 18:09:42

お礼

回答ありがとうございます。
自分は計算上混乱することが多いので
文字は全部singleにしてます。

投稿日時 - 2009-12-22 03:14:13

ANo.15

このQ&Aは役に立ちましたか?

9人が「このQ&Aが役に立った」と投票しています

回答(18)

ANo.18

おはようございます。

もうご覧になっていないかも知れませんが、
いくつかアドバイスさせていただきます。

>自分は計算上混乱することが多いので
>文字は全部singleにしてます。

変数の型について、理解不足を認識されているようですが、
目的別にきちんと宣言しておくことをお勧めします。
そうすることで、予期せぬプログラムミスで意図しない値が
変数に代入されようとした場合にエラーが発生して間違いに
気づくことができます。

私はカウンタ変数iをSingle型で宣言する事に大きな違和感を感じます。
行数が32767を超えてもオーバーフローしないようにLong型としました。


私がSingleをDobleに変えた理由は、特に科学技術計算をする場合には、
計算過程で起こりうるオーバーフローを心配するからです。

今回のケースでは不要でも、今後計算を複雑に繰り返す過程で、
オーバーフローは必ず意識したほうが良い問題です。
オーバーフローは、計算結果ではなく計算過程で起こること多いです。

VBAではオーバーフローはエラーで教えてくれるようですが、
他の言語ではエラーにならず予期せぬ計算をすることがあります。


それから、Functionなどのサブルーチンを利用する際は、
メインからサブへ変数(引数)を渡すことになります。
この時の渡し方には、参照渡し(ByRef)と値渡し(ByVal)があります。
省略した場合は、参照渡し(ByRef)となります。
参照渡しでは、サブルーチンの中で引数を書き換えた場合に、
メイン側でもその変更が反映します。
ここを理解したうえで省略する必要があります。


それから、省略といえば、セルの値を
例えば Cells(1,1) のように記述されていますが、
これは、 Cells(1,1).Valueを省略した記述です。
理解した上で省略してください。


最後に、VBAではVBA自身が「変数の型変換」をある程度自動でやってくれます。
これは、便利な機能なのですが、注意をしておいたほうが良い
ところです。
私のコードでは、Long型で宣言したiを10倍したものをセルに代入
していますが、このセルの値はVBAが自動的にDoble型に変更しています

余談ですが
 例えば、
 MsgBox TypeName(変数)
 で変数の型を確認できます。


長々と書きましたが、基本文法を理解するために
最適な参考書を購入されることをお勧めします。

以下、参考URLを示します。

参考URL:http://oshiete1.goo.ne.jp/qa5302737.html

投稿日時 - 2009-12-23 08:37:50

お礼

>例えば Cells(1,1) のように記述されていますが、
>これは、 Cells(1,1).Valueを省略した記述です。
知らなかった…VBA value で検索しても大したこと書いてないから
そういえばエクセル計算でも計算値同士の計算で
計算値自体を変えると連動した値が変わりますね
回答ありがとうございました。

投稿日時 - 2009-12-25 17:09:23

ANo.17

こんにちは。

アドバイスとして、ひとこと書かせていただきます。

VBAの基本的な部分の、まだ、右辺と左辺もわかっていらっしゃらないのに、いきなり、サブルーチンのFunctionプロシージャを作るのは、難しいのではないでしょうか?

経験がある方でも、Functionプロシージャに、多少のためらいを覚えるのも当然で、それは、Excelでは、Functionプロシージャはほとんど使われません。Excelでは、そうした必要性がないからです。

自分の自信や能力と、学習ステップは一致しません。プロの方のアドバイスで、プログラミングの組み立てや文章化するなんていうものは、このレベルでは、まったく関係ないです。たかが、VBAでも、一通りモノになる人は、10人に1人の世界です。だから、掲示板でも、ユーザー層の厚いExcel VBAで、ひとつのボーダーラインを越えた回答者は、一向に増えてきません。それよりも遥かに上の人たちにアドバイスを貰っても、分かるわけがありません。

今は、内容的には、入門レベルなのに、いきなり、VBAの初級編の最終章をやっているような内容です。VBAを一通り終えるまでは、良いお手本を真似るしかありません。段階的に書かれた良いテキストを入手することです。書名は、「Office 系」カテゴリを検索すれば出てきます。Webサイトでは、ひとつのワザは見つけられても、体系的には身につきません。

VBAがいくら易しいとはいっても、基礎的な知識もないままに、自己流なのか、配列やユーザー定義関数を、自力で解こうとするのは、何時間かかっても無理だと思います。Single型、配列変数、サブルーチン、ユーザー定義関数、これらのキーワードが、どの程度の位置にあるものか、体系的に分かっているならよいのですが、コードを見る限りは、まだ、入門編が終わっていないと思います。いくら、どの方が、きちんとしたコードを書いたところで、どう判断してよいか分からないと思います。

ふつう、VBAは、誰が教えるわけでもなく、段階的にやっていればVBE自身が教えてくれるものなのです。しょせん、プログラミング言語だとは言っても、人が作ったものであって、それをひとつずつ段階的に約束事を覚えるしかないのです。成功体験が、次のステップに進めてくれます。

変数やユーザー定義関数(Functionプロシージャは、ユーザー定義関数とは別)は、後回しです。
また、メソッドは何か、プロパティは何か、オブジェクトとは何かなど、テレビを見るために、テレビの構造から勉強し始めること同じことです。そんなことは、最初はどうでも良いことです。

ご質問者さんは、別件のご質問で、プログラミングの考え方から始めようとしていましたが、そういう導入部分から間違っていたと思います。最初は、自分では考えないことです。コードのパターンというものを倣い覚えていきます。そのためには、基本のパターンを何度も何度も自分で書いて実行してみることです。手取り足取り教えてもらっても、物事には覚える段階があるわけで、パラレルで覚えられる人は皆無に近いです。

すでに、何名かの完成されたコードは出ていますが、もし、何か仕事などで使いたいなら、今後も、掲示板できちんとした説明をして、誰かにお任せで作ってもらったほうがよいです。自分で考えても、当分の間届かないです。それと、今回は、特別な要件がなければ、計算過程をユーザー定義関数にする意味はないと思います。

投稿日時 - 2009-12-21 11:32:05

お礼

回答ありがとうございます
自分は暗記と思考の内で暗記の方が問題あるようです
とりあえず今は覚える段階ということで

投稿日時 - 2009-12-25 16:30:32

ANo.16

#12です。

いろいろな方からのアドバイスを受けて
混乱しているかもしれませんね。

さきほどの関数の内容は不十分だったようです。
訂正しておきます。

Sub sss()
  Dim i As Long

  For i = 1 To 10
    Cells(i + 1, "A").Value = 10 * i
    Cells(i + 1, "B").Value = kyouryoku2(Cells(i + 1, "A").Value)
  Next i
  
End Sub

Function kyouryoku2(myArg As Double) As Double
  Dim U As Double
  
  U = myArg * 1000 / 3600
  kyouryoku2 = 1.5 * 2 * U ^ 2
  
End Function

投稿日時 - 2009-12-20 18:13:09

ANo.14

Public Sub f()

Dim kekka As Single, i As Single, u As Single

For i = 1 To 10

u = 10 * i

Cells(i + 1, 1) = u

kekka = kyouryoku2(u)

Cells(1 + i, 2) = kekka

Next i
End Sub

Function kyouryoku2(u As Single) As Single

Dim u As Single

u = (u * 1000 / 3600) 'U(km/h)をU(m/s)にする

kyouryoku2 = 1.5 * 2 * u ^ 2

End Function

何かの技術計算ですか???
私だったら、上記の様に、書き直します。

因みに、Singleより、Doubleを使った方がいいかも
昔のパソコンは、処理能力が、低いので
倍精度は、使わない場合があったのですが、
今は、皆、倍精度を利用しますよ。

Function kyouryoku2(u As Single) As Single

このように定義しているので、
シートでもこれは、関数として使えるので
速度のデータ数が少ない時は、直接これを
利用したほうがいいです。

投稿日時 - 2009-12-20 17:55:02

ANo.13

簡単なコードでも慣れるまでは、なかなかでしょう。


質問者のコード

>Sub sss()
>Dim kekka As Single, i As Single, U As Single
>For i = 1 To 10
>Cells(i + 1, 1) = 10 * i
>kekka = kyouryoku2(i, U)  ●●●
>Cells(1 + i, 2) = kekka

 
●のkouryouku2(i,U) の引数Uにはその前に何も代入されてませんよね。
(実際には初期値、0.0が入っている)
ですから、この"U"は何ら意味を持たないことになります。

もちろん、kouryoku2で変数の宣言をしないで
このUを変数として使うためであれば別ですが、
普通そういうことはしません。

で、今回のは、引数Uは外して、
kouryoku2(i) のように、i だけ十分でしょう。

質問者のコードをなるべく残してやると。。

'----------------------------------
Sub SSS()
  Dim i As Long
  For i = 1 To 10
    Cells(i + 1, 1) = 10 * i
    Cells(1 + i, 2) = Kyouryoku2(i)
  Next i
End Sub
'--------------------------------
Function Kyouryoku2(i)
  Dim U As Double
  U = (i * Cells((i + 1), 1) * 1000 / 3600)
  Kyouryoku2 = 1.5 * 2 * U ^ 2
End Function
'--------------------------------

それから、慣れたら引数の型(As Doubleとか)を指定するようにしましょう。

また、理解を深めるためにはヘルプが役に立ちますので
じっくり眺めてみることをお勧めします。
以上です。
 

投稿日時 - 2009-12-20 17:29:48

お礼

回答ありがとうございます。
他の文法もあるでしょうし、ヘルプ見てみます

投稿日時 - 2009-12-22 03:12:32

ANo.12

こんにちは。

やりたいことは、
あるデータに対して、* 1000 / 3600 の計算をさせる。
ということですよね。

だとしたら、kyouryoku2という関数(Function)は、
  受け取ったデータに  * 1000 / 3600という計算をして
それを返すという単純な処理にすべきです。

例えば、
Function kyouryoku2(myArg As Double) As Double
  kyouryoku2 = myArg * 1000 / 3600
End Function
となります。

myArgという変数(引数)で受け取った数値に対して
* 1000 / 3600をして、kyouryoku2に代入するだけです。

そしてメインのプロシージャーは、例えば以下のようになります。

Sub sss()
  Dim i As Long

  For i = 1 To 10
    Cells(i + 1, "A").Value = 10 * i
    Cells(i + 1, "B").Value = kyouryoku2(Cells(i + 1, "A").Value)
  Next i

End Sub


ちなみに、
C2セルに10と入力し、
D2セルに=kyouryoku2(C2)
と入力すれば、2.7777と計算されるはずです。

投稿日時 - 2009-12-20 17:13:30

お礼

回答ありがとうございます。

投稿日時 - 2009-12-22 02:14:18

ANo.11

勉強なら、いろいろな事に、トライしてください。

まず、sub,functionの作りかただとか、
簡単なところから、はじめたほうが、良いかも知れまね。

インターネットの説明が、少ないなら、
書籍に頼るのも、一つの手かもしれません。

金銭的な問題なら、図書館にも、今は、結構そろっている
地域もありますよ。

足が、丈夫なら、立ち読みとかもあります。

自分にあった、情報を見つけると、結構飲み込みは
早いかも!!!

GOO教えてでは、ホームページの情報とか、書籍のような
詳細な、情報を得るには、向かないかも???

時間がないというと、困りますが。

投稿日時 - 2009-12-20 14:29:24

補足

度々すいません、修正してみました。
後は回答No8についてわからないところが―
Function kyouryoku2(i As Single) As Single これだとプログラムとして成立できません。
kyouryoku=function(U)ですが、U自体がiの関数であるため、i、U両方指定する必要があるのだと思いますが。

Sub sss()
Dim kekka As Single, i As Single, U As Single
For i = 1 To 10

Cells(i + 1, 1) = 10 * i
kekka = kyouryoku2(i, U)
Cells(1 + i, 2) = kekka
Next i
End Sub

Function kyouryoku2(i As Single, U As Single) As Single
U = (Cells((i + 1), 1) * 1000 / 3600) 'U(km/h)をU(m/s)にするkyouryoku2 =1.5 *2* U ^ 2
End Function

今は図書館で借りていますが、基礎は基礎であるが故にあまり細かく書いていませんでした
単に自分の理解力が不足しているのでしょうが
VBA自体のプログラムの本は少なく、C+が一番多かったですね

投稿日時 - 2009-12-20 15:31:54

ANo.10

#6です。

結果が表示されないのは、tom11さんが#7で指摘されているとおり、
Cells(1 + i, 2) = kekka
としなければなりません。


「セルの参照は関数の中では行わないほうが望ましい」と書いたのは、
そうしなければダメということではなく、きれいなコードを書くためにそうしたほうが望ましいというだけの意味ですので、分からなければ今のところは無視してもかまいません。

関数の中でセルを参照するなら、関数の引数にUを含む必要はありません。(#8での指摘どおり)
当然関数の呼び出し側もUは不要です。
(Uがあってもエラーにはならないですが、無意味です)


>スタック領域が不足してますと出たので
>nag0720さんのプログラムを参考にして出来るだけ短くしようと思ったのですが

スタック領域不足エラーは、コードが長いのが原因ではなく、別の原因です。
例えば、関数の中でその関数名を参照している場合などに発生します。
大抵はプログラムミスですので原因を調べて修正する必要があります。
たまに、エラーのあるプログラムを何回も実行しているとそのようなエラーが出る場合もありますが、その場合はExcelを再起動すれば解消します。

投稿日時 - 2009-12-20 10:26:42

補足

あれ? Uを外したら関数として成立しないのですが。
iを含んだUから値を求める関数で、Uを求めるのではありませんので。
Uを外すとfunction()が求まらなくなりますが…

何とかプログラムとして成立しました…が、tom11さんの
Function kyouryoku2(i As Single) As Single
この文がよくわかりません。上の通り、functionがiの関数ならそれでいいのでしょうが、今回は『iを含んだUの関数』であるため、求める値自体が違ってくるのですが。どちらかを抜くと『変数が定義されていません』とエラーが出てしまいます。

正直言うと、間違えすぎて自分の作ったプログラムが正しい筈がないって前提でプログラム作ってます



Sub sss()
Dim kekka As Single, i As Single, U As Single
For i = 1 To 10

Cells(i + 1, 1) = 10 * i
kekka = kyouryoku2(i, U)
Cells(1 + i, 2) = kekka
Next i
End Sub

Function kyouryoku2(i As Single, U As Single) As Single
U = (Cells((i + 1), 1) * 1000 / 3600) 'U(km/h)をU(m/s)にするkyouryoku2 =1.5 *2* U ^ 2
End Function

投稿日時 - 2009-12-20 14:34:28

ANo.9

追伸、何がやりたいのかわからなかったので、

文法だけの注意です。

ちなみの、もしかして、コピーペー族ですか???

投稿日時 - 2009-12-20 08:47:46

お礼

一応は勉強です。ただ、もうすでにこのプログラムに40時間以上費やしても出来ないので半ば諦めモードです…死んだ方がいいかもしれない。
肉体的にも精神的にも時間的にもアウト

投稿日時 - 2009-12-20 13:14:43

ANo.8

よく見ると、

>Function kyouryoku2(U As Single, i As Single) As Single
>U = (i * Cells((i + 1), 1) * 1000 / 3600)
>kyouryoku2 =1.5* 2*U ^ 2
>End Function

これもめちゃくちゃですね。

Function kyouryoku2(i As Single) As Single

こうかな???

ここまで、基礎がないと、勉強なら良いですが、
実務では危険すぎます。

投稿日時 - 2009-12-20 08:39:07

ANo.7

>kekka = kyouryoku2(U, i)
>kekka = Cells(1 + i, 2)


よく見ていませんが。

Cells(1 + i, 2)= kekka

じゃないですか。

投稿日時 - 2009-12-20 08:31:51

ANo.6

>そもそもfunctionの使用方法を間違えていると自分で思います。

コードを見ましたが、functionの使用方法だけでなく、変数の宣言(Dim)についても理解していないようですね。

>ある式に定められた値を代入(inputではなくEXCEL上に指定済み)し、
>その定数の横にそれぞれ出力されるプログラムです。

計算結果を返す関数にするなら下記のようなコードになります。
(セルの参照は関数の中では行わないほうが望ましいです)

Sub sss()
Dim kekka As Single, U As Single, i As Integer

Cells(2, 1) = 10
・・・(省略)
Cells(11, 1) = 100

For i = 1 To 10
U = Cells(i + 1, 1)
kekka = kyouryoku(i, U)
Cells(i + 1, 2) = kekka
Next i
End Sub

Function kyouryoku(i As Integer, U As Single) As Single
U = i * U * 1000 / 3600
kyouryoku = 1.5 * 2 * U ^ 2
End Function


関数の中でセルの参照や結果の代入を行うなら下記のようなコードになります。
(FunctionではなくSubになります)

Sub sss()
Cells(2, 1) = 10
・・・(省略)
Cells(11, 1) = 100

kyouryoku
End Sub

Sub kyouryoku()
Dim kekka As Single, U As Single

For i = 1 To 10
U = i * Cells(i + 1, 1) * 1000 / 3600
kekka = 1.5 * 2 * U ^ 2
Cells(i + 1, 2) = kekka
Next i
End Sub

投稿日時 - 2009-12-20 03:25:21

補足

function の中には幾つも文字いれてもいいのですか?
また、
<セルの参照は関数の中では行わないほうが望ましいです
これは計算の値を座標で入力してはいけないという意味でしょうか?
スタック領域が不足してますと出たので
nag0720さんのプログラムを参考にして出来るだけ短くしようと思ったのですが


Sub sss()
Dim kekka As Single, U As Single, i As Single
For i = 1 To 10
Cells(i + 1, 1) = 10 * i    
kekka = kyouryoku2(U, i)
kekka = Cells(1 + i, 2)
Next i
End Sub

Function kyouryoku2(U As Single, i As Single) As Single
U = (i * Cells((i + 1), 1) * 1000 / 3600)
kyouryoku2 =1.5* 2*U ^ 2
End Function


上手く表示されません。プログラムの間違いは表示されなかったので、どこかがおかしいのだと思うのですが、どうでしょう?

投稿日時 - 2009-12-20 04:30:24

ANo.5

>functionはどのように用いることができるのか?
Excelがサポートしてないけど自分には必要なWorksheetで使う関数も作ることができます。質問者画学生か社会人化どういう職業かも全く分かりませんので例として適当ではないかもしれませんが
今年度の所得税は課税所得ごとに
195万円以下 課税所得*5%
195万円を超え 330万円以下 課税所得*10%-97,500
330万円を超え 695万円以下 課税所得*20%-427,500
695万円を超え 900万円以下 課税所得*23%-636,000
900万円を超え 1,800万円以下 課税所得*33%-1,536,000
1,800万円超             課税所得*40%-2,796,000
となっています。
ワークシートで所得税を計算する必要があるときこれをIF関数の入れ子またはVllokupなどでで作るのは大変です。そこで「課税所得を受け取って所得税額を返す関数があればな」
それじゃ税額計算という関数を自作することにしましょう。
例えばA1に課税所得が入っていてB1に所得税額を出したければ
B1に=税額計算(A1)
としてマクロに
Function(課税所得 as Currency) as Currency
'課税所得から税額計算する処理 結果を課税所得に入れる
end function
とすることで計算できます。
関数に与える値は複数個与えることができますが基本的に戻るのはひとつのです。
日付関係もExcelは和暦に関してはある程度しかサポートしてくれていないので自分で作ったりします。
他にもいろいろありますがあまり深く説明しても混乱するかもしれないので今日はこの辺で(^^;)

投稿日時 - 2009-12-19 23:22:04

ANo.4

なにをFunctionに渡して何を返すのか分からないので何とも答えようがない。
関数の作り方と使い方の見本としてSum関数もどきとそれを使うSubを書きます。
関数Summodokiは引数として範囲を受け取りその範囲の合計を返します。
Sub 関数Drv()
Cells(11, 1) = Summodoki(Range("A1:A10"))
End Sub
Function Summodoki(範囲 As Range) As Long
Dim r As Range
Dim d As Long
For Each r In 範囲
d = d + r.Value
Next
Summodoki = d
End Function
参考になればいいのですが。

投稿日時 - 2009-12-19 21:04:46

補足

そもそもfunctionの使用方法を間違えていると自分で思います。

functionはどのように用いることができるのか?
プログラミングに関しては初心者もいいところで
実際、RangeやLong,Valueは初めて見ました…

投稿日時 - 2009-12-19 21:41:21

ANo.3

まず functionの終わりは、End Functionになります。
functionは引数に対する値を取得するものなので。
x = funcA(1, 2)
のような使い方になります。
http://www.officepro.jp/excelvba/sub/index6.html

投稿日時 - 2009-12-19 20:24:06

補足

それは、EXCEL座標(1,2)にxを代入するという意味で
合っていますか? 
function の説明はどこも少なくて…

投稿日時 - 2009-12-19 20:40:50

ANo.2

わからんけど
WhiteRayさんが作成されたfunction内で使用している関数で、引数が不足
しているんじゃないですかね。
シングルステップでエラー箇所を特定してアップすれば原因は分かりますよ。
多分ね。

投稿日時 - 2009-12-19 20:00:31

補足

シングルステップとはステップインのことでしょうか?
1度目のそれでコンパイルエラーが…

投稿日時 - 2009-12-19 20:14:52

ANo.1

そのコードが示さないと回答しようがありません

投稿日時 - 2009-12-19 19:56:15

補足

すみませんでした、こんなプログラムです

Sub sss()
Dim kekka As String, D(10) As Single, i As Single

Cells(2, 1) = 10
Cells(3, 1) = 20
Cells(4, 1) = 30
Cells(5, 1) = 40
Cells(6, 1) = 50
Cells(7, 1) = 60
Cells(8, 1) = 70
Cells(9, 1) = 80
Cells(10, 1) = 90
Cells(11, 1) = 100
kekka = kyouryoku
End Sub


Function kyouryoku(D,U) As String, U as single

Dim D(10) As Single

For i = 1 To 10
U = (i * Cells((i + 1), 1) * 1000 / 3600)
D(i) = 1.5 * 2 * U ^ 2
Next i
End Sub


恐らくは一部と言うよりも、プログラムとして成立していないのでしょう。

投稿日時 - 2009-12-19 20:08:22

あなたにオススメの質問