Excel VBA質問箱 IV

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

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


2549 / 13646 ツリー ←次へ | 前へ→

【67316】Findでシートと行を範囲指定して検索する方法 まめ 10/11/23(火) 22:54 質問[未読]
【67317】Re:Findでシートと行を範囲指定して検索す... Hirofumi 10/11/24(水) 9:12 回答[未読]
【67318】Re:Findでシートと行を範囲指定して検索す... Hirofumi 10/11/24(水) 9:48 回答[未読]
【67349】Re:Findでシートと行を範囲指定して検索す... まめ 10/11/27(土) 1:38 お礼[未読]
【67319】Re:Findでシートと行を範囲指定して検索す... UO3 10/11/24(水) 10:49 発言[未読]
【67320】Re:Findでシートと行を範囲指定して検索す... UO3 10/11/24(水) 11:21 発言[未読]
【67352】Re:Findでシートと行を範囲指定して検索す... まめ 10/11/27(土) 2:36 お礼[未読]

【67316】Findでシートと行を範囲指定して検索する...
質問  まめ  - 10/11/23(火) 22:54 -

引用なし
パスワード
   色々試してみて試行錯誤をし、サーチエンジンで検索もしたのですが、分からなくお力をお借りしたく質問させて頂いています。

一度は出来上がったコードだと思ったのですが、想定とは違った結果になってしまいました。
検証を行った結果、Findでの検索の範囲をシート全体としていた為想定とは違った列の値がかえってきているのが原因と分かりました。

検索の範囲を指定すればうまくいくだろうと思い
Set Obj = Worksheets("シフト").Cells.Find(day, LookAt:=xlWhole)
→Set Obj = Worksheets("シフト").Range("E3:AI3").Find(day, LookAt:=xlWhole)
の様に書き換えてみたりしたのですが上手く行かず・・・

上記のFindの検索の範囲指定を「〜シートの〜列目の変数dayを探す」と指定することは出来ますでしょうか。

以下が、書いているコードです。

Sub 抽出()
  Dim lngYLine As Long
  Dim intXLine As Integer
  Dim Obj As Object
  Dim day As Integer
  Dim ws As String
  day = Range("F4")
  ws = ActiveSheet.Name

  Set Obj = Worksheets("シフト").Cells.Find(day, LookAt:=xlWhole)
  If Obj Is Nothing Then
    MsgBox "対象の日付が見つかりませんでした。"
  Else
    lngYLine = Worksheets("シフト").Cells.Find(day).Row
    intXLine = Worksheets("シフト").Cells.Find(day).Column
  End If

For i = 6 To 38

  ActiveWorkbook.Worksheets("シフト").Activate
  If Not (Cells(i, intXLine).Value = "" Or Cells(i, intXLine).Value = "休" Or Cells(i, intXLine).Value = "有 ") Then

  If Cells(i, 2).Value <> "" Then
  With Worksheets(ws).Range("B9")
  .Value = .Value & Cells(i, 2).Value & "、"
  End With
  Else
  End If
  End If
Next i

ActiveWorkbook.Worksheets(ws).Activate

End Sub

以上、お力添え頂けましたら幸甚存じます。

【67317】Re:Findでシートと行を範囲指定して検索...
回答  Hirofumi  - 10/11/24(水) 9:12 -

引用なし
パスワード
   日付をFindで探すのは色々難しい見たい?
こんなのでは?

Sub 抽出_2()
  
  Dim lngYLine As Long
  Dim intXLine As Long
'  Dim Obj As Object
'  Dim day As Integer
'  Dim ws As String
  
  Dim i As Long
  Dim vntDay As Variant
  Dim vntDate() As Variant
  Dim wksList As Worksheet
  Dim ws As Worksheet
  
  Set wksList = ActiveWorkbook.Worksheets("シフト")
  
  vntDay = Range("F4").Value
  
  Set ws = ActiveSheet

'  Set Obj = Worksheets("シフト").Cells.Find(day, LookAt:=xlWhole)
'  If Obj Is Nothing Then
'    MsgBox "対象の日付が見つかりませんでした。"
'  Else
'    lngYLine = Worksheets("シフト").Cells.Find(day).Row
'    intXLine = Worksheets("シフト").Cells.Find(day).Column
'  End If
  '日付の行を配列として取得
  vntDate = wksList.Range("E3:AI3").Value
  '日付行を先頭から見て行く
  For i = 1 To UBound(vntDate, 2)
    'もし、Range("F4")と同じ日付が有ったらForを抜ける
    If vntDate(1, i) = vntDay Then
      Exit For
    End If
  Next i
  '日付が有った場合
  If i <= UBound(vntDate, 2) Then
    '行位置は固定
    lngYLine = 3
    'E列(5列目)からの列位置を取得
    intXLine = 5 + i - 1
  Else
    MsgBox "対象の日付が見つかりませんでした。"
  End If

  With wksList
    For i = 6 To 38
      If Not (.Cells(i, intXLine).Value = "" _
          Or .Cells(i, intXLine).Value = "休" _
              Or .Cells(i, intXLine).Value = "有 ") Then
        If .Cells(i, 2).Value <> "" Then
          ws.Range("B9").Value _
            = ws.Range("B9").Value & .Cells(i, 2).Value & "、"
        End If
      End If
    Next i
  End With
  
  ws.Activate

  Set wksList = Nothing
  Set ws = Nothing
  
End Sub

【67318】Re:Findでシートと行を範囲指定して検索...
回答  Hirofumi  - 10/11/24(水) 9:48 -

引用なし
パスワード
   Exit Subを書き忘れました

  Else
    MsgBox "対象の日付が見つかりませんでした。"
    Set wksList = Nothing '追加
    Set ws = Nothing '追加
    Exit Sub '追加
  End If

後、日付を探すのにMatch関数を使って善いかも?

【67319】Re:Findでシートと行を範囲指定して検索...
発言  UO3  - 10/11/24(水) 10:49 -

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

こんにちは

「〜シートの〜列目の変数dayを探す」と書いていらっしゃいますが
「〜シートの〜行目の指定領域内で変数dayを探す」ということですよね。

それと、日付と書いていらっしゃいますのでhirofumiさんも、日付型を前提とした
コメントを書いていらっしゃいますが、
Dim day As Integer
day = Range("F4")
と、ありますから、F4の値、および E3:AI3 内の値は 整数で 1〜31なんでしょうね?

うまくいかないというのが、どう、うまくいかなかったのですか?
少なくとも、こちらで、コピペして F4 および E3:AI3 に適当な数値をいれて動かすと
存在する場合はlngYLine、lngXLineに、正しい数値がはいりますし、存在しなかったら
存在しないということを把握できています。

むしろ、存在しなかった場合、【おかまいなし】に、後半の処理をしているのが気になります。
(それと、変数 i が規定されていませんね。Option Explicit の記述はないのですか?)

コードにインデントをつけますと、以下のようになっていますよ。

Option Explicit

Sub 抽出()
 Dim lngYLine As Long
 Dim intXLine As Integer
 Dim Obj As Object
 Dim day As Integer
 Dim ws As String
 Dim i As Long
 
 day = Range("F4")
 ws = ActiveSheet.Name

 Set Obj = Worksheets("シフト").Range("E3:AI3").Find(day, LookAt:=xlWhole)
 If Obj Is Nothing Then
   MsgBox "対象の日付が見つかりませんでした。"
 Else
   lngYLine = Worksheets("シフト").Cells.Find(day).Row
   intXLine = Worksheets("シフト").Cells.Find(day).Column
 End If

 For i = 6 To 38  '見つからなかった場合も、これ以降実行???

  ActiveWorkbook.Worksheets("シフト").Activate
  If Not (Cells(i, intXLine).Value = "" Or Cells(i, intXLine).Value = "休" Or Cells(i, intXLine).Value = "有 ") Then

   If Cells(i, 2).Value <> "" Then
    With Worksheets(ws).Range("B9")
     .Value = .Value & Cells(i, 2).Value & "、"
    End With
   Else     '<=== このコードは不要でしょ?
   End If
  End If
 Next i

 ActiveWorkbook.Worksheets(ws).Activate

End Sub

【67320】Re:Findでシートと行を範囲指定して検索...
発言  UO3  - 10/11/24(水) 11:21 -

引用なし
パスワード
   補足というか参考情報です。


【日付】が【1〜31の整数】だとして、Findではない方法で場所を取得するサンプルです。
Sample2 は E列が1、F列が2、G列が3・・・となっていることが前提ですが。


Option Explicit

Sub Sample1()
 Dim lngYLine As Long
 Dim intXLine As Variant '見つからなかったときのエラー値を格納するためVariant
 Dim day As Long     'A4に大きな値が入っている場合の障害を想定してLong
 Dim okFlag As Boolean
 With Worksheets("シフト")
  day = Val(.Range("A4").Value)
  lngYLine = 3
  intXLine = Application.Match(day, .Range("E3:AI3"), 0)
  If IsNumeric(intXLine) Then
   intXLine = intXLine + .Columns("D:D").Column
   If .Cells(lngYLine, intXLine).Value = day Then okFlag = True
  End If
  
  If Not okFlag Then
   MsgBox "対象の日付が見つかりませんでした。"
  Else
   '後半のロジック
  End If
 End With
End Sub

Sub Sample2()
 Dim lngYLine As Long
 Dim intXLine As Integer
 Dim day As Long     'A4に大きな値が入っている場合の障害を想定してLong
 With Worksheets("シフト")
  day = Val(.Range("A4").Value)
  lngYLine = 3
  intXLine = day + .Columns("D:D").Column
  If .Cells(lngYLine, intXLine).Value <> day Then
   MsgBox "対象の日付が見つかりませんでした。"
  Else
   '後半のロジック
  End If
 End With
End Sub

【67349】Re:Findでシートと行を範囲指定して検索...
お礼  まめ  - 10/11/27(土) 1:38 -

引用なし
パスワード
   レスありがとうございます。
下記UO3さんから既にご指摘受けているのですが、
日付型ではなく、F4の値、および E3:AI3は整数なのです(汗
説明不足で申し訳ありません。

いま、ご教授頂いた方法で試しています。

付け足しでつたない説明を独り言のように追加させて頂きますと、

F4はシートA、E3:AI3はシートBとシートをまたがって行っております。

FindでシートB全体から探すと縦軸にも1から数字が連続で振ってあり、
そっちがE3:AI3(1〜31)よりも先に引っかかってしまい
上手くいきませんでしたので、シートAのF4の値(1〜31)を
シートBのE3:AI3(1〜31)の中(範囲を限定して)から見つけその列番号を変数 intXLine に格納するという書き方がしたく質問させて頂いた次第です。

ご教授頂いた方法と併せて
「Match関数を使って善いかも」という自分のレベルで理解できそうな
所から試行錯誤して行こうと思います。

【67352】Re:Findでシートと行を範囲指定して検索...
お礼  まめ  - 10/11/27(土) 2:36 -

引用なし
パスワード
   レスありがとうございます。
>
>「〜シートの〜列目の変数dayを探す」と書いていらっしゃいますが
>「〜シートの〜行目の指定領域内で変数dayを探す」ということですよね。
>はい、まさにその通りです。

>それと、日付と書いていらっしゃいますのでhirofumiさんも、日付型を前提とした
>コメントを書いていらっしゃいますが、
>Dim day As Integer
>day = Range("F4")
>と、ありますから、F4の値、および E3:AI3 内の値は 整数で 1〜31なんでしょうね?
>はい、hirofumiさんには私の説明不足で迷惑をお掛けしたかもで心苦しい思いです。追記で説明を加えるとF4はシートA、E3:AI3はシートBにあります。

>うまくいかないというのが、どう、うまくいかなかったのですか?
>少なくとも、こちらで、コピペして F4 および E3:AI3 に適当な数値をいれて動かすと
>存在する場合はlngYLine、lngXLineに、正しい数値がはいりますし、存在しなかったら
>存在しないということを把握できています。
>度々の説明不足で申し訳ありません、
FindでシートB全体から探すと縦軸にも1から数字が連続で振ってあり、
そっちがE3:AI3(1〜31)よりも先に引っかかってしまい
上手くいきませんでしたので、シートAのF4の値(1〜31)を
シートBのE3:AI3(1〜31)の中(範囲を限定して)から見つけその列番号を変数 intXLine に格納するという書き方がしたく質問させて頂いた次第です。

>むしろ、存在しなかった場合、【おかまいなし】に、後半の処理をしているのが気になります。
はい、Exit Subにて処理を抜けるようにします。

>(それと、変数 i が規定されていませんね。Option Explicit の記述はないのですか?)
>今まで行き当たりばったりでコードを書いておりまったく基本的なことも分かっておらず、度々のご指摘ありがとうございます、最近「大村あつし」著のVBAの基礎本を購入しました。少しずつ体系立てて覚えていこうと思っています・・・

ご教授いただきました事を踏まえて作業に取り掛かろうと思います。
また、結果が出ましたらきちんとお礼申し上げに参ります、今後ともよろしくお願い致します。

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