• 締切済み

VBAでユーザー定義関数作りにチャレンジしてます。

DATEDIF関数をなんとかユーザー定義関数に組み込んでみようと思い、VBAをはじめてみました。 標準モジュールでFunctionを使って書くところまでは何とかたどり着いたのですが、 DATEDIF自体の計算についてどうやって場合わけしていったらいいのか悩み始めてしまいました。 DATEDIF(開始日,終了日,単位)とした場合、 単位="D"もしくは"d"ならば、(開始日-終了日)/ 1 と、適当ではありながらも考えてみました。 そこからが問題で、月数、年数を数えるときに日付の違う月数をどうやって数えるのか、とか、うるう年の計算をどうしたらよいのかとか。。。 単にシリアル値を取り出して割るだけじゃだめですよね? 検索でユーザー定義関数についても、DATEDIF関数自体に関してもしてみたのですが、どうしても理解に苦しんでいます。 直接の答えでなくてもいいので、関連サイトや関連書籍でいいものがあったら教えてください。 本当は本は人に言われて買うものではないと思っているのですが、自分の踏み込んだことのない分野なのでちょっと手のつけようがなくて困っています。。。 どうかお願いします。

  • eub55
  • お礼率89% (103/115)

みんなの回答

  • Nac
  • ベストアンサー率63% (7/11)
回答No.2

補足ありがとうございます。 標準で用意されている関数をわざわざ自作して使用する ということにまだちょっと納得いかないんですけど、 この先オリジナルの関数を作成したいための勉強で作成されている と解釈しました。 とりあえず例です。 Function datedif2(dt1 As Date, dt2 As Date, tp As String) '2つの日付の差を求める関数 datedif2(日付1,日付2,記号) '記号の説明 ' "d":日差を求めます ' "m":月差を求めます ' "y":年差を求めます '変数の宣言 Dim tp_cv As String Dim dt1_cv As Long Dim dt2_cv As Long '引数の変換 tp_cv = StrConv(tp, vbLowerCase) '記号を小文字に変換 dt1_cv = CLng(dt1) '日付1のシリアル値 dt2_cv = CLng(dt2) '日付2のシリアル値 '計算処理 Select Case tp_cv '記号によって処理分岐 Case "d" '日差の場合 datedif2 = tm2_cv - tm1_cv 'シリアル値の差をだして日数を計算 Case "m" '月差の場合 ... '省略 Case "y" '年差の場合 ... '省略 Case Else 'エラー処理 datedif2 = Null End Select End Function *各関数などの詳細はHELPを参照してください。  HELPは読みにくいかもしれませんが、関連を追ってじっくり読みこみ、  使用例を参考にして理解していくと非常に強力な武器になります。 条件が多岐にわたる場合はIF文よりもSELECT CASEを使う方がすっきりします。 月差と年差に関しては単純に2000/12/31と2001/01/01の差が 1年または1月と計算してもよいのならばFormat関数などで 年と月を分離してそれぞれ計算すればいいかと思います。 上記の例で年差を出すなら2001-2000、 月差を出すなら(2001-2000)*12+1-12 という具合に計算できます。 トライアンドエラーの繰り返しになると思いますけど、 失敗に負けないで頑張ってくださいね!

eub55
質問者

お礼

ありがとうございます! 確かに、もともと存在する関数なので、わざわざ作る必要もないのですけれど、 勉強しようと思ったきっかけがDATEDIF関数だったので、そこから始めてみることにしました。 いきなり難しいのに手をつけすぎかもしれませんが、やっていく中で 抑えなきゃいけない基本的なことももちろん勉強していくつもりなので、 また、何かあったらよろしくお願いします。 まずはいろいろやってみないとですね!!

  • Nac
  • ベストアンサー率63% (7/11)
回答No.1

すみません、回答ではありません。 いくつか確認したいことがあります。 VBAを・・とありますが、これはACCESSのVBAですか?EXCELの?WORDの? 確かにEXCELにはDATEDIF関数があります。 知りたいのはこの関数のアルゴリズムですか? そうではなくてACCESSでEXCELのDATEDIF関数と同等のことがしたいということですか? というのであればDateDiff関数があります。 年、月、日だけでなく週、時間、分、秒の差もとれます。 見当違いのことを言ってるのであれば申し訳ないです。

eub55
質問者

補足

ごめんなさい。本当に初心者なもので、質問の仕方も心得ていませんでした。 EXCELのVBAで、ワークシート関数にユーザー定義関数としてDATEDIFを組み込んでみたいのです。 DATEDIF関数も普通に入力して使ってはいるので、使い方自体は理解してるのですが、自分で作るときにいったいどこから手をつければいいのか、場合わけに悩んでいます。 単位に入力された値によっては返す値を買えるということはIFで分けるわけですよね? それをどこからやっていくかで今とまっているところのです。 これで質問の内容がおわかりいただけたでしょうか? よかったら、またアドバイス下さい。

関連するQ&A

  • エクセルのユーザー定義関数で(VBA)

    エクセルのVBAで、セルに「=SheetName」と書き込めば、その関数を書き込んだセルが属するシート名をセルに代入さるようなユーザー定義関数を作りたいと考えています。 で、標準モジュールに Public Function SheetName(test) SheetName = ????? End Function と、書き込んでふと止まりました。 ユーザー定義関数を書き込んだシートの名前ってどうやって取得すればいいのでしょうか?VBでいうSenderみたいなのってあるんでしょうか? どなたか?詳しい方教えて頂けないでしょうか? 宜しくお願いいたします。

  • クラスの関数へユーザー定義型の引数を渡す(VB6.0)

    お世話になります。 クラスモジュール内へ宣言した関数へユーザー定義型(標準モジュール内でPublicで宣言)の引数を渡すとコンパイルエラーとなってしまいます。 ユーザー定義型を宣言した以外の標準モジュールでは同じ関数は動きますが、Formモジュールでは動きません。 標準モジュールにしかユーザー定義型の引数を渡すことは出来ないのでしょうか??

  • VBAユーザー関数を外部から制御

    ExcelのVBAで、標準モジュールにワークシートで使うユーザー関数を記述しています。 ユーザー関数は、使い勝手を組み込みのワークシート関数と同様にするため、 Application.Volatile (True) で自動再計算するようにしており、数百カ所以上のセルに使用しています。 しかし、他のVBAモジュールでユーザー関数の戻り値が変わるような操作をすると、その都度 数百か所以上が再計算されるため、非常に時間がかかります。 ユーザー関数のApplication.Volatile (False) にすると瞬間で終了する処理が、数分かかる場合も あります。 他のVBAモジュールから、一時的にユーザー関数の処理内容を変更するようなことは可能でしょうか。

  • VBAで書いたExcelユーザー定義関数が上手く動きません

    WinXPSP2 Office2003 を使用しています。 プログラムは、本やネットで調べただけの素人です。 具体的には、大量のascファイルにファイル自身の情報をヘッダとして書き込む作業をします。 そのために、ファイルの情報などを返すユーザー定義関数を作り、それを用いた一連の書き込み作業をマクロにして保存し、アドイン化してしまおうと考えました。 作業をマクロにしてアドイン化することはできるようになりましたが、肝心のユーザー定義関数を作るVBAが良くわかりません。 たとえば以下のように、ファイルの作成日時を返すユーザー定義関数を書いて標準モジュールに張ってみたのですが、上手く動きませんでした(具体的には”#VALUE!”になる)。 Function CreationDate() CreationDate = ActiveWorkbook.BuiltinDocumentProperties("Creation Date").Value End Function 次の、ファイルの名前を返すユーザー定義関数は上手く動きました。 Function FileName() As String FileName = Application.ActiveWorkbook.Name End Function なぜ後者が動いて前者が動かないのか、よく理解できません。 どのように変えればよいのか、教えていただけないでしょうか? よろしくお願いします。

  • Excel2003 ユーザー定義関数

    お世話になります。 ユーザー定義関数について教えて下さい。バージョンはExcel2003です。 B268セルの数式をコピーしてB259~B281までその数式を貼り付けるような使い方をしたいのですが、ユーザー関数は関数の中身を変更しても再計算しないとのことで再計算されません。 セルひとつひとつに貼り付けを行っていくと再計算されましたが、さらに広範囲に一気にユーザー関数を使用した数式を貼り付ける使い方で、再計算させる方法はありますでしょうか。 よろしくお願いします。

  • ユーザー定義関数の作成

    1) 基準年の値をP0,t年後の値をPtとした場合の年あたりの伸び率rは、               1/t      r = (Pt/P0)  - 1  で計算されます。 これを計算するユーザー定義関数のVBAを教えてください。 2) 1からnまでの逆数の和  1+1/2+1/3+・・・+1/n=Σ1/i を計算するユーザー定義関数のVBAを教えてください。

  • ユーザー定義関数の使用法

    公開されたサイトですばらしいユーザー定義のマクロを見つけました。 ワークシート関数Datedifのバグを解決するものです。 しかし、残念ながら書いてある説明だけでは使い方がわからないのです。 ご教示いただければ幸いです。 これです。↓Public Function ktDATEDIF http://www.h3.dion.ne.jp/~sakatsu/Excel_Tips05.htm

  • 複素数関数のユーザー定義方法等をお教えください

    カテゴリーにVBAがありませんでしたので VBに投稿させていただきます。 EXCEL2000VBAで複素数関数や三角関数等を用いて 加速度波形処理の勉強をしています。 過去のQ&Aで VBAアドインの複素数関数を用いた場合の 計算時間の長さを短縮する方法としまして (1)ユーザー定義で複素数関数計算を作成する。 (2)モジュールに直接書込む。 との記述がありました。(質問番号:81639) 上記(1)(2)につきまして詳しくお教えください。 自作のVBAにどのようにして上記(1)(2)を 作成又は書込みすれば良いのかがわかりません。 複素数関数計算のFUNCTION?等も お教えいただけましたら幸いです。 宜しくお願いします。

  • エクセル関数で期間を求める方法について

    エクセル関数で期間を何年何ヶ月と1個のセルに求める方法が過去の質問の回答で A1にスタート(開始日) B1にエンド(終了日) C1セルに =DATEDIF(A1,B1,"Y")&"年" & DATEDIF(A1,B1,"YM") & "月" カレンダの応答日主義で1ヶ月を数える計算がありました。 これとは別に何年何ヶ月の月計算を属した日から属した日までの月数 (例)開始日2005年3月31日~終了日2005年4月1日の場合2ヶ月で計算させる方法を A1にスタート(開始日) B1にエンド(終了日) C1セルに 何と入れたら良いかどなたか教えてください。

  • DATEDIF関数

    少し前にもDATEDIF関数の事で質問を出したのですが、 その作業中のことです。 開始日から終了日までの、期間月数を出すため、 =DATEDIF(N40-DAY(N40),DATE(YEAR(N41),MONTH(N41)+1,0),"M") という数式を入れています。 (N40が開始年月・N41が終了年月です) 年月のみの入力なので、開始年月は日を相殺し、終了年月はその月末を出すようにしてます。 で、大抵の値では上手くいくのですが、 開始年月 2000/9 終了年月 2004/4 の時だけ上手くいきません。 本当は「44」という値が欲しいのに、「43」になります。 どうやら終了年月が絡んでいるっぽいのですが、何が悪いのかが分かりません。 分かる方がいらっしゃったら教えて下さい。