[[20121104070952]] 『時間の比較』(チサ) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『時間の比較』(チサ)

いつもお世話になっております。

どうしても進まなくて どなたかお助けください。

同一行の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


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ダンプは本当に助かっています。ありがとうございました。  (チサ)


ichinose 様

>誤差の原因は、よく調べていただき、顛末の投稿をお願いします。

こんばんは!

先日からいろいろテストしてみました。

テーブルの内容はほぼ関数で埋まっています。名前、店をキーに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


ichinose 様
こんばんは!

申し訳ございません。お手数おかけしました
入力データに問題があり、文字データが入っていました。
HEX データ表示することができました。
これでいちいちファイルに書き出さなくてすみます。

今回のトラブルで随分勉強になりました。
いろいろと、ありがとうございました。  (チサ)


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.