• ベストアンサー

VBAで関数をつくる

If文やForNext構文を駆使して階乗、順列、組み合わせの計算を実現する関数を作りたいです。どのように考えてどのようなプログラムを書けばよいか教えてください!

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

  • ベストアンサー
noname#60992
noname#60992
回答No.3

階乗については、 Function Fact(n) as long Fact = 1 for i = 1 to n Fact = Fact * i next i End Function で最低限のものは実現できます。 最低限という意味は、エラーが起きたときの対応ができていないということです。 例えば、負の数を引き渡したときは、1が返されます。 また、171以上の数を引き渡すと、オーバーフローしますし、 longの定義上正確に計算できるのは、17までだと思います。 組み合わせについても、 Function Combi(n,r) as long Combi = Fact(n)/(Fact(r)*Fact(n-r)) End Function で最低限のものは作れますが、やはりFactの制限に引っかかります。 factというファンクションを使わなければ、 ループを使い n(n-1)(n-2)(n-3)・・・(n-r+1)/r! を計算することによって、多少は上限が増えますが、どの時点で正確でなくなるのか、どの時点でオーバーフローするのかなどを検証しておく必要はあります。 それよりも完成度の高いものを目指す場合は、数自体の構造体を自分で作り、それらを演算させるプログラムを組まなくてはいけません。演算する速度は遅くなりますが、VBAで作れないわけではありません。 何にしても、計算の上限値はどこかに設定しておかなくてはいけませんし、上限を越した際のエラー処理の方法を考えておく必要があります。 

mountain3
質問者

お礼

詳しい説明をどうもありがとうございました。おかげで疑問が解決しました!

その他の回答 (2)

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

順列。組み合わせともに公式に、階乗が現れてきます。 階乗は Sub test01() n = 1 For i = 1 To 17 n = n * i Cells(i, "A") = n Next i End Sub のようにすれば計算されますが、エクセルの画面のセルに表示は上記ぐらいが限度です。 ですから用途については、非常に限られています。エクセルは不向きでしょう。 これ以上を考えるなら、数学的アルゴリズムの考察が難しく、この質問振りからでは、そちらの知識のほうが追いつかないのでは。 ーー 質問が漠然としすぎ。 多桁、近似の計算のアルゴリズムなどに習熟しているか まず後者の習得でしょう。 私は知らないが、理系の研究などでは、既成の専門ソフトを使うのでは。 素人が安易に作ると危ない。

noname#77845
noname#77845
回答No.1

まず大事なのは、階乗・順列・組合せの計算を具体的に記述することです。 それが出来れば、後はその考え方をコードにするだけです。 例:(あくまでも一例) Public Sub kaijo() Dim i As Integer Dim j As Long j = 1 For i = Cells(1, 1).Value To 1 Step -1 j = j * i Next i Cells(1, 2).Value = j End Sub これで、A1に入っている数字の階乗の計算結果をB1に表示できます。 見本にもなっていませんが、こういう感じで作っていけばいいかと…。

関連するQ&A

  • 順列組合せの拡張関数

    階乗n!の拡張にガンマ関数がありますが、順列組合せnCrを拡張した関数はあるのでしょうか。

  • 標準関数の中身について

    最近C言語を学びはじめた初心者です。 標準関数にprintfやsinなどいろいろありますがこれらの中身はどうなっているのですか? 例えばprintfを作った人はif文やfor文など関数でないものを駆使して作っていったということなんですか?しかしif文やfor文だけではディスプレイに表示させたり ということはできないですよね? 単なる数値計算というだけならfor文とかを使ってできそうですが、ディスプレイに表示させたりファイルに書き込んだり、とかいう作業はコンピューター内部でどのようにして実行されているのでしょうか?またそういう関数を自分で作るにはどういう知識が必要なんでしょうか? ちょっと馬鹿っぽい質問かもしれませんがよろしくお願いします。

  • やってみてもわからないので教えてください

    組み合わせ(nCm)を計算するプログラムを作成せよ。 ただし、nの階乗を計算する関数factorialと組み合わせを計算する関数combinationを作成し、 関数combinationの中で関数factorialを使用して組み合わせを計算すること。 <実行結果> 組み合わせnCmを計算します。 nとmを入力してください(n>m) n --> 8 m --> 6 異なる8個の整数から6個の整数を取り出す組み合わせは28通りです。

  • IF関数との組み合わせを教えて下さい。

    IF関数との組み合わせを教えて下さい。 エクセルで計算式を組んでいます。 Q3のセルに =ROUND(Q3*1.05,0) と入れています。 この計算の結果が50001になたっときだけ、50000になるようにしたいです。 Q3セルにIF関数を組み合わせればいいのはわかるのですが、どう入れたらいいか教えて下さい! よろしくお願いします。

  • 順列と組み合わせ

     高校1年です。数学Aで教えてほしいことがあります。  数Aの「順列と組み合わせ」という単元があり、そこでは、!(階乗)P(順列)C(組み合わせ)、円順列、じゅず順列、重複順列 等など、いろいろな公式(単語)?が出てきました。 それらの公式は、とりあえず教科書を読んで覚えました。  しかしいざ問題演習になると、どの公式を使えばいいのかがわかりません。  『こんな問題にはこの公式を使う』という見分け方をどなたか教えてください。

  • excel2007 VBA countif関数

    CountIf関数が使えなくて(構文エラーになる)困っています。ワークシートで試した時には、普通に動いていたのですが、、、、A列のデータに重複がないか調べるプログラムで、flag列というのがあって ここに0が入っている行のデータのみ重複をチェックするようにする(途中)です。 矢印で書いた部分がおかしくて、なぜか構文エラーとなります。COUNTIF(A:A,A&i) という風に本当は使いたいのですが ":"で構文エラーになってしまいます。さんざん調べたのですが、私の力では解決できません。将来的にCOUNTIFのカウント数が1>でNGと表示させるつもりです。 よろしくお願いします。 'flagデータ数を配列に代入 For i = 1 To lRow flag_column(i) = Cells(i + 1, flag_column_number).Value '各行の情報を配列に代入 Next i '配列が0の行についてCOUNTIF関数を実行 For i = 1 To lRow If flag_column(i) = 0 Then j = COUNTIF(A1:A10, A & i)  <- ここ Cells(i + 1, 6).Value = j End If Next i

  • 関数をVBAで知りたい

    300ぐらいのセルに関数で計算をしているのですが、時間がかかって仕方ありません。次の関数をVBAに直して頂けませんか 質問1:表示したいセルはRange("AD98")です =IF(AND(COUNT(OFFSET(AC98,1-AD$8,0):AC98)<>AD$8),"",IF(AND(COUNT(OFFSET(AC98,1-AD$8,0):AC98=AD$8,AD97=""),AVERAGE(OFFSET(AC98,1-AD$8,0):AC98),IF(COUNT(AD97=1),AD97+2/(AD$8+1)*(AC98-AD97)))) 質問2:表示したいセルはRange("AC98")です =IF(AND(COUNT(AA98)=1,COUNT(AB98)=1),AA98-AB98,"") よろしくお願いします

  • VBAでDATEDIF関数の埋め込み

    VBAでエクセル関数のDATEDIF関数でJ3から始まりその列の最後に入力された次の空白セルに関数を埋め込みたいのですがうまくいきません、どなたか教えてください。 現在の式は Range("J"&NewDataRow)、Value=,=IF(DATEDIF(E3,Today(),"Y")>80,"大型中止",OK)ですがE3の結果が出ます、列には途中違う計算式も入っていくことになるので入力した行の計算結果がほしいのです。よろしくお願いします

  • 桁あふれ誤差のプログラムで質問です。

    1から15までの階乗を計算するプログラムで、階乗を求める関数を定義してその結果を確認し、その際に階乗の計算を開始する数と終了する数を記号定数で定義(#defineを使って)したいのですが、分からなくて困っています。 関数を使わないで以下のようにやり、 #include <stdio.h> #include <math.h> int main(void) { int n; int ans=1; for(n=1;n<=15;n++) { ans=ans*n; printf("%d!=%d\n",n,ans); } return 0; } これをやってみてなんとか結果が確認できたのですが、上記のように、階乗を求める関数を定義して、この上記のプログラムを書き換えて、そのときに階乗の計算を開始する数と終了する数を記号定数で定義(#defineを使って)して行いたいのですが、 分からなくて本当に困っています。助けてください。

  • 高機能な表計算ソフトを探しています

    5000程度の階乗や順列を使った計算をしたいのですが、 例えば (aPn * bPn) / C! に a,b,C の値を与えて n=1,2...100 でそれぞれ計算して出力する。 EXCELでは、階乗の計算は170程度までしか出来ないので、他にソフトがないか探しています。 お金を出してまで...とは考えていないので、フリーに限ります。 何か、良いものはないでしょうか。よろしくお願い致します。

専門家に質問してみよう