Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3672 / 13644 ツリー ←次へ | 前へ→

【60775】Find関数の使い方について Porta 09/3/13(金) 19:30 質問[未読]
【60776】Re:Find関数の使い方について kanabun 09/3/13(金) 19:37 発言[未読]
【60777】Re:Find関数の使い方について kanabun 09/3/13(金) 20:06 発言[未読]
【60778】Re:Find関数の使い方について Porta 09/3/13(金) 21:22 発言[未読]
【60779】Re:Find関数の使い方について kanabun 09/3/13(金) 21:39 発言[未読]
【60783】Re:Find関数の使い方について Porta 09/3/14(土) 9:50 質問[未読]
【60784】Re:Find関数の使い方について kanabun 09/3/14(土) 11:48 発言[未読]
【60789】Re:Find関数の使い方について Porta 09/3/14(土) 20:50 お礼[未読]

【60775】Find関数の使い方について
質問  Porta  - 09/3/13(金) 19:30 -

引用なし
パスワード
   A6(2009/3/1)〜A2196(2015/2/28)まで、当年の3月1日から連続した日にち
があります。
表示は「3月1日」のようになっており『年』は表示していません。
InputBoxに年月日(2011/3/3)を入れてその対象年月日の行をを検出すること
をしています。
For〜NextやMatch関数を使っての検索はできたのですが、
Find関数を使うと、シートの日にちを一旦日付のシリアル値に
変換して、また戻すというスマートさがないやり方になってしまいます。
シート上で月日をシリアル値に変更しないでFind関数で検索する方法を教えてください。
現在は下のコードを考えました。

Sub Find_methodで検索()
 Dim r As Range
 Dim c As Range
 Dim ch
 Dim ch2
 ch = Application.InputBox(Prompt:="検索したい年月日…3/3のように半
角入力してください" _
    & Chr(10) & "当年以外は2013/3/3のように年を入力してくだ
さい", _
     Title:="検索", Default:="ここに検索したい日付を入れて下さい",
Type:=1)
 If ch = False Then
  MsgBox "Cancelが押されました", vbExclamation
  Exit Sub
 End If

 With Range("A1", Cells(Rows.Count, "A").End(xlUp))
  .NumberFormatLocal = "G/標準"
 End With
 
 Set r = Range("A1", Cells(Rows.Count, "A").End(xlUp))
 
 Set c = r.Find(ch, Range("a1"), _
     xlFormulas, xlWhole, , xlPrevious)
 If Not c Is Nothing Then
  c.Activate
  
  MsgBox "昨日は" & c.Address(0, 0) & "にあります"
 Else
  MsgBox "その年月日はありません", vbExclamation
 End If
 
 With Range("A1", Cells(Rows.Count, "A").End(xlUp))
  .NumberFormatLocal = "m""月""d""日"";@"
 End With
 
End Sub

【60776】Re:Find関数の使い方について
発言  kanabun  - 09/3/13(金) 19:37 -

引用なし
パスワード
   ▼Porta さん:
こんばんは。

>Match関数を使っての検索はできたのですが、

日付の検索は (単一行や単一列なら)Match関数を使うのが正しい選択かと
思いますよ。

>Find関数を使うと、

Findメソッド は基本的に文字列の検索ですから、
日付のMatchingには向いていないと思います。
どうして Findメソッドを使おうと思われたのですか?

【60777】Re:Find関数の使い方について
発言  kanabun  - 09/3/13(金) 20:06 -

引用なし
パスワード
   ▼Porta さん:
追伸です。

>A6(2009/3/1)〜A2196(2015/2/28)まで、当年の3月1日から連続した日にち
>があります。

つまり、漏れない 連続した日付がセットしてあるということですね?
なら、Matchも必要ないです。
[A6]セルの日付から 求める日付までの差分( Datediff)だけOffset
すればよいのですから。

Sub Try1()
 Dim theDay As Date
 Dim ss As String
 
 ss = "検索したい年月日… 3/3のように半角入力してください " _
    & vbLf & "当年以外は2013/3/3のように年を入力してください"
 ss = InputBox(ss, "日付検索", CStr(Date))
 If StrPtr(ss) = 0& Then Exit Sub
 If Not IsDate(ss) Then
   MsgBox "入力値は有効な日付ではありません"
   Exit Sub
 End If
 theDay = CDate(ss)
 With [A6].Offset(DateDiff("d", [A6].Value, theDay))
   .Select
   MsgBox theDay & " 日へジャンプしました", , .Address(0, 0)
 End With
 
End Sub

【60778】Re:Find関数の使い方について
発言  Porta  - 09/3/13(金) 21:22 -

引用なし
パスワード
   ▼kanabun さん:

回答有難うございます。
素晴らしいコードですね。感心しました。

少し私に理解できない点があります。
> With [A6].Offset(DateDiff("d", [A6].Value, theDay))
>   .Select
>   MsgBox theDay & " 日へジャンプしました", , .Address(0, 0)
> End With
DateDiff関数がうまく使われていることは分かりますが…今一
頭にしっかりと入りません。
シート関数でいえば、ここの"d"は何なんでしょう?

それから
If StrPtr(ss) = 0& Then Exit Sub
のStrPtrと 0&の意味を教えてください。

この方法ですと、記述していない20年先の年月日のセルアドレスも
分かるということになりますね。

よろしくお願いします。

【60779】Re:Find関数の使い方について
発言  kanabun  - 09/3/13(金) 21:39 -

引用なし
パスワード
   ▼Porta さん:
>
>少し私に理解できない点があります。
>> With [A6].Offset(DateDiff("d", [A6].Value, theDay))
>>   .Select
>>   MsgBox theDay & " 日へジャンプしました", , .Address(0, 0)
>> End With
>DateDiff関数がうまく使われていることは分かりますが…今一
>頭にしっかりと入りません。
>シート関数でいえば、ここの"d"は何なんでしょう?

ヘルプにあるとおりです。
  DateDiff(interval, date1, date2)
最初の引数 interval は date1 と date2 の間隔を計算するときの単位を
指定するものです。
 "yyyy" なら 年単位で、
 "m" なら 月単位で、
 "d" なら 日単位で 間隔を計算します。

しかし、よく考えてみれば、
> With [A6].Offset(DateDiff("d", [A6].Value, theDay))

こんなことしなくても「日差」ですから、
 With [A6].Offset(CLng(theDay) - [A6].Value2)

でよかったですね。

>
>それから
>If StrPtr(ss) = 0& Then Exit Sub
>のStrPtrと 0&の意味を教えてください。

StrPtr関数は 文字列変数の格納されているメモリ上の先頭アドレス(Pointer)
を返します。
StrPtr関数の戻り値が 0& (長整数の0 )のときは 変数がどこにも格納されてい
ない状態を意味し、InputBox関数で[Cancel]ボタンが押されると、アドレス無しの
文字列変数が返されることになっています。

>
>この方法ですと、記述していない20年先の年月日のセルアドレスも
>分かるということになりますね。

う〜ん、確かに(-_-)
最終の日付のチェックが必要でしたかね?

【60783】Re:Find関数の使い方について
質問  Porta  - 09/3/14(土) 9:50 -

引用なし
パスワード
   ▼kanabun さん:
ありがとうございました。

好みで判断では悪いのですが…いや理屈があるかと思いますが

小生はApplication.InputBoxを使いたく(InputBoxは横長になりすぎるためですが)貴殿のInputBoxをApplication.InputBoxに変更しました。

そうすると、「Cancel」又は「×」を押したときの表示が
"入力値は有効な日付ではありません"となります。

また
 If ss = False Then
    MsgBox "Cancelが押されました", vbExclamation
  Exit Sub
 End If
を付け加えるとそれなりに表示できますが

例えば「Y」を入力してOKを押すとこの上のコード部分で
エラーが発生します。
inputboxにType:=1で無いためだと思いますが。

根本的なところを理解できていないのかも知れません…
InputBoxとApplication.InputBoxの基本的な理解が出来ていないから
こんな質問になってしましました。(お許しください)

【60784】Re:Find関数の使い方について
発言  kanabun  - 09/3/14(土) 11:48 -

引用なし
パスワード
   ▼Porta さん:

InputBox関数は InputBox$関数なので、返される値は文字列型となります。
だから
> Dim ss As String
と宣言しておいて、StrPtr(ss) でキャンセルされたときの判断をしている
わけです。

>小生はApplication.InputBoxを使いたく(InputBoxは横長になりすぎるためですが)貴殿のInputBoxをApplication.InputBoxに変更しました。
>
>そうすると、「Cancel」又は「×」を押したときの表示が
>"入力値は有効な日付ではありません"となります。

Application.InputBox のばあいは、すでにおやりになっているように、
Dim ch (As Variant)
と Variant型変数で受けて、戻り値が Falseだったら Cancelされたことを
判定してください。
そのあと、「有効な日付」かどうかは 別途、
IsDate(ch)
で判別することになるんでしょうか


>
>また
> If ss = False Then
>    MsgBox "Cancelが押されました", vbExclamation
>   Exit Sub
> End If
>を付け加えるとそれなりに表示できますが
>
>例えば「Y」を入力してOKを押すとこの上のコード部分で
>エラーが発生します。
>inputboxにType:=1で無いためだと思いますが。
>
>根本的なところを理解できていないのかも知れません…
>InputBoxとApplication.InputBoxの基本的な理解が出来ていないから
>こんな質問になってしましました。(お許しください)

【60789】Re:Find関数の使い方について
お礼  Porta  - 09/3/14(土) 20:50 -

引用なし
パスワード
   ▼kanabun さん:

有難うございました。非常に勉強になりました。
今後ともよろしくお願いします。
CStrやCDateもすぐには頭に出ないコードを
勉強できて、ハッピーでした。
有難うございました。

3672 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free