[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『時間の比較』(チサ)
いつもお世話になっております。
どうしても進まなくて どなたかお助けください。
同一行の5番目と9番目のセルに時刻 9:30 が入っています。
これを比較して 同じなら A処理 違ったら B処理をしたいのですが
見た目は同じなのに違うと判断されてしまいます。
If c.Offset(, 4).Value = c.Offset(, 8).Value Then
デバッグモードにするとC.offset( ,4) = 0.395833333333333
C.offset( ,8) = 0.395833333333333 と表示されます。
MsgBox " stp4 時間違う time = " & c.Offset(, 4).Value & " time2 = " & c.Offset(, 8).Value こちらも上と同じ数字が表示されます。
セルの書式設定はどちらも は時刻 の 13:30
セルにカーソルを持っていくと どちらも 9:30:00 となります。
何がおかしいのでしょうか? どなたか教えてください。
よろしくお願いいたします。 (チサ)
Excel2003 Windows 7
>何がおかしいのでしょうか? よくいわれる小数の演算誤差だと思います。 思います というのは、実際にどのような経過で二つのセルに時刻が設定されているのか 明確でないので。
例
新規ブックの標準モジュールに
'============================================================ Sub test1() With Range("a1:b1") .NumberFormatLocal = "hh:mm" .Cells(1).Value = CDate("9:30") With .Cells(2) .Formula = "=""17:58:26""-""8:28:26""" .Value = .Value End With MsgBox "(a1 = b1) = " & (Range("a1").Value = Range("b1").Value) End With End Sub
上記のtest1を実行してください
セルA1には、直接 9:30という時刻を設定 セルB1には、17:58:26 -8:28:26 という時刻の引き算の結果を設定
その二つが等しいか否かを表示しています 結果は、False(等しくない)とでます。
同じ標準モジュールに
'============================================================ Sub test2() Dim dbla1 As Double Dim dblb1 As Double dbla1 = Range("a1").Value dblb1 = Range("b1").Value MsgBox "a1 = " & floating_img(dbla1, 1) & vbCrLf & "b1 = " & floating_img(dblb1, 1) End Sub
別の標準モジュールに
'============================================================ Option Explicit Type d_data dbl As Double End Type Type s_data sng As Single End Type Type bd_data byt(0 To 7) As Byte End Type Type bs_data byt(0 To 3) As Byte End Type Function floating_img(ByVal myvalue As Variant, ByVal typ As Long) As String '指定された型の数値のメモリーイメージをHEXコードで出力する 'in ----myvalue----数値 ' typ=0--single 1--double 'out-----floating_img ---メモリーイメージ(HEXコードで) On Error Resume Next Const typ_sin = 0 Const typ_dbl = 1 Dim g0 As Long Dim g1 As Long Dim dd As d_data Dim ss As s_data Dim bb_s As bs_data Dim bb_d As bd_data Dim wk As String Select Case typ Case typ_sin ss.sng = CSng(myvalue) LSet bb_s = ss Case typ_dbl dd.dbl = CDbl(myvalue) LSet bb_d = dd End Select If typ = 0 Then g1 = UBound(bb_s.byt()) Else g1 = UBound(bb_d.byt()) End If floating_img = "" For g0 = g1 To 0 Step -1 If typ = 0 Then wk = Hex(bb_s.byt(g0)) Else wk = Hex(bb_d.byt(g0)) End If If Len(wk) = 1 Then wk = "0" & wk floating_img = floating_img & wk Next End Function
として、test2を実行してください。
A1,B1の値をDouble型に移して、内部データ(8バイトのデータ)を表示しています(表示は16進数)。
A1とB1では、深いところで違っていますよね? 等しくない結果の原因は、これです。
test1,test2と同じモジュールに
'========================================================= Sub test3() MsgBox "(a1 = b1) = " & (CDate(Range("a1").Text) = CDate(Range("b1").Text)) End Sub
こんな風にすると、等しいという結果を得られます。
検討してください
ichinose
計算も何もせず、どちらも入り口の違う手入力なのですが、どこか違うのでしょう。どうちがうのか調べてみます。
テキストに変換すればいいのですね。出来そうな気がしてきました。
お助けくださり、本当にありがとうございました。(チサ)
>テキストに変換すればいいのですね。出来そうな気がしてきました。
たいていの場合それでいいのでしょうが、厳密に云うと「変換」ではありません。 TEXTプロパティは 「セルに表示されている文字列」であって、 「セルに表示されるベキ文字列」ではありません。 列幅が狭くて「#####」なんて表示になると実体とは似ても似つかない文字になります。
私は読んでいないですが、ある質問者さんが読んだ参考書では、 TEXTプロパティの使用は出来るだけ避けるべき、とあったらしいです。 それで、質問者さんから、逆に私が注意を受け、仕方なくFormat関数を噛ませて 表示されるべき文字列にする案にしたことがあります。(^^ゞ
>どちらも入り口の違う手入力なのですが、どこか違うのでしょう。どうちがうのか調べてみます。
いままでの経験則では『手入力の時間データ同士は、異同大小の比較で食い違う事はない』と云うのが相場でした。
今回、それが崩れると云う話の展開になるので「入り口の違う手入力」がどういう事なのか、 是非ともご説明いただきたいと思います。現時点では、私は「手入力データ」に懐疑的です。
<追記> 今、改めてトライしてみると、Format関数の書式設定は注意を要します。 書式を"mm:ss"とかにすると、mmは月の指定と解釈されるようです。(Win7,XL2010)
ワークシート関数のTEXT関数を使った方が無難と思えました。
(半平太) 2012/11/05 11:26
> 書式を"mm:ss"とかにすると、mmは月の指定と解釈されるようです。(Win7,XL2010)
分の書式はnnです。"hh:nn:ss" ですね。
minuteのmを使いたいところですけど、それだと月と被るので、mと似ているってことで
nになったのかなと思っています。
−佳−
佳さん こんばんは
あら!そうなんですか?
"h:mm:ss" だと普通に出てくるので、"mm"の代わりに"nn"を使うのは知らなかったです。
ありがとうございました
>mと似ているってことで >nになったのかなと思っています。 そうなんでしょうけど、老眼の身には紛らわしくて、却ってツライ(とほほ)
(半平太) 2012/11/05 23:19
まさしく 手入力直後のデータの比較ではありません。
基本時間を手入力したマスター を ワークシート上でVlookupなどで得た基本時間をマクロで中間ファイルに転記したデータと 同一フォーマットの別シートの同一セルを直接 関数を壊して手入力した時間を比較し、時間の修正が行われたデータのみ書き出したい、というのが目的の時間の比較です。
これから、じっくり調べていきたいと思います。
皆様 いろいろとありがとうございます。 (チサ)
>TEXTプロパティの使用は出来るだけ避けるべき あっ、そうですね!!私も普段は使いませんが、 今回は、何気に .Textを使っていました。 Application.Textと記述するのが、妥当ですね
ご指摘感謝します。
誤差の原因は、よく調べていただき、顛末の投稿をお願いします。
ichinose
>基本時間を手入力したマスター を ワークシート上でVlookupなどで得た基本時間をマクロで中間ファイルに転記したデータと >同一フォーマットの別シートの同一セルを直接 関数を壊して手入力した時間
全体の流れは、演算誤差を誘発する計算はしていない印象を受けます。
なので、この部分に認識の違いがあるのではないかと思います。 ↓ 『基本時間を手入力したマスター』
大量に規則的な時間データを入れる場合、人間は一つひとつ手入力しないのが普通です。 もし、マスターに1,2番目のデータを手入力して、あとはオートフィルで出力したとすると、 それらは、一つひとつ手入力したデータと異なる可能性があります。 オートフィルのデータはエクセルが「演算」して出力したものだからです。
ichinose さん
>Application.Textと記述するのが、妥当ですね
へー、これまた新知識です。 WorksheetFunctionって書くのイヤだなぁと思う時があるので、これは使えます。 ごちゃごちゃ書き込んでみるもんですね。^^
(半平太) 2012/11/06 09:54
これもまた、まさしくその通りのような気がします。
私もそうしましたし、このデータを作った彼もきっとそのようにマスターを作成したと思います。
ここらあたりに原因ありそうな気がしてきました。
ichinose 様 とっても感謝しております。
HEXダンプ 今からじっくり勉強させていただき、サブルーチン化にして(今日から勉強)、原因追求がんばります。またご指導お願いいたします。 (チサ)
>私もそうしましたし、このデータを作った彼もきっとそのようにマスターを作成したと思います。 >ここらあたりに原因ありそうな気がしてきました。
それなら、決まりです。
私が「可能性がある」と云ったのは、確信がなくて云ったのではなく、 全部が全部異なる訳ではないと云うニュアンスで書いたのであり、 手入力データと異なる時間データがマスターに確実に存在します。
手入力データに合わせる為、以下の様な処置を施す(それで解決です)。
B2セル =TEXT(A2,"[h]:mm:ss")*1 下にコピー
行 ______________A______________ __________________B______________ 1 今までのマスタ内の時間データ この数式の結果をコピーして、A列に「値貼り付け」する 2 1:50 1:50 3 2:31 2:31
(半平太) 2012/11/06 19:50
> B2セル =TEXT(A2,"[h]:mm:ss")*1 ↑ 秒は要らなかったです。m(__)m
B2セル =TEXT(A2,"[h]:mm")*1
(半平太) 2012/11/06 20:23
マスターの時間の入力エリアの対処が必要なのがよくわかりました。
教えていただきたいのですが、マクロで関数が入っているセルを扱う時、計算結果後を扱うにはどのようにしたらよいのでしょうか? (チサ)
ちょっと面食らうご質問ですね。
Valueプロパティか、Value2プロパティを使うことだと思いますが、 多分ご質問の趣旨は、そんなことではないですよね?
(先走って考えると、数式自体を改訂すると云う対応になると思います。)
(半平太) 2012/11/07 09:32
朝からテストをやり直しておりますと、微妙な数値のちがいどころか、時間と計算式の比較になってしまって、今もず〜と悩んでおります。
計算式をもってくる、というのはどのような時にそのようになるのでしょうか?
計算式に整合性というか、リンクはくずれています。検索ファイルが同一フォルダーにない、とか・・
数式自体どころか、もしかしてファイル構成がよくないのかも、と思ったりもしております。(チサ)
質問内容がガラッと変わりましたね?
>マクロで関数が入っているセルを扱う時、計算結果後を扱うにはどのようにしたらよいのでしょうか? >微妙な数値のちがいどころか、時間と計算式の比較になってしまって、今もず〜と悩んでおります。 >計算式をもってくる、というのはどのような時にそのようになるのでしょうか? >計算式に整合性というか、リンクはくずれています。 >検索ファイルが同一フォルダーにない、とか・・ >数式自体どころか、もしかしてファイル構成がよくないのかも、
これだけで状況を正確に判断することはできません。 多分、計算式が本来見に行くべき場所とは違う「リンク先フォルダ名」に 書換えられていたと云うことなんでしょうね?
推測の上で考えるのは無駄が多いので、気が進まないのですけど、、、
元々、自フォルダとマスタフォルダは同じだったのに、 自ファイルを別のフォルダに移動した、と云うことでしたら、 数式は、新しい自フォルダ内のマスタを見に行こうとしますよ。
そこに、別の(しかし同名の)マスタがあれば、数式はエラーになりません。 しかし、新天地のマスタが、正しい時間データを持っていないなら、 数式の結果は使い物にはなりません。
マクロを駆使して、「自動的に」昔のマスタを参照する数式に戻したい、なんてことを お考えなら私はお役に立てません。(到底無理です) ただ、昔のマスタがあったフォルダのPathが分かっている、と云うことなら リンクの編集で簡単にできます。
・・・・と書いたはいいが、多分妄想でしょうね。無駄が多いので、ここまでにしておきます。
>(半平太)様 ↑ 「さん」ずけでお願いします。「様」は私には重すぎます。
(半平太) 2012/11/08 11:19
やっとバグみつかり、元の不具合の再現が出来るようになりました。
実際にオートフィルでマスターを作成したところ、まさしくあの現象がでましたので、TEXT加工すればすっきり思う動きになりました。
ありがとうございました。
ichinose さん
>誤差の原因は、よく調べていただき、顛末の投稿をお願いします。
もう少しいろいろなパターンをテストしてみて、何かわかりましたら報告させていただきます。
HEXダンプは本当に助かっています。ありがとうございました。 (チサ)
>誤差の原因は、よく調べていただき、顛末の投稿をお願いします。
こんばんは!
先日からいろいろテストしてみました。
テーブルの内容はほぼ関数で埋まっています。名前、店をキーにVlookupなどでマスターから基本出退勤時間を取得してます。
更新データの出退勤と比較し違っていたら、出退勤時間取得の関数を壊して更新データの出退勤時間で置き換えるという処理を目的としております。
時間の比較をするために、Valueで取り込んだテーブルと、変更のないものは、関数のまま書き出したいので、Formulaで取り込んだテーブルを用意しています。
したがって、時間が違った時、時間をformulaの該当テーブルに置き換えて、書き出しています。
その置き換えたデータを次にvalueで取り込んだ時、値が手入力した値と異なっているのが原因のようです。
同じ処理を繰り返すと、交代に9:30の値が 3FD9555555555555 と 3FD955555555554F を繰り返していました。
これで、やっとすっきりしました。
教えて頂きました、HEX LIST のサブルーチンをマクロに組み込もうと思ったのですが、どうもうまくいきませんでした。
型が一致しない、というエラーで・・・。
勉強のために、教えていただけないでしょうか。
よろしくお願いいたします。 (チサ)
Sub test1()
Dim v As Variant '転記用配列 Dim vv As Variant '転記用配列2 Dim mysthm Dim mykibou
Dim dbla1 As Double Dim dblb1 As Double
With shB v = .Range("A1").Resize(41, 250).Value 'シフト表領域を取込 値 vv = .Range("A1").Resize(41, 250).Formula 'シフト表領域を取込 計算式 End With
With shL For Each c In .Range("A2", .Range("A" & .Rows.Count).End(xlUp))
mysthm = c.Offset(, 4).Value ・ ・ dbla1 = mysthm dblb1 = mykibou MsgBox "a1 = " & floating_img(dbla1, 1) & vbCrLf & "b1 = " & floating_img(dblb1, 1)
Next End With End Sub
>型が一致しない、というエラーで・・・。 どこでこのエラーが発生するのですか?
それから、セルのデータは?
エラーが再現できません
ichinose
申し訳ございません。お手数おかけしました
入力データに問題があり、文字データが入っていました。
HEX データ表示することができました。
これでいちいちファイルに書き出さなくてすみます。
今回のトラブルで随分勉強になりました。
いろいろと、ありがとうございました。 (チサ)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.