[[20200526034843]] 『findを使った日付検索』(mogu) ページの最後に飛ぶ

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

 

『findを使った日付検索』(mogu)

findを使って日付検索をしたいです。

セル範囲("K39:AF44")からセルK4と同じ日付を探し、その場所を行数で出力させています。
仮に、
 (what:="2020/5/26", LookIn:=xlValues)
であれば、正しく実行されます。
しかし、K4 に2020/5/26が入っており、
 (what:=Range("K4").Value, LookIn:=xlValues)
これを実行しても出力されません。

K4の日付は手入力ですが、検索範囲内の日付は関数の計算結果です。
また、K4も検索範囲内も表示形式は、日付の1900/1/1に合わせています。
下記が作ったマクロです。
よろしくお願いします。

Sub 日付検索()

    Dim target As Range  '検索にヒットしたセルを記録
    Dim firsttarget As Range  '最初に検索にヒットしたセルを記録
    Dim searchrng As Range '検索範囲

    Set searchrng = Worksheets("転記用").Range("K39:AF44")
    Set target = searchrng.find(what:=Range("K4").Value, LookIn:=xlValues) '最初のFindでK4の値を検索するように設定

    If Not target Is Nothing Then  '検索対象が1件以上ある場合に下記コードを実行
        Set firsttarget = target

        Do
            Set target = searchrng.FindNext(target)   '()内のセルの次のセルから検索を続行

            MsgBox target.Row
        Loop While target.address <> firsttarget.address '最初のセルに戻るまでDo~Loopを継続
    End If

End Sub

< 使用 Excel:unknown、使用 OS:unknown >


 LookIn:=xlValues ⇒ LookIn:=xlFormulas にすれば良いでしょう

 Sub 日付検索()
    Dim target As Range         '検索にヒットしたセルを記録
    Dim firsttarget As Range    '最初に検索にヒットしたセルを記録
    Dim searchrng As Range      '検索範囲

    Set searchrng = Worksheets("転記用").Range("K39:AF44")
    Set target = searchrng.Find(what:=Range("K4").Value, LookIn:=xlFormulas)    '最初のFindでK4の値を検索するように設定
    If Not target Is Nothing Then                                               '検索対象が1件以上ある場合に下記コードを実行
        Set firsttarget = target
        Do
            MsgBox target.Row
            Set target = searchrng.FindNext(target)         '()内のセルの次のセルから検索を続行
        Loop While target.Address <> firsttarget.Address    '最初のセルに戻るまでDo~Loopを継続
    End If
 End Sub

(ピンク) 2020/05/26(火) 05:28


変更して実行しましたが、何も表示されませんでした、、、。
(mogu) 2020/05/26(火) 22:28

  >検索範囲内の日付は関数の計算結果です。 

  数式で日付を出しているんですよね。

  なら、LookIn:=xlFormulas なので、
  数式文字列の中に、たまたまその日付文字が入ってない限り、
  ヒットしないと思いますよ。

  1.LookIn:=xlValues に戻す。

  2.セル書式を「ユーザー定義」ベースで見て、どうなっているかチェックする
    yyyy/m/d;@ になっていたら 
    yyyy/m/d  に全部変更する。つまり「;@」を取る

(半平太) 2020/05/26(火) 23:13


実行できました。
ありがとうございます!!
(mogu) 2020/05/26(火) 23:17


関連はするが、別の話でもあり、たぶん明解な回答は無いだろうと思いますので、
コメントは取り下げます。

(γ) 2020/05/27(水) 10:00


 >たぶん明解な回答は無いだろうと思いますので、 

 日付データが生の値のケースについてだったと思いますが、
 発想を変えると、シンプルな原理で説明できそうです。

 すると「おお、素晴らしい。検索語にDateValue関数を使い、
      引数LookInにxlFormulasを指定すると、セルの表示形式にかかわらず、
        ちゃんと検索できました。」

 とOfficeTanakaさんが言ったのがそもそもミスリードに思えます。

 ※得られた結果に間違いはないですが、検索値をDATE型にするが必須と思い込まされる。
  しかし勘違い。それでは部分一致のオプションも使えない(にくい)。

 1.検索値の型はどうあるべきなのか
   文字列型である。
   
   DATE型で渡すと、"3/14/2011"の順の文字列に変換されて処理される。
     下記2の(2)と相性がいいので、結果オーライと呼ぶべき現象が起きたりする。
   上述の文字列で検索していると認識できていた人は別ですが。

 2.対象日付データの何プロパティを検索するのか
   「Textプロパティの様なもの」である。
   Textプロパティそのものではない。見た目と異なるので理解しにくい所。

    例として、日付が2011/3/14のシリアル値である場合の「Textプロパティの様なもの」
   
   セルの書式→    *2011/3/14   2001/3/14  3/14 
    オプション       ↓      ↓    ↓
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   (1) xlValues     3/14/2011(※)   2011/3/14   3/14   (バラバラ。書式を統一しないと全部はヒットできない)
   (2) xlFormuas      3/14/2011(※)  3/14/2011  3/14/2011 (一貫しており、書式に左右されない)

   ※ 年の位置順が異なるのだが、ユーザーは気づかない(気づけない。シート上では差がないので)
        xlValuesも、セルの書式が「*2011/3/14」の場合はシートの文字を見てはいない。

(半平太) 2020/05/31(日) 17:17


 コメントありがとうございます。

 Sub test()
     Dim r As Range
     Set r = [A1]
     r = Date
     Debug.Print r.Value; Tab; TypeName(r.Value)
     Debug.Print r.Formula; Tab; TypeName(r.Formula)
     Debug.Print r.Value2; Tab; TypeName(r.Value2)
 End Sub

 2020/05/31    Date
 43982         String
  43982        Double

 という結果になるわけですが、これとの関係において、
 おしゃるような「Textプロパティの様なもの」の内容が
 なかなか分かりにくいというのが正直のところです。

 結果こうなるということ自体は理解するのですが、
 特にxlValuesとしたときの振る舞いは書式にも影響されるので、
 なかなか事前の予測可能性は低いですね。

 この質問者さんの前回のスレッド
[[20200524233755]] で引用した
http://officetanaka.net/excel/vba/tips/tips131d.htm
 のなかで、tanakaさんは、まとめとして、
 | 日付の検索を一言で表すと「いろいろあって難しい」ってことですね。
 | そのことだけ、忘れないようにしましょう。
 と発言されているのは、これに関する仕様の難しさを指摘されているのかもしれません。

 今回のコメントにより、少なくとも数式ではなく値そのものである場合は、
 xlFormuasを使うと安定するということは覚えておきたいと思います。

 関連質問にコメントをいただき、ありがとうございました。

(γ) 2020/05/31(日) 21:42


 >・・・
 > という結果になるわけですが、これとの関係において、

 ちょっと理解できないです。

 パラメタのWhatに渡しているのがDATE型であると言うだけで、
 それをどう処理するかは、RangeのFindメソッドの仕様次第です。

 γさんのテスト結果の様なデータが、内部でそのまま利用されている訳ではないです。

 >これに関する仕様の難しさを指摘されているのかもしれません。

 そうですか・・、私は、なんだ簡単なことだったんだなと思ったのですが。

(半平太) 2020/05/31(日) 22:24


>バラバラ。書式を統一しないと全部はヒットできない
というところ、同じ感じを持ちました。

それらが、(私には)仕様から演繹的に導き出せそうもない気がする、というだけです。
セルの書式ごとに、それはそういう結果になるのが仕様だと認め、それを暗記できていれば、
たぶん何の問題もないのだと思います。
たぶん、私の能力不足なんだと思います。

(γ) 2020/05/31(日) 22:47


 γさんにそう言われると、二の句が継げないです。
 γさんの能力に及ぶ人は、まずいないですからねぇ。。

 次回、機会がありましたら、
 時刻付日付データの午前0時に発生する問題を検討したいと思っています。

 では、今回はこれで失礼します。

(半平太) 2020/05/31(日) 23:31


コメント返信:

[ 一覧(最新更新順) ]


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