C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: Excelマクロにて小数部を求めたい


(過去ログ 35 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■17611 / inTopicNo.1)  Excelマクロにて小数部を求めたい
  
□投稿者/ 萩泉 (1回)-(2008/04/28(Mon) 11:19:52)

分類:[VB6 以前] 

使用OS:Windows2000
開発環境・言語:MicrosoftExcel2000 , MicrosoftVisualBasic6.0

こんにちは、お世話になります。

エクセルの勤務表に、日勤時間や週勤時間等を自動記録するシステムを作成しています。
現在は週の初めの営業日と、終わりの営業日の入力を求め、
その週の勤務時間と標準勤務時間を記録する部分を作っております。

そのうちの、標準勤務時間の部分が、
小数部が切り捨てられるのか、本来の値とずれてしまいます。

マクロなしでやると、標準勤務時間は以下の式を入力しています。
=INT(0.319444444444444*営業日数*24/1)+MOD(0.319444444444444*営業日数*24,1)*60/100

それをマクロでは以下のように記録してみました。
------------------------------------------------------
Sub 週勤計算()

Dim Startday As Integer         '週始めの営業日を格納
Dim Endday As Integer           '週終わりの営業日を格納
Dim Fixedstandard As Single     '週の標準勤務時間を計算して格納

'週初めの営業日の入力を求める。
Startday = Application.InputBox("週の始まりの平日を入力してください。", "週勤務時間計算", , , , , , 1)
'週終わりの営業日の入力を求める。
Endday = Application.InputBox("週の終わりの平日を入力してください。", "週勤務時間計算", , , , , , 1)

-中略(週の勤務時間を記録)-

'記録部のセルを結合
Range(Cells(Startday + 3, "M"), Cells(Endday + 3, "M")).MergeCells = True

'週の標準勤務時間を算出してセルに入力
Fixedstandard = (Int(0.319444444444444 * (Endday - Startday + 1) * 24 / 1)) + (0.319444444444444 * (Endday - Startday + 1) * 24 Mod 1) * 60 / 100
Cells(Startday + 3, "M") = Fixedstandard

End Sub
------------------------------------------------------

MOD関数の動作が違うらしいということは理解できたのですが、
小数部を切り捨てない関数、もしくは演算子が分からず、つまづいています。

この質問を書くためにデバック作業をしながら確認をしていたら、
int関数の動きも期待通りでない気がしてきました。

引用返信 編集キー/
■17614 / inTopicNo.2)  Re[1]: Excelマクロにて小数部を求めたい
□投稿者/ 片桐 (89回)-(2008/04/28(Mon) 11:29:54)
実際には、日付時間はセルの表示方法を変えないと「シリアル値」と呼ばれる、一見すると数値に見えるもので表示されてしまうことがあるので、数値と誤解しがちですが、数値で計算するととんでもなく大変です。

まず、時間や日付は数値で計算するよりも、専用関数を使うほうが楽なので、「数値で計算」という概念を捨てて、再度プログラム仕様を練り直す方がよろしいかと思います。

週はじめの日付と終わりの日付の間の日数は、日付期間差を求める関数で計算
週の標準勤務時間は、その日数×時間(数値)にしてから、シリアル値に変換

で、処理できると思います。
マクロで使えるVBA処理関数のヘルプもご参照ください


引用返信 編集キー/
■17617 / inTopicNo.3)  Re[2]: Excelマクロにて小数部を求めたい
□投稿者/ やじゅ (331回)-(2008/04/28(Mon) 12:10:13)
>萩泉さん
>
>MOD関数の動作が違うらしいということは理解できたのですが、
>小数部を切り捨てない関数、もしくは演算子が分からず、つまづいています。

MOD関数とVBAのMod関数では小数点の扱いが違いますね。
MOD関数は浮動小数点を考慮してますが
Mod関数は浮動小数点があっても丸めてしまいます。

小数部を切り捨てないMod関数 Currency型は適当なものに変更してください
Public Function fmod(ByVal a As Currency, ByVal b As Currency) As Currency
fmod = a - Int(a / b) * b
End Function

引用返信 編集キー/
■17623 / inTopicNo.4)  Re[3]: Excelマクロにて小数部を求めたい
□投稿者/ 萩泉 (2回)-(2008/04/28(Mon) 14:22:42)
No17614 (片桐 さん) に返信
> 実際には、日付時間はセルの表示方法を変えないと「シリアル値」と呼ばれる、
> 一見すると数値に見えるもので表示されてしまうことがあるので、数値と誤解しがちですが、数値で計算するととんでもなく大変です。
シリアル値とは、たとえば"7:40"と入力した際に、表示を標準にすると見える"0.3194444"のことでしょうか。
"7:40"が60進だとしたら、10進で表示されたものが"0.3194444"だと思っていたのですが…。
数値で計算した後にシリアル値に変換、とあるのですが、数値とシリアル値の違いは何でしょう?

> 週はじめの日付と終わりの日付の間の日数は、日付期間差を求める関数で計算
これは多分、表の入力に日付(yy/mm/dd)がないので出来ません。

(既に使われている勤務表のエクセルがあり、すべて手動(計算)入力では誤りが出るということで、
現在私がマクロを付け加えているという現状なので、あまり大幅な変更を加えられません。
表の構造を簡易的に示したものを下記とします。

A| B | C | D | E | F | G
------------------------------------------------------------------------------------------------------
日|曜日| 出 | 退 | 日勤 | 週勤 | 標準週勤
------------------------------------------------------------------------------------------------------
1| 月 |09:00|17:40|"=(休憩始-C1)+(B1-休憩終)"| |
--|----|-----|-----|--------------------------| |
2| 火 |09:30|18:30|"=(休憩始-C2)+(B2-休憩終)"|"=int((D1+D5)*24/1)+mod((D1+D5)*24,1)*60/100"|"=7:40*5"
--|----|-----|-----|--------------------------| HH.MM |
3| 水 |09:10|20:30|"=(休憩始-C3)+(B3-休憩終)"| |
----------------------------------------------| |

> 週の標準勤務時間は、その日数×時間(数値)にしてから、シリアル値に変換
> で、処理できると思います。
HH:MMの形式で表示すると、24時間ごとに0に戻ってしまうので困るのですが…。
そういう方法ではないのでしょうか?今ひとつ理解が完全でないようです。


No17617 (やじゅ さん) に返信
> 小数部を切り捨てないMod関数 Currency型は適当なものに変更してください
> Public Function fmod(ByVal a As Currency, ByVal b As Currency) As Currency
> fmod = a - Int(a / b) * b
> End Function
これは、、、わざわざ作ってくださったのでしょうか、ありがとうございます。
ひとまずこちらを使って実行してみます。
引用返信 編集キー/
■17625 / inTopicNo.5)  Re[4]: Excelマクロにて小数部を求めたい
□投稿者/ 萩泉 (3回)-(2008/04/28(Mon) 15:53:41)
fmod関数で成功いたしました。
int関数が期待通りでなさそうというのも、fmod関数を使ったら付随して解決することが出来ました。

片桐様、やじゅ様、お世話になりました。
ありがとうございます。
解決済み
引用返信 編集キー/
■17626 / inTopicNo.6)  Re[4]: Excelマクロにて小数部を求めたい
□投稿者/ 魔界の仮面弁士 (697回)-(2008/04/28(Mon) 15:56:17)
2008/04/28(Mon) 15:58:55 編集(投稿者)

# 既に解決済みだったので、解決済みチェックを入れました。

No17623 (萩泉 さん) に返信
> 数値で計算した後にシリアル値に変換、とあるのですが、数値とシリアル値の違いは何でしょう?
日付シリアル値は、内部的には数値です。
ただ、日付では秒未満の情報が管理されない(誤差範囲)とされるため、たとえば
 100.123456
 100.123457
 100.123458
 100.123459
といった日付シリアル値は、いずれも同一日時「1900-04-09 02:57:47」を
指し示す点に注意が必要です。(これらは、内部的には別の日時なので、
内部値をそのまま比較すると、別の時刻として扱われる事になります)


> HH:MMの形式で表示すると、24時間ごとに0に戻ってしまうので困るのですが…。
> そういう方法ではないのでしょうか?今ひとつ理解が完全でないようです。
セルの書式を『hh:mm:ss』ではなく、『[hh]:mm:ss』や『[hh]:mm』にすれば、
Excel 上で 24 時以上の値(24:57 とか 27:15:00 とか) を利用できますよ。
計算するにも都合が良いかと。
解決済み
引用返信 編集キー/
■17629 / inTopicNo.7)  Re[5]: Excelマクロにて小数部を求めたい
□投稿者/ 萩泉 (4回)-(2008/04/28(Mon) 17:19:12)
2008/04/28(Mon) 19:11:24 編集(投稿者)
2008/04/28(Mon) 17:19:51 編集(投稿者)
2008/04/28(Mon) 17:19:46 編集(投稿者)

No17626 (魔界の仮面弁士 さん) に返信
>>数値で計算した後にシリアル値に変換、とあるのですが、数値とシリアル値の違いは何でしょう?
> 日付シリアル値は、内部的には数値です。
> ただ、日付では秒未満の情報が管理されない(誤差範囲)とされるため、たとえば
>  100.123456
>  100.123457
> といった日付シリアル値は、いずれも同一日時「1900-04-09 02:57:47」を
> 指し示す点に注意が必要です。(これらは、内部的には別の日時なので、
> 内部値をそのまま比較すると、別の時刻として扱われる事になります)
精度が問われる場合には日付シリアル値を数値だと思っていると痛い目を見るようですね…。
今回は10分刻みの勤務表ですので、問題はなさそうです。

>>HH:MMの形式で表示すると、24時間ごとに0に戻ってしまうので困るのですが…。
>>そういう方法ではないのでしょうか?今ひとつ理解が完全でないようです。
> セルの書式を『hh:mm:ss』ではなく、『[hh]:mm:ss』や『[hh]:mm』にすれば、
> Excel 上で 24 時以上の値(24:57 とか 27:15:00 とか) を利用できますよ。
ありがとうございます、表示形式の"時刻"と"日付"しか見ていなかったので気づきませんでした。
"ユーザー定義"にこんな便利な書式があったのですね。

> 計算するにも都合が良いかと。
セルをセレクトするたびに長い式が出てくるのも閉口ですし、
マクロのソースも短くなるので、こちらを採用しようかと思います。

ご教授ありがとうございます。


ところで…シリアル値でない時間の数値っていったいどんなものでしょう…。
今は分からなくてもなんとかなりそうですが、いつかまたつまづきそうです。
誰かお手すきでしたら、ご説明いただけると恐悦至極。
本来は、別スレッド立てるべきなのでしょうが…。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -