プロが教えるわが家の防犯対策術!

お世話になっております。

ワークシートの有無を確認してからシートを削除するマクロを作りたいと思っています。
特定の名前のシートを削除するマクロを以前、こちらで頂いたので、
それをカスタマイズしようと思ったのですが、、、まだ実力不足でできませんでした。

以前いただいたマクロはこちらです
「EXCEL-VBA ワークシートを4枚削除するマクロを作成したい」
https://bitly.is/1g3AhR6

カスタマイズできなかった理由ですが、
確認するシート名がSheetAのA20、A21、A22にあります。

要するに取得したA20、A21、A22値を元にワークシートの有無を
確認しなければならないのですが、そのためのコードが書けませんでした。

すいませんが詳しい方、説明の上手な方、直接、コードで説明できる方、
教えて下さい。よろしくお願いします。

コードはリンク先のものを利用して頂いてもOKですし、
新規に書き上げて頂いてもOKです。

お手数ですが、よろしくお願いします。

追記
前回、教えて頂いたtatsu99さん、tom04さん、bonaronさん、
ありがとうございました。

質問者からの補足コメント

  • どう思う?

    補足です
    A20、A21、A22の値の名前のワークシートがあれば、
    3枚とも削除します。一応、追記しておきます。

    ※もし可能でしたら、「~シートにはデータが存在する可能性があります~」の
    確認メッセージの表示なしにできればありがたいです。

    すいませんがよろしくおねがいします。

      補足日時:2016/12/12 11:47
  • うれしい

    みなさんいつも丁寧なご解答ありがとうございます。

    今夜(12日夜)、明日(13日終日)と多忙のため、
    頂いたご解答を確認出来ません。
    ちょっと空きますが14日以降に確認の上、
    ご返答、ベストアンサーの付与、etc.をさせて頂きます。


    tom04さん
    ご解答ありがとうございます。動作確認しております。
    とりあえずコードを利用させて頂いており、ベストアンサー候補です。
    いつもご解答頂きありがとうございます。

    tatsu99さん
    リンクが機能せずにすいませんでした。
    2回目のご解答ありがとうございます。
    頂いたコードを確認の上、後日、お礼をさせて頂きます。
    今回は本当にありがとうございます。

    くんこばさん
    2回目のご解答ありがとうございます。
    良い機会なので、基礎的なことで聞いてみたいことがあります。
    なのでしばらく質問をあけておきます。
    いつもご解答ありがとうございます。

      補足日時:2016/12/12 20:27

A 回答 (11件中1~10件)

https://bitly.is/1g3AhR6
を見ようとおもったのですが、ログインしないとソースは見れないようです。
ログインの方法を教えてください。

参考までに、下記のサイトはログインなしで、誰もが利用可能です。(私はこちらを利用しています)
http://climbi.com/
    • good
    • 1
この回答へのお礼

ご解答ありがとうございます。

こちらのミスでリンク先が閲覧できずにすいません。
↓リンク先はこちらです

「EXCEL-VBA ワークシートを4枚削除するマクロを作成したい」
https://oshiete.goo.ne.jp/qa/9543475.html

ログイン中のままショートURLをコピーしてしまいました。
通常の閲覧するURLをそのままコピーしましたので、
これで大丈夫だと思います。

すいませんがよろしくお願いします。

お礼日時:2016/12/12 17:19

シートが存在すればtrue、なければfalse。


これじゃダメ?
Public Function f000_sample(str As String) As Boolean
On Error GoTo exit_kb
Dim ret As Boolean
ret = False
Worksheets(str).Name = str
ret = True
exit_kb:
f000_sample = ret
End Function
    • good
    • 0
この回答へのお礼

ご解答ありがとうございます。

あまりにもレベルの低い話で申し訳ないです。
使い方が全くわかりません。

Subプロシージャーの名前はどうすればいいの?
取得するための名前SheetAのA20、A21、A22はどこで参照するの?

という感じです。
せっかくご解答頂いたのですが、ちょっと今回のご解答ではしんどいです。

前回はアドバイスありがとうございました。
今回はこちらのレベルが低いので、ご解答の意味がわかりませんでしたが、
機会がありましたら、またお願いいたします。

お礼日時:2016/12/12 18:46

こんにちは!



>A20、A21、A22の値の名前のワークシートがあれば
「Sheet1」のA20~A22の範囲とします。

一例です。

Sub Sample1()
Dim k As Long, myRng As Range, c As Range
Set myRng = Worksheets("Sheet1").Range("A20:A22")
For k = Worksheets.Count To 2 Step -1 '←シート見出しの最後から2番目まで//
Set c = myRng.Find(what:=Worksheets(k).Name, LookIn:=xlValues, lookat:=xlWhole)
If Not c Is Nothing Then
Application.DisplayAlerts = False
Worksheets(k).Delete
Application.DisplayAlerts = True
End If
Next k
End Sub

こんな感じではどうでしょうか?m(_ _)m
    • good
    • 1
この回答へのお礼

No.11のご解答で少し触れたとおり、
いきなりベストアンサーのご解答です。

ですがベストアンサーをつけると質問が閉じてしまいます。
なので、お礼が遅れてしまいすいませんでした。

一応、こちらも入力させて頂きました。

お礼日時:2016/12/14 23:36

あ、やっぱり説明不足になりましたか。


サブプロシージャとか分かります?

このコードは、strにシート名を指定すると、その存在を判定してくれる関数になります。
VBA開いて、プロシージャに貼り付ければ、ワークシート関数としても利用出来ます。
内容としては非常に簡単で、シートが存在しない場合エラーとなる処理があります。
エラーとなったら存在しない、と判断してるわけです。
これだとコードは少なくて済みますので。

ちょっと変数名とか、適当過ぎましたね。
(^_^ ; )

利用方法としては、削除前にその判定を入れて、trueの時だけ削除するようにします。

帰宅して余裕があればコードも載せれますが、ちょっと厳しいかも…
    • good
    • 0

以下のようにしてください。

標準マクロへ登録します。
----------------------------------------------
Option Explicit

Public Sub Macro1()
Dim sh1 As Worksheet
Dim row As Long
Dim sheetName As String
Dim ctr As Long
ctr = 0
Set sh1 = Worksheets("SheetA")
'20行~22行のA列を参照する
For row = 20 To 22
sheetName = sh1.Cells(row, "A").Value
'シート名が空白でなく、且つ、存在するなら削除する
If sheetName <> "" Then
If ExistsWorkSheet(sheetName) = True Then
Application.DisplayAlerts = False 'シート削除時の警告を出さないようにする
Worksheets(sheetName).Delete '該当シートを削除する
Application.DisplayAlerts = True 'シート削除時の警告を出すようにする(元に戻す)
ctr = ctr + 1
MsgBox ("[" & sheetName & "]の削除完了")
End If
End If
Next
MsgBox (ctr & "件削除完了")
End Sub

'ワークシートの存在チェック
Public Function ExistsWorkSheet(ByVal sheetName As String) As Boolean
Dim ws As Worksheet
ExistsWorkSheet = False
For Each ws In Worksheets
If UCase(ws.Name) = UCase(sheetName) Then
ExistsWorkSheet = True
Exit Function
End If
Next ws
End Function
---------------------------------------------
尚、以前、私が回答したマクロですが、
マクロの存在チェック(ExistsWorkSheet)にバグがありました。
バグの内容は、excelのシート名は大文字、小文字を区別しない為、
ブック中に[sheet1]が存在した状態で、[SHEET1]の存在チェックを行うと、Falseが返ってしまい、
存在しない扱いになってしまうことです。(シート名がSheet1でも同様です)
今回は、この不具合を修正しました。(両方、大文字にした後で比較するようにしました)
申し訳ありませんが、
以前のExistsWorkSheetは、今回提示したExistsWorkSheetで置き換えてください。
お詫びして訂正いたします。

又、マクロ中で確認の意味でメッセージボックスを表示していますが
不要であれば、削除してください。
    • good
    • 1
この回答へのお礼

ご解答ありがとうございます。

動作確認致しました。
いろいろやってみたのですが、「'」以下にコメントをつけて頂いており
わかりやすくて助かりました。

加えて、削除時に確認のメッセージを出さないコードを
挿入して頂きありがとうございます。

いつも質問内容をよく読んで頂いたコードを書いて頂き
本当にありがとうございます。機会がありましたらまたお願いいたします。

----------
追記
もしお手数でなければこの機会に
1個教えて頂きたいことがあります。

くんこばさんとのやりとりで
「サブプロシージャーしかわからない」という話がありました。

で、、、私もステップアップしたいので、
tatsu99さんがよく使う、「Public Sub 名前()」のプロシージャーを
理解したいと思っています。

不思議に思っていたのですが、
今回のマクロは
Public Sub Macro1()

End Sub

End Function

とEnd のついたところが2つあります。

Public Sub 名前()というプロシージの時は

End Sub

End Function
の2つEndが必要ということでしょうか?

お手数でなければこれだけ教えて下さい。
ヒントにしていろいろ調べたいと思います。

お礼日時:2016/12/14 10:30

No4の方へ


あまり、回答者同士で批判しあうのは、好みませんが、1っだけ言わせてください。

>このコードは、strにシート名を指定すると、その存在を判定してくれる関数になります。
>VBA開いて、プロシージャに貼り付ければ、ワークシート関数としても利用出来ます。
>内容としては非常に簡単で、シートが存在しない場合エラーとなる処理があります。
>エラーとなったら存在しない、と判断してるわけです。

ということですが。
No2のソースは簡潔で素晴らしいのですが、1つ欠点がございます。
それは、そのFunctionを呼び出すと、シート名を変えてしまうことです。
例えば、ブック中に"sheet1"のシートがあり、"SHEET1"が存在するかどうかの
チェックの為、そのFunctionを呼び出すと、シート名が"SHEET1"に変わってしまいます。

従って、No2のFunctionをワークシート関数等の汎用的な関数として利用すると、
いつのまにか、シート名が変わっていて、利用者がおやっと思う可能性があります。
ですので、シート名を変えないで、シートの存在チェックを行うように改良していただければ、
そちらのほうが良いかと思います。
    • good
    • 1

'==============================================================


' シート名の存在チェック
'==============================================================
Public Function CheckExistSheet(sheetname As String) As Boolean
On Error GoTo exit_proc
Dim ret As Boolean
ret = False
Worksheets(sheetname).Name = sheetname
ret = True
exit_proc:
CheckExistSheet= ret
End Function

いつか理解できる日が来ることを願って。
    • good
    • 0
この回答へのお礼

ご解答ありがとうございます。

一応、やってみたのですが、
やっぱりわかりませんでした。
くんこばさんのコメントのにあるように
今の実力では理解出来ないです。

せっかくご解答頂いたのにすいません。
また機会がありましたらよろしくお願いします。


追記
サブプロシージャーはわかりますよ。
Public ~ とか、関数を自作するもの
とかもあったと思います。

ガイドブックで読んでそういうのがある、、、
というのは知っていますが理解して使えるのはサブプロシージャだけです。

お礼日時:2016/12/14 10:00

No.7 さんへ



No.6 さんのご指摘について No.7 でも改善されていないので、
その対策を。

代入を逆向きにすれば良いですね。

Public Function CheckExistSheet(ByVal sheetname As String) As Boolean
  On Error GoTo exit_proc
  Dim ret As Boolean
  ret = False
  sheetname = Worksheets(sheetname).Name
  ret = True
exit_proc:
  CheckExistSheet = ret
End Function

あるいは
Worksheets(sheetname).Name = Worksheets(sheetname).Name & ""
とか。
    • good
    • 1
この回答へのお礼

ご解答ありがとうございます。

くんこばさんのコメントに記載させていただいた通り、
今のところ実力不足でサブプロシージャーを使ったものか、
コピペで動作するものでないと使いこなせません。

せっかくご解答頂いたのですが、こちらの実力不足で
理解できずすいません。
機会がありましたら、またよろしくお願いします。

追記
私のページ経由でみなさんが情報交換をして頂いてレベルアップできれば
それは価値があると思います。
なので、機会がありましたら、遠慮なさらずに、またお願いいたします。

今回はご解答ありがとうございました。

お礼日時:2016/12/14 10:04

No5です。


>不思議に思っていたのですが、
>今回のマクロは
>Public Sub Macro1()
>~
>End Sub
>~
>End Function
>とEnd のついたところが2つあります。
>Public Sub 名前()というプロシージの時は
>End Sub
>~
>End Function
>の2つEndが必要ということでしょうか?


私が提供したマクロは
マクロ本体の

Public Sub Macro1()

End Sub

とサブプロシージャである
'ワークシートの存在チェック

Public Function ExistsWorkSheet(ByVal sheetName As String) As Boolean

End Function

の2つからできています。
サブプロシージャは、ほかのプロシージャから呼び出されることを前提に
作っています。
この②は、引数で指定されたワークシート名が、ブック中に存在するか否かのチェックを行い、
存在すれば、true、しなければ、falseを返す処理をおこないます。
①のなかで、
If ExistsWorkSheet(sheetName) = True Then
のステートメントがありますが、これが、実際に②を呼び出している部分です。
sheetNameには、A20~A22の内容がセットされるので、このA20~A22のシートがあるかどうか
の判断を行っていることになります。
サブプロシージャは、他のプロシージャからも呼び出せます。
もし、今回、
Public Sub Macro1()
End Sub
の後に
Public Sub Macro2()
End Sub
Public Sub Macro3()
End Sub
のように2つのプロシージャを追加した場合、
②のExistsWorkSheetをMacro2,Macro3から呼び出すことができます。

サブプロシージャを作ると、何が嬉しいのかということですが、
「同じプログラムを2度書かないですむ」ということです。
今回の②のExistsWorkSheetを1度作成しておけば、
今後、どのプロシージャからでも、このExistsWorkSheetを呼び出せば
簡単にワークシートの存在の有無のチェックが可能になります。

尚、くんこばさんが提供された
No2の
Function f000_sample
No7の
CheckExistSheet
もこれに該当します。

今回、私の②のExistsWorkSheetと
くんこばさんのf000_sample、CheckExistSheet
は全く同じ、引数、戻り値なので
私のMacro1の中の
If ExistsWorkSheet(sheetName) = True Then のかわりに
If f000_sample(sheetName) = True Then か
If CheckExistSheet(sheetName) = True Then としても
全く同じ結果になります。

但し、くんこばさんのマクロを使用すると、
No6で私が指摘したように、シート名が変わってしまいます。
(Sheet1があった状態で、SHEET1があるかチェックをするとシート名がSHEET1になります)
今回の案件の場合は、シートがあれば、削除するので、シート名が変わっても、どのみち
問題ないのですが、
シートの有無のチェックだけを行い、あっても、なくても、そのシートを削除しない場合に
問題になります。

時間があれば、自分で以下の確認をしてください。
くんこばさんのCheckExistSheetを登録します。
更に、以下のマクロを作成し、実行してください。
Public Sub MacroXXX()
If ExistsWorkSheet("SHEET1") Then
MsgBox ("SHEET1あり")
Else
MsgBox ("SHEET1なし")
End If
End Sub

実行時、Sheet1が存在する状態で呼び出すと、「SHEET1あり」が表示され、その後、
Sheet1がSHEET1に代わります。Sheet1がない状態で呼び出すと、「SHEET1なし」が
表示されます。
尚、このシート名が変わってしまうのは、よくないので、これを変えたい場合は、
No8でbonaronさんが提示した方法を採用すればよいかと。
    • good
    • 1
この回答へのお礼

ご解答ありがとうございます。

なんとなくですが前半はわかりました。

すいませんが後半がよくわかりませんでした。
特に「~くんこばさんのCheckExistSheetを登録します。~」
というのは以下のようにマクロをつなげて
マクロを実行してみなさい、、、ということだと思ったのですが、、、
やってみたところエラーで止まります。

なので、、、多分、
「~くんこばさんのCheckExistSheetを登録します。~」
という言葉の意味を私が間違って解釈しているのだと思います。
----以下のマクロです。

頂いたご解答を改めて読み返して、いろいろと自分で確認してみたいと思います。
今回は丁寧なご解答を頂き、本当にありがとうございます。

本当なら文句なしのベストアンサーですが、、、
tom04さんに、リンクがつながらない状態で
カスタマイズしやすいコードを頂いております。

なので、今回は tom04さんにベストアンサーをゆずらせて頂きます。
今回は何度も丁寧なご解答ありがとうございます。
機会がありましたら、ぜひお願いいたします。

※頂いたアドバイスは後程ゆっくり読み返して頑張ってみます。


--------
'「~くんこばさんのCheckExistSheetを登録します。~」
Public Sub MacroXXX()
If ExistsWorkSheet("SHEET1") Then
MsgBox ("SHEET1あり")
Else
MsgBox ("SHEET1なし")
End If
End Sub

Public Function CheckExistSheet(sheetname As String) As Boolean
On Error GoTo exit_proc
Dim ret As Boolean
ret = False
Worksheets(sheetname).Name = sheetname
ret = True
exit_proc:
CheckExistSheet = ret
End Function

お礼日時:2016/12/14 19:41

No9です。


>マクロを実行してみなさい、、、ということだと思ったのですが、、、
>やってみたところエラーで止まります。

すみません。私の誤りでした。
Public Sub MacroXXX()
If ExistsWorkSheet("SHEET1") Then
MsgBox ("SHEET1あり")
Else
MsgBox ("SHEET1なし")
End If
End Sub


If ExistsWorkSheet("SHEET1") Then

If CheckExistSheet("SHEET1") Then
に変えてください。

大変、失礼しました。お詫びして訂正いたします。
    • good
    • 1
この回答へのお礼

何度もご解答ありがとうございます。

図々しい話ですが、もしかして、ネット上にいらっしゃるかも、、、と思いました。
なので職場からお礼をコメントさせて頂き
自宅に帰ってtatsu99さんのご解答を確認してから、
tom04さんにお礼&ベストアンサーの入力をして質問を閉じるつもりでした。

今夏は何度もご解答頂き本当にありがとうございます。
こちらの操作、解釈が間違っていなかったようですので、
ステップアップの良いきかっけになりました。

これからは時々

Public Sub Macro1()

End Sub

Public Function

End Function

のパターンでコードを書いたりカスタマイズしてみようと思います。

今回は何度も本当にありがとうございました。機会がありましたら、またお願いします。

お礼日時:2016/12/14 22:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!