Excel VBA質問箱 IV

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

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


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

【27262】確認方法 じゅん 05/8/3(水) 19:49 質問[未読]
【27263】Re:確認方法 つん 05/8/3(水) 20:25 回答[未読]
【27265】Re:確認方法 りん 05/8/3(水) 21:26 回答[未読]
【27299】Re:確認方法 じゅん 05/8/4(木) 15:46 質問[未読]
【27300】Re:確認方法 つん 05/8/4(木) 16:14 回答[未読]
【27301】Re:確認方法 Jaka 05/8/4(木) 16:23 発言[未読]
【27302】Re:確認方法 つん 05/8/4(木) 16:39 発言[未読]
【27303】Re:確認方法 でれすけ 05/8/4(木) 16:52 回答[未読]
【27305】Re:確認方法 ichinose 05/8/4(木) 17:01 発言[未読]
【27319】Re:確認方法 じゅん 05/8/5(金) 11:42 お礼[未読]

【27262】確認方法
質問  じゅん  - 05/8/3(水) 19:49 -

引用なし
パスワード
   どうしても分からないため、みなさまのお力添えをいただきたく、
質問させて下さい。

Application.InputBoxにて、セル参照(Rangeオブジェクト)
のタイプでデータを取得します。
指定した行数(セルではなく)を削除するようにしたいのですが、
例えば、30行目〜50行目以外を指定した場合は
「削除できない」ようにしたいのです。

第一の確認方法として、
InputBoxで取得したデータの中にアルファベットが入っていたら、
セルを参照している証拠なので、NG
ということはしました。

しかし、その他の確認方法がどうしても分かりません。
カンマで分けたり、力技で行おうと思えば出来るのかもしれませんが、
途方もない時間をかけた割には、たかがしれてる処理だと思うので、
どうにか簡単に確認する方法はないか教えていただきたいと思っています。

何か画期的な方法がありましたら、ぜひ教えて下さい!
よろしくお願いします。

【27263】Re:確認方法
回答  つん E-MAIL  - 05/8/3(水) 20:25 -

引用なし
パスワード
   こんばんは^^

>Application.InputBoxにて、セル参照(Rangeオブジェクト)
>のタイプでデータを取得します。
>指定した行数(セルではなく)を削除するようにしたいのですが、
>例えば、30行目〜50行目以外を指定した場合は
>「削除できない」ようにしたいのです。
>
>第一の確認方法として、
>InputBoxで取得したデータの中にアルファベットが入っていたら、
>セルを参照している証拠なので、NG
>ということはしました。
>
>しかし、その他の確認方法がどうしても分かりません。
>カンマで分けたり、力技で行おうと思えば出来るのかもしれませんが、
>途方もない時間をかけた割には、たかがしれてる処理だと思うので、
>どうにか簡単に確認する方法はないか教えていただきたいと思っています。
>
>何か画期的な方法がありましたら、ぜひ教えて下さい!
>よろしくお願いします。

これって、InputBoxで行全体を選択して・・・ってことですよね?
で、30行目〜50行目以外は無効にしたいって・・・
それでしたら、取得した行の行番号と行数を取得したらいいんでは?

Sub test()

  Dim r As Range
  
  Set r = Application.InputBox("test", "test", , , , , , 8)
  
  MsgBox r.Row
  MsgBox r.Rows.Count

  Set r = Nothing

End Sub

こんな感じで・・・
画期的かどうかはわかりませんが・・・

【27265】Re:確認方法
回答  りん E-MAIL  - 05/8/3(水) 21:26 -

引用なし
パスワード
   じゅん さん、つん さん、こんばんわ。

>Application.InputBoxにて、セル参照(Rangeオブジェクト)
>のタイプでデータを取得します。
>指定した行数(セルではなく)を削除するようにしたいのですが、
Sub test()
  Dim r1 As Range
  On Error Resume Next 'キャンセル対策
  Set r1 = Application.InputBox("行単位で選択してね", "行選択", Type:=8)
  On Error GoTo 0
  '行全体を選択しているときに削除
  If Not r1 Is Nothing Then
   '行全体に範囲を拡張したものと同じならば削除
   If r1.Address = r1.EntireRow.Address Then
     r1.Delete
   Else
     MsgBox "行単位で選択してね", vbExclamation
   End If
  End If
  Set r1 = Nothing
End Sub

ただし、行単位で削除したいということならば、こちらのほうが入力する人も簡単かも。
Sub test()
  Dim r1 As Range
  On Error Resume Next 'キャンセル対策
  On Error GoTo 0
  Set r1 = Application.InputBox("範囲を選択してね", "選択", Type:=8)
  '行全体で削除
  If Not r1 Is Nothing Then
   With r1.EntireRow
     If MsgBox(.Address(False, False) & "を削除します", vbOKCancel) _
     = vbOK Then .Delete
   End With
  End If
  Set r1 = Nothing
End Sub
こんな感じです。

【27299】Re:確認方法
質問  じゅん  - 05/8/4(木) 15:46 -

引用なし
パスワード
   つんさま、りんさま

ご教授下さいまして、本当にありがとうございます!
新たな発見などもあり、さらなる成長が出来たと思っています。

早速、記載していただいたことを実践してみましたが、
行いたいことと相違がありました。
私の良くない記述のせいで、ご迷惑をおかけします。

もう少し細かく書かせていただきたいのですが、
最初に書かせていただいた30〜50行目を
再度例にとらせていただきます。

InputBoxから35行目を選択すると、「$35:$35」となりますよね。
これは、30〜50行目内なので、OKです。
次に20行目を選択すると、「$20:$20」となりますよね。
これは、30〜50行目外なので、NGです。

このように、1行のみ指定された場合は、
rowメソッドを使用して判断できます。

しかし、複数行指定した場合、
「$30:$35」や「$28:$30」、「$20,$25」などを判断する方法
が分かりません・・・
rowメソッドで取得しようにも、最初の行(「$30:$35」なら$30のみ)
しか取得してくれず、$30, $31, $32, $33, $34, $35と認識してくれないと
困る気がします。

このレベルになると、セル内の文字などで判断するしかないでしょうか?
(Aの列に*が書かれている行が書かれているかなど)

個人的には、「$30:$35,$38,$40,$45:$51」と選択した場合には、
$30, $31, $32, $33, $34, $35, $38, $40, $45, $51
と区切られ、一つ一つに対して確認できればと思うのですが、
この方法以外にありますでしょうか?
(上記方法は、力技では何とかなると思いますが、時間がかかる上、
そこまでかけていられない都合もあります)

長くなってしまい、大変申し訳ありませんが、少しでも意図が
伝わったらと思います。

どうぞよろしくお願い致します。

【27300】Re:確認方法
回答  つん E-MAIL  - 05/8/4(木) 16:14 -

引用なし
パスワード
   こんにちは^^

>このように、1行のみ指定された場合は、
>rowメソッドを使用して判断できます。
>
>しかし、複数行指定した場合、
>「$30:$35」や「$28:$30」、「$20,$25」などを判断する方法
>が分かりません・・・

Rows.Count と併せて判断させてやればいいんじゃないですか?

Row で、最初の行の行番号が取得できますよね?
Rows.Count で、選択された行の行数が取得できますよね?

この二つで、選択された最終行の行番号が取得できると思います。

「$20,$25」みたいに飛び地になってる場合は

Areas.Count 使えばいいかな?

【27301】Re:確認方法
発言  Jaka  - 05/8/4(木) 16:23 -

引用なし
パスワード
   こんにちは。
先々週?作った奴、InputBoxじゃないけど...。
つんさんにあげる。

Sub 許可テスト飛び飛びOK()
  Dim 許可範囲 As Range, 選択範囲 As Range, Flg As Boolean
  'Set 許可範囲 = Columns(3).Resize(, 3)  'OK
  Set 許可範囲 = Range("C3:E5").EntireColumn 'OK
  'Set 許可範囲 = Columns("C:E") 'OK
  'Set 許可範囲 = Rows(3).Resize(3) 'OK
  'Set 許可範囲 = Range("B2:E10") 'OK
  
  For Each 選択範囲 In Selection.Areas
    If 選択許可範囲内か(許可範囲, 選択範囲) = False Then
      Flg = True
      Exit For
    End If
  Next
  If Flg Then
    MsgBox "選択されたセルは、許可範囲 " & 許可範囲.Address(0, 0) & _
       " から、外れている物があります。"
  Else
    MsgBox "選択されたセルは、許可範囲 " & 許可範囲.Address(0, 0) & _
       " 内に全て入ってます。"
  End If
  Set 許可範囲 = Nothing
End Sub

Function 選択許可範囲内か(許可範囲 As Range, 選択範囲 As Range) As Boolean
  Dim 許可行上 As Long, 許可行下 As Long, 許可左列 As Long, 許可右列 As Long
  Dim 選択行上 As Long, 選択行下 As Long, 選択左列 As Long, 選択右列 As Long

  If Application.Intersect(選択範囲, 許可範囲) Is Nothing Then
   選択許可範囲内か = False
   Exit Function
  End If
 
  With 許可範囲
    許可行上 = .Cells(1).Row
    許可行下 = .Cells(.Cells.Count).Row
    許可左列 = .Cells(1).Column
    許可右列 = .Cells(.Cells.Count).Column
  End With
 
  With 選択範囲
    選択行上 = .Cells(1).Row
    選択行下 = .Cells(.Cells.Count).Row
    選択左列 = .Cells(1).Column
    選択右列 = .Cells(.Cells.Count).Column
  End With
 
  If 許可行上 <= 選択行上 And 許可行下 >= 選択行下 And _
   許可左列 <= 選択左列 And 許可右列 >= 選択右列 Then
   選択許可範囲内か = True
  Else
   選択許可範囲内か = False
  End If
End Function

【27302】Re:確認方法
発言  つん E-MAIL  - 05/8/4(木) 16:39 -

引用なし
パスワード
   ▼Jaka さん〜

あんがと〜
Jakaさんコードをもとにアレンジしてみるわ〜
って、私の質問ちゃうねんけど(笑)

【27303】Re:確認方法
回答  でれすけ  - 05/8/4(木) 16:52 -

引用なし
パスワード
   こんにちは。

こんな感じででどうでしょうか。
Intersectを使って選択をした範囲を30行〜50行の範囲に
絞り込んでしまいます。

Dim DelRow As Range

On Error Resume Next
  Set DelRow = Application.InputBox("セルまたは列を選択してください", Type:=8)
  If DelRow Is Nothing Then Exit Sub
On Error GoTo 0

Set DelRow = Intersect(Rows("30:50"), DelRow)
If DelRow Is Nothing Then Exit Sub

Set DelRow = DelRow.EntireRow
DelRow.Select

If MsgBox("現在選択されている行を削除します。よろしいですか", vbOKOnly) = vbYes Then
 DelRow.Delete
End If

【27305】Re:確認方法
発言  ichinose  - 05/8/4(木) 17:01 -

引用なし
パスワード
   こんばんは、皆さん。

でれすけさんのコードで機能を果たしていると思いますが。

>rowメソッドで取得しようにも、最初の行(「$30:$35」なら$30のみ)
>しか取得してくれず、$30, $31, $32, $33, $34, $35と認識してくれないと
>困る気がします。
困る理由もわかりませんが、一行ずつ取得したいなら、
'=====================================================
Sub main()
  On Error Resume Next
  Dim rng As Range
  Dim ans As Range
  Dim chkrng As Range
  Set chkrng = Rows("30:50")
  Set rng = Application.InputBox("", , , , , , , 8)
  If Err.Number = 0 Then
    Set ans = Application.Intersect(chkrng, rng.EntireRow)
    If Not ans Is Nothing Then
     For Each are In ans.Areas
      With are
      For idx = 1 To .Rows.Count
        MsgBox .Rows(idx).Address & " は削除可能セル範囲"
        ' 実際の削除処理
        Next
      End With
     Next
    Else
     MsgBox "nogood"
     End If
    End If
End Sub

【27319】Re:確認方法
お礼  じゅん  - 05/8/5(金) 11:42 -

引用なし
パスワード
   みなさま
多大なお力、本当にありがとうございました!

おかげでさまで、自分の考えていたことが実現できそうです!
今回、特に大発見だったのが「Intersect」関数です。
こんな便利なものがあったなんて!
これがあれば、一つ一つの行を確認する必要はないですね。

自分の未熟さを痛感したと同時に、こんなにもすごい方々が
いらっしゃることを実感致しました!

これから作成に入らせていただきますが、もしまた困ったことが
あった際には、改めて質問させて下さい。

それにしても、真剣に色々悩んで、自分ではどうしようもないと思い
投稿させていただいたのですが、解決策が見つかると、
もっと早く投稿していればなぁと思いますね。。
(考えた分、成長には繋がると思いますが)

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