今回は「日付の検索はいろいろと難しい」という話をします。
次に書く通りに操作してください。まず新規ブックを挿入します。
Excelを起動して最初に表示されるBook1でもけっこうです。Sheet1のセルA1に「2010/7/1」と入力して、セルA1のフィルハンドルをセルA5までドラッグします。
セル範囲A1:A5には、
2010/7/1
2010/7/2
2010/7/3
2010/7/4
2010/7/5
と入力されましたよね。念のため確認しておきます。
これはすべて「シリアル値」がセルに入力されています。また、表示形式は何も変更していません。
このセル範囲から「2010/7/5」を検索してみます。検索に使うのはFindメソッドです。
Sub Sample1()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:="2010/7/5")
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub\
は失敗します。見つかりません。
このように、セルに「シリアル値」が入力されていて、セルの表示形式に日付標準の「* 2001/3/14」が設定されているときは、検索語に「"2010/7/5"」のような文字列を指定すると見つかりません。
ここはDateValue関数などを使って、検索語にシリアル値を指定しなければいけません。
次のようにすれば見つかります。
Sub Sample1()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:=DateValue("2010/7/5"))
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub
では、日付の検索で検索語に「"2010/7/5"」のような文字列は使えないのかというと必ずしもそうではありません。
今、日付が入力されているセル範囲A1:A5を選択して、表示形式を「* 2001/3/14」から「*」のない「2001/3/14」に変更してください。
画面の見た目は変わりませんね。こうすると、
Sub Sample1()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:="2010/7/5", LookIn:=xlFormulas)
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub
は見つかりませんが、
Sub Sample1()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:="2010/7/5", LookIn:=xlValues)
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub
なら見つかります。
引数LookInに指定した定数に注目してください。
では、このように、日付の表示形式を変更した場合、DateValue関数ではどうでしょう。
Sub Sample1()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:=DateValue("2010/7/5"), _
LookIn:=xlFormulas)
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub
は見つかりますが、
Sub Sample1()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:=DateValue("2010/7/5"), _
LookIn:=xlValues)
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub
では見つかりません。
「"2010/7/5"」と文字列を指定した場合とは逆に、引数LookInに定数xlFormulasを指定しなければ、検索に成功しません。
LookInなどの引数は前回の指定を引き継ぎます。
これは、マクロでFndステートメントを実行したときだけではなく、手動で[検索と置換]ダイアログボックスを操作した場合も同じです。確実に検索を行うには、Findメソッドの引数を省略しない方がいいですね。
さて、ワークシート上のデータを、もう少し変更してみましょう。
セル範囲A2:A5を選択してDeleteキーを押します。2行目以降をクリアしてください。
そして、セルA2に「=A1+1」と入力します。セルA2には「2010/7/2」と表示されますね。
このセルA2のフィルハンドルを、セルA5までドラッグします。セルA5には「2010/7/5」が表示されて、今までと何も変わっていないように見えます。
しかし、セルA5には「=A4+1」という数式が入力されている点に留意してください。
このとき、どのセルにも「2010/7/5を表すシリアル値」は直接入力されていません。
この状態では、
Sub Sample1()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:=DateValue("2010/7/5"), _
LookIn:=xlFormulas)
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub
も
Sub Sample1()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:=DateValue("2010/7/5"), _
LookIn:=xlValues)
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub
も検索に失敗します。
セルに、直接シリアル値が入力されているのではなく「=A1+1」のような数式が入力されていると、DateValue関数では検索できないのでしょうか。
セル範囲A1:A5を選択して、表示形式を「* 2001/3/14」に設定してください。
今度は、
Sub Sample4()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:=DateValue("2010/7/5"), _
LookIn:=xlFormulas)
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub
は失敗しますが、
Sub Sample4()
Dim FC As Range
Set FC = Range("A1:A5").Find(What:=DateValue("2010/7/5"), _
LookIn:=xlValues)
MsgBox IIf(FC Is Nothing, "失敗", "成功")
End Sub
は成功します。
このように、日付の検索は一筋縄ではいきません。
・セルに入力されているのはシリアル値か数式か
・セルにどんな表示形式が設定されているか
・検索語が文字列形式かDateValueなどの関数か
・Findメソッドの引数に何を指定しているか
などによって、検索が成功したり失敗したりします。
特効薬的な「こうすれば全てOK」という必殺技はありません。
マクロで日付を検索するときに最も大事なことは『いろいろあって難しいんだ』という認識を持つことです。