• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:マクロ 困っています)

マクロ困っています

このQ&Aのポイント
  • マクロ作成中に発生しているFINDエラーの解決方法を教えてください。
  • セルの書式設定をユーザー定義にして時間のみ表示しています。
  • スケジュール表の特定の列で時間を検索する際にエラーが発生しているようです。

質問者が選んだベストアンサー

  • ベストアンサー
  • kagakusuki
  • ベストアンサー率51% (2610/5101)
回答No.2

 エラーの原因に関しては下記の参考URLのページを御覧下さい。 【参考URL】  [XL2000]Findメソッドで日付と時刻形式のデータを検索できない【日本マイクロソフト サポート】   https://support.microsoft.com/ja-jp/kb/416317/ja  又、それとは別の話として、時刻の情報を含んでいるデータを扱う際には、FLOOR関数やCEILING関数等の切り捨てや切り上げを行う関数を使う事は出来るだけ避けた方が良いと思います。  また、"1:00"の様な時・分・秒単位の情報を含んている値を、数回程度であれば兎も角、何度も重複して加減乗除を行う事も出来るだけ避けた方が良いと思います。  Excelでは日時のデータを扱う際に「基点である1900年1月1日0:00:00を数値の1として日単位の数値」であるシリアル値で表しており、時刻の様な1日未満の値は「コンマ何日」なのかという小数値で表しています。  例えば3:00は8分の1日なのでシリアル値は0.125、1900年1月2日6:00のシリアル値は2.25という具合です。  処が1:00では24分の1日なのでシリアル値は0.0416666666666666・・・という無限小数となってしまいます。  この様に時刻によっては無限小数で表さなければならない値も多いのですが、Excelでは数値の有効桁数を15桁までしか扱いませんので、無限小数を扱う際には正確に取り扱う事は出来ず、僅かながら誤差を含んだ値となります。  そのため、無限小数である日時のデータ同士の間でFLOOR関数やCEILING関数などを使用しますと、日時のデータの組み合わせによっては誤った計算結果が表示されてしまう場合があります。 【参考URL】  http://www.h3.dion.ne.jp/~sakatsu/TimeSerial_Error.htm  http://www.primestaff.co.jp/fumitaka_doc/2009/01/excel-floor-1.html  ですから、もし、1時間未満の端数を切り捨てた「日付+時刻」の値を求めるのでしたら、 =FLOOR(NOW(),"1:00") というのは止めて、 =(TEXT(NOW(),"yyyy/m/d h")&":0")+0 等の様にされるべきかと思います。  同様に 開始 = Application.WorksheetFunction.Floor(ws1.Cells(10, 2), (1 / 24)) というのは止めて、 With ws1.Cells(10, 2) 開始 = Int(.Value)+TimeSerial(Hour(.Value),0,0) End With とされるべきかと思います。  それで、御質問の件の解決方法ですが、まず、念のためにR3C3セルに入力する関数を次の様にして下さい。 =(TEXT(NOW(),"yyyy/m/d h")&":0")+0  又、同じく念のためにR3C4以降のセルに入力する関数を次の様にして下さい。 =(TEXT(RC[-6]+1/24,"yyyy/m/d h")&":0")+0  そして肝心のVBAに関してですが、Findメソッドを使ったために話がややこしくなったのですから、Findメソッドを使わずに済ませた方が良いのではないかと思います。  例えばMatch関数を使えば次の様になります。 Sub スケジュール表作成_改() Dim 始点, 終点 As Double Dim 開始c As Integer Dim ws1 As Worksheet Dim 検索値 As Variant 'Set ws1 = Worksheets("スケジュール表") Set ws1 = Worksheets("Sheet18") 始点 = ws1.Cells(3, 3).Value 終点 = Application.WorksheetFunction.Max(ws1.Rows(3)) 検索値 = ws1.Cells(10, 2).Value 開始c = 0 If IsDate(検索値) Then 検索値 = CDbl(検索値) + 0.000001 If 始点 <= 検索値 And 検索値 < 終点 + 1 / 24 Then 開始c = Application.WorksheetFunction.Match(検索値, ws1.Rows(3)) End If End If If 開始c = 0 Then MsgBox "現在、スケジュールが設定されているのは" & Chr(13) & _ Format(始点, "yyyy/m/d h:mm:ss") & "~" & Format(終点 + TimeSerial(0, 59, 59) _ , "yyyy/m/d h:mm:ss") & Chr(13) & "の範囲のみです。" _ , vbInformation, "スケジュール範囲外" End If End Sub  尚、 検索値 = CDbl(検索値) + 0.000001 の所で0.000001を加えているのは、万が一、有効桁数15桁の末尾の所で誤差が出たとしても検索結果自体には影響しない様にするためで、あくまで念の為に付け加えただけであり、もしかしますと必要が無いものである可能性もあります。  又、もしR10C2セルに入力されている日時がスケジュール表に記入されている期間の範囲外であった場合には、Msgboxによって期間外である事を御知らせする様にしております。  因みに、他にもやり方は色々あると思います。  例えば、1時間ごとに6列ずつ列がずれる事が決まっているのですから、何も3列目のセルに入っている値を検索対象にせずとも、R10C2セルに入力されている日時と、R3C3セルに入っている日時の間に何時間分の時間差があるのかを求めて、それを6倍すればC3セルとの列数の差を求める事が出来ます。 Sub スケジュール表作成_改2() Dim 始点, 終点 As Double Dim 開始c As Integer Dim 始点セル As Range Dim ws1 As Worksheet Dim 検索値 As Variant Set ws1 = Worksheets("スケジュール表") Set 始点セル = ws1.Cells(3, 3) 始点 = 始点セル.Value 終点 = Application.WorksheetFunction.Max(ws1.Rows(3)) 検索値 = ws1.Cells(10, 2).Value 開始c = 0 If IsDate(検索値) Then 検索値 = CDbl(検索値) + 0.000001 If 始点 <= 検索値 And 検索値 < 終点 + 1 / 24 Then 開始c = 始点セル.Column + Int((検索値 - 始点) * 24) * 6 End If End If If 開始c = 0 Then MsgBox "現在、スケジュールが設定されているのは" & Chr(13) & _ Format(始点, "yyyy/m/d h:mm:ss") & "~" & Format(終点 + TimeSerial(0, 59, 59) _ , "yyyy/m/d h:mm:ss") & Chr(13) & "の範囲のみです。" _ , vbInformation, "スケジュール範囲外" End If End Sub

kero1192kero
質問者

お礼

返事が遅れて申し訳ありませんでした。 色々細かな事まで教えて頂き、ありがとうございました。 オートフィルターの時も色々考えて、ここに質問した記憶があります。 時間の検索って難しいですね。 教えてもらった記述をベースに考えていこうかと思います。 大切な時間を割いて、色々教えて頂きありがとうございました。 たぶん、ここに質問すると思うので、時間があればまた教えて下さい。

その他の回答 (1)

  • dogs_cats
  • ベストアンサー率38% (278/717)
回答No.1

検索日の列番号を取得したいという事で良いのでしょうか。 findシート関数を使用しないで、do~loopとDateDiffで開始日と検索日の差が0時間の場合れ列番号を開始cに取得する方法で良ければ下記はその一例です。 検索は249列目までとしています。検索日が見つからない場合は検索cは0となります。 Sub スケジュール表作成() Dim 始点 As Date, 終点 As Date, 開始 As Date, 終了 As Date Dim 検索日 As Date Dim 開始c As Integer, 終了c As Integer Dim ws1 As Worksheet, ws2 As Worksheet Dim i As Integer Dim find_value As Double Dim cell_value As Double Set ws1 = Worksheets("sheet1") 始点 = ws1.Cells(3, 3).Value 終点 = ws1.Cells(3, 249).Value 開始 = Application.WorksheetFunction.Floor(ws1.Cells(10, 2), (1 / 24)) i = 3 Do While i < 250 検索日 = Application.WorksheetFunction.Floor(ws1.Cells(3, i), (1 / 24)) If DateDiff("h", 開始, 検索日) = 0 Then 開始c = i Exit Do End If i = i + 6 Loop End Sub

kero1192kero
質問者

お礼

返事が遅れてすみませんでした。 繰り返し記述で目的の列まで辿りつく方法もあるんですね。とても参考になりました。 ですが、もう一人の方が繰り返し記述ではなく、もっと早い方法で検索する方法を教えてくれたので、今回はその方の方法でやろうかなと思います。 今回の質問に大切な時間を割いて頂き、ありがとうございました。 たぶん、また違う内容で質問する時があると思いますので、その時は宜しくお願い致します。

関連するQ&A

専門家に質問してみよう