Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


290 / 13645 ツリー ←次へ | 前へ→

【81156】ユーザー定義関数、シート上とコード内のふるまい hoyahoyamachine 20/1/7(火) 11:50 質問[未読]
【81157】Re:ユーザー定義関数、シート上とコード内... γ 20/1/7(火) 20:42 回答[未読]
【81158】Re:ユーザー定義関数、シート上とコード内... γ 20/1/7(火) 21:56 発言[未読]
【81161】Re:ユーザー定義関数、シート上とコード内... hoyahoyamachine 20/1/12(日) 16:06 お礼[未読]
【81159】Re:ユーザー定義関数、シート上とコード内... Jaka 20/1/9(木) 1:47 発言[未読]
【81160】Re:ユーザー定義関数、シート上とコード内... Jaka 20/1/9(木) 3:24 発言[未読]
【81162】Re:ユーザー定義関数、シート上とコード内... hoyahoyamachine 20/1/12(日) 16:13 発言[未読]
【81163】Re:ユーザー定義関数、シート上とコード内... Jaka 20/1/12(日) 22:01 発言[未読]
【81164】Re:ユーザー定義関数、シート上とコード内... hoyahoyamachine 20/1/13(月) 0:02 発言[未読]

【81156】ユーザー定義関数、シート上とコード内の...
質問  hoyahoyamachine  - 20/1/7(火) 11:50 -

引用なし
パスワード
   こんにちは。
初めて質問いたします。

ユーザー定義関数で、シート上での結果とコード内での結果に違算があり、原因がつかみかねています。

マイクロソフトのユーザー定義関数の制限によるといろいろ書いてありますが、
特段プロパティもメッソドも使わず、セル値を変更することもなく、ただ参照しているだけのコードです。具体的には以下の通りです。

ワークシートDB とワークシートHolidayがあり、DBにはテーブルがセットされ、以下のフィールドとデータがあります。

ワークシートDBの一部
PerDay  Quantity  StDate  EnDate
14.4    400   20/1/7  =EnDate([@PerDay],[@Quantity],[@StDate])

ワークシートHoliday、セルA1から下方へセット
Holiday
2020/1/1
2020/1/2
2020/1/3
2020/1/4
2020/1/5
2020/1/12
2020/1/19
2020/1/25
2020/1/26
2020/2/1
2020/2/2
2020/2/9

Function EnDate(ByVal PerDay As Single, Quantity As Single, StDate As Date) As Date
'日産、生産数量、開始日から終了日を休日リストを参照しつつ求める
Dim wsHoliday As Worksheet
Dim ProdDays As Single, d As Date, h As Range
  ProdDays = Quantity / PerDay '生産日数をセット
  Set wsHoliday = Worksheets("Holiday") 'ワークシートのセット
  d = StDate '基点をセット
  Do Until ProdDays <= 0 '生産日数が0以下になればDoLoop終了
    For Each h In wsHoliday.Cells(1, 1).CurrentRegion '休日それぞれについて
      If d = h.Value Then '日付と休日が一致すれば
        ProdDays = ProdDays + 1 '生産日数を一日増やす
      End If
    Next h
    ProdDays = ProdDays - 1 'ループ一回ごとに生産日数を一日減らす
    d = d + 1 '次の日をセット
  Loop
  EnDate = d '終了日を返す
End Function

結果、シート上では2020/2/4、コード実行の結果は2020/2/11 でした。
シート上では休日が加算されていない感じですね。

原因がつかめないので、ChangeイベントでEnDateを実行するようにしたのですが、今後の知見のためにもご教授いただきたくよろしくお願いいたします。

【81157】Re:ユーザー定義関数、シート上とコード...
回答  γ  - 20/1/7(火) 20:42 -

引用なし
パスワード
   Excel のユーザー定義関数の制限について
ht tps://support.microsoft.com/ja-jp/help/170787/description-of-limitations-of-custom-functions-in-excel
には、
>正しい計算を行うには、計算で使用されるすべての範囲を引数として関数に渡す必要があります。
と記載されています。
祝日のテーブルを引数として追加すれば、両者は一致すると思います。

【81158】Re:ユーザー定義関数、シート上とコード...
発言  γ  - 20/1/7(火) 21:56 -

引用なし
パスワード
   For Each h In wsHoliday.Range("A2:A13")と明示的に書いておけば、
引数として渡さなくてもよかったですね、どうも失礼。

【81159】Re:ユーザー定義関数、シート上とコード...
発言  Jaka  - 20/1/9(木) 1:47 -

引用なし
パスワード
   私的な意見ですが、
表がどうなっているのかわからないけど、
CurrentRegion なんか使って大丈夫なのかな?
という事と、

>      If d = h.Value Then '日付と休日が一致すれば
>        ProdDays = ProdDays + 1 '生産日数を一日増やす
>      End If

私なら、この辺↑で、一致しない日付を書き出して確認します。
ひたすら、F8キー押しまくる時もありますけどね。

時折、こんな物を書き足して、途中からF8で確認します。

ct = ct + 1
if ct = 100 then
  a = 0  ←ここにブレークポイント
end if

【81160】Re:ユーザー定義関数、シート上とコード...
発言  Jaka  - 20/1/9(木) 3:24 -

引用なし
パスワード
   >私なら、この辺↑で、一致しない日付を書き出して確認します。

一致するものかも、それでも解らなければ両方。

【81161】Re:ユーザー定義関数、シート上とコード...
お礼  hoyahoyamachine  - 20/1/12(日) 16:06 -

引用なし
パスワード
   ▼γ さん:
>For Each h In wsHoliday.Range("A2:A13")と明示的に書いておけば、
>引数として渡さなくてもよかったですね、どうも失礼。

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

CurrentRegionを使わずに、明示的に書くと確かに正しい答えになりました。
そこで、休日の範囲を引数として、

=wfEnDate([@PerDay],[@Quantity],[@StDate],OFFSET(Holiday!$A$1,0,0,COUNTA(Holiday!$A:$A)-1,1))

で休日の増減に対応できました。

【81162】Re:ユーザー定義関数、シート上とコード...
発言  hoyahoyamachine  - 20/1/12(日) 16:13 -

引用なし
パスワード
   ▼Jaka さん:
>>私なら、この辺↑で、一致しない日付を書き出して確認します。
>
>一致するものかも、それでも解らなければ両方。

ご回答ありがとうございました。
CurrentRegionがどうも怪しかったようで、Yさんのご指摘で解決の方向です。

ユーザー定義関数をワークシート上で使用する場合に[F8]は使えるのでしょうか?

【81163】Re:ユーザー定義関数、シート上とコード...
発言  Jaka  - 20/1/12(日) 22:01 -

引用なし
パスワード
   ▼hoyahoyamachine さん:

>ユーザー定義関数をワークシート上で使用する場合に[F8]は使えるのでしょうか?

Function プロシジャーのコード内にブレークポイントを設けておけば、
数式を書き込んだ時にそこで止まるけど。

でも、Function プロシジャーにする前に、Sub プロシジャーで、まともに動くまで確認します。

【81164】Re:ユーザー定義関数、シート上とコード...
発言  hoyahoyamachine  - 20/1/13(月) 0:02 -

引用なし
パスワード
   ▼Jaka さん:
>▼hoyahoyamachine さん:
>
>>ユーザー定義関数をワークシート上で使用する場合に[F8]は使えるのでしょうか?
>
>Function プロシジャーのコード内にブレークポイントを設けておけば、
>数式を書き込んだ時にそこで止まるけど。
>
>でも、Function プロシジャーにする前に、Sub プロシジャーで、まともに動くまで確認します。

はい、確かにそうですね。
Subプロシジャでは問題なく動くのですけれど、今回ワークシート上では休日をカウントしなかったんです。
一時しのぎの回避策で、シートモジュールのChangeイベントを利用して標準モジュールのFunctionプロシジャをコールする手段をとり、問題ない動作を確認したのですが、ユーザー定義関数としてFunctionプロシジャを使う場合、参照先は引数にしないといけない、ってことがわかりました。

290 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free