• ベストアンサー

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

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

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

  • ベストアンサー
  • tom11
  • ベストアンサー率53% (134/251)
回答No.15

間違い修正 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 を 削除してください。

WhiteRay
質問者

お礼

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

その他の回答 (17)

  • ka_na_de
  • ベストアンサー率56% (162/286)
回答No.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
WhiteRay
質問者

お礼

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

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

こんにちは。 アドバイスとして、ひとこと書かせていただきます。 VBAの基本的な部分の、まだ、右辺と左辺もわかっていらっしゃらないのに、いきなり、サブルーチンのFunctionプロシージャを作るのは、難しいのではないでしょうか? 経験がある方でも、Functionプロシージャに、多少のためらいを覚えるのも当然で、それは、Excelでは、Functionプロシージャはほとんど使われません。Excelでは、そうした必要性がないからです。 自分の自信や能力と、学習ステップは一致しません。プロの方のアドバイスで、プログラミングの組み立てや文章化するなんていうものは、このレベルでは、まったく関係ないです。たかが、VBAでも、一通りモノになる人は、10人に1人の世界です。だから、掲示板でも、ユーザー層の厚いExcel VBAで、ひとつのボーダーラインを越えた回答者は、一向に増えてきません。それよりも遥かに上の人たちにアドバイスを貰っても、分かるわけがありません。 今は、内容的には、入門レベルなのに、いきなり、VBAの初級編の最終章をやっているような内容です。VBAを一通り終えるまでは、良いお手本を真似るしかありません。段階的に書かれた良いテキストを入手することです。書名は、「Office 系」カテゴリを検索すれば出てきます。Webサイトでは、ひとつのワザは見つけられても、体系的には身につきません。 VBAがいくら易しいとはいっても、基礎的な知識もないままに、自己流なのか、配列やユーザー定義関数を、自力で解こうとするのは、何時間かかっても無理だと思います。Single型、配列変数、サブルーチン、ユーザー定義関数、これらのキーワードが、どの程度の位置にあるものか、体系的に分かっているならよいのですが、コードを見る限りは、まだ、入門編が終わっていないと思います。いくら、どの方が、きちんとしたコードを書いたところで、どう判断してよいか分からないと思います。 ふつう、VBAは、誰が教えるわけでもなく、段階的にやっていればVBE自身が教えてくれるものなのです。しょせん、プログラミング言語だとは言っても、人が作ったものであって、それをひとつずつ段階的に約束事を覚えるしかないのです。成功体験が、次のステップに進めてくれます。 変数やユーザー定義関数(Functionプロシージャは、ユーザー定義関数とは別)は、後回しです。 また、メソッドは何か、プロパティは何か、オブジェクトとは何かなど、テレビを見るために、テレビの構造から勉強し始めること同じことです。そんなことは、最初はどうでも良いことです。 ご質問者さんは、別件のご質問で、プログラミングの考え方から始めようとしていましたが、そういう導入部分から間違っていたと思います。最初は、自分では考えないことです。コードのパターンというものを倣い覚えていきます。そのためには、基本のパターンを何度も何度も自分で書いて実行してみることです。手取り足取り教えてもらっても、物事には覚える段階があるわけで、パラレルで覚えられる人は皆無に近いです。 すでに、何名かの完成されたコードは出ていますが、もし、何か仕事などで使いたいなら、今後も、掲示板できちんとした説明をして、誰かにお任せで作ってもらったほうがよいです。自分で考えても、当分の間届かないです。それと、今回は、特別な要件がなければ、計算過程をユーザー定義関数にする意味はないと思います。

WhiteRay
質問者

お礼

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

  • ka_na_de
  • ベストアンサー率56% (162/286)
回答No.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

  • tom11
  • ベストアンサー率53% (134/251)
回答No.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 このように定義しているので、 シートでもこれは、関数として使えるので 速度のデータ数が少ない時は、直接これを 利用したほうがいいです。

  • myRange
  • ベストアンサー率71% (339/472)
回答No.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とか)を指定するようにしましょう。 また、理解を深めるためにはヘルプが役に立ちますので じっくり眺めてみることをお勧めします。 以上です。  

WhiteRay
質問者

お礼

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

  • ka_na_de
  • ベストアンサー率56% (162/286)
回答No.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と計算されるはずです。

WhiteRay
質問者

お礼

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

  • tom11
  • ベストアンサー率53% (134/251)
回答No.11

勉強なら、いろいろな事に、トライしてください。 まず、sub,functionの作りかただとか、 簡単なところから、はじめたほうが、良いかも知れまね。 インターネットの説明が、少ないなら、 書籍に頼るのも、一つの手かもしれません。 金銭的な問題なら、図書館にも、今は、結構そろっている 地域もありますよ。 足が、丈夫なら、立ち読みとかもあります。 自分にあった、情報を見つけると、結構飲み込みは 早いかも!!! GOO教えてでは、ホームページの情報とか、書籍のような 詳細な、情報を得るには、向かないかも??? 時間がないというと、困りますが。

WhiteRay
質問者

補足

度々すいません、修正してみました。 後は回答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+が一番多かったですね

  • nag0720
  • ベストアンサー率58% (1093/1860)
回答No.10

#6です。 結果が表示されないのは、tom11さんが#7で指摘されているとおり、 Cells(1 + i, 2) = kekka としなければなりません。 「セルの参照は関数の中では行わないほうが望ましい」と書いたのは、 そうしなければダメということではなく、きれいなコードを書くためにそうしたほうが望ましいというだけの意味ですので、分からなければ今のところは無視してもかまいません。 関数の中でセルを参照するなら、関数の引数にUを含む必要はありません。(#8での指摘どおり) 当然関数の呼び出し側もUは不要です。 (Uがあってもエラーにはならないですが、無意味です) >スタック領域が不足してますと出たので >nag0720さんのプログラムを参考にして出来るだけ短くしようと思ったのですが スタック領域不足エラーは、コードが長いのが原因ではなく、別の原因です。 例えば、関数の中でその関数名を参照している場合などに発生します。 大抵はプログラムミスですので原因を調べて修正する必要があります。 たまに、エラーのあるプログラムを何回も実行しているとそのようなエラーが出る場合もありますが、その場合はExcelを再起動すれば解消します。

WhiteRay
質問者

補足

あれ? 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

  • tom11
  • ベストアンサー率53% (134/251)
回答No.9

追伸、何がやりたいのかわからなかったので、 文法だけの注意です。 ちなみの、もしかして、コピーペー族ですか???

WhiteRay
質問者

お礼

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

  • tom11
  • ベストアンサー率53% (134/251)
回答No.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 こうかな??? ここまで、基礎がないと、勉強なら良いですが、 実務では危険すぎます。