Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : 指定なし)
シートの検索
投稿日時: 19/05/21 22:01:57
投稿者: tomisuke

非常に多くのsheetがあるbook内で、特定の文字を含むsheetを検索して表示させていますが、ループを使った検索では時間がかかるために改良したいです。
お力を貸していただけると、幸いです。
 
今までの検索
 
Sub 検索()
Dim myWS As Worksheet
     
  On Error GoTo エラー処理
   
    For Each myWS In Worksheets
        If Not myWS.Name Like "*" & TextBox1.Value & "*" Then
            If Not ActiveSheet.Name Like "*" & TextBox1.Value & "*" Then
                myWS.Select (False)
            Else
                myWS.Select
            End If
        End If
    Next
  
ActiveWindow.SelectedSheets.Visible = False
Worksheets(Worksheets.Count).Visible = True
  
 Exit Sub
  
エラー処理:
   MsgBox ("存在しません")
End Sub
 
調べているうちにこのようなVBAを見つけたのですが、応用は可能ですか?
 
Sub SheetExists()
 
Dim wb As Workbook
Dim ws As Worksheet
 
Set wb = ThisWorkbook
 
On Error Resume Next
Set ws = wb.Worksheets("Sheet1") '←存在確認したいシートを指定
On Error GoTo 0
 
If Not ws Is Nothing Then 'Nothingならシートが存在しない
    ws.Select
Else
   MsgBox "存在しません"
End If
 
End Sub
 
このVBAだとsheet名が固定されており、いろいろ試したのですが上手くできませんでした。
また特定の文字を含んだsheetが複数あった場合に1つのsheetしか選択されませんでした。
特定の文字を含んだ複数のsheetを表示させるにはどうしたらよいのでしょうか?
説明が分かりにくく、お手数をおかけしますがよろしくお願い致します。

回答
投稿日時: 19/05/21 22:37:44
投稿者: simple

提示されたコードが良く理解できないのと、
時間がどの程度かかっているのか不明ですが、
それはともかくとして、
要件としては、

・特定の文字列を含むシートは表示し、
・含まないシートは非表示にしたい
ということですか?
 
ループでひとつひとつのシート名をチェックして、
含めば .Visible = True
含まなければ .Visible = Falseにしていく
と言う処理では何か問題があるのですか?
 
質問者さんのおっしゃる「存在確認したいシートを指定」して
存在チェックする方式ですが、
特定の文字列を含むシート名をどうやって直接指定するのですか?
特定の文字列以外の部分の文字列は可能性として無数にあるじゃないですか?
無理じゃないですか?
 
結局は、今あるシートをチェックすることになると思いますよ。

投稿日時: 19/05/21 22:55:55
投稿者: tomisuke

simple様、回答ありがとうございます。
要件としては、
 
・特定の文字列を含むシートは表示し、
・含まないシートは非表示にしたい
 
で、合っています。
 
ブック内のシートの数が多く、特定の文字を含むシートが複数あります。
この文字を含むシートのみを表示させたいのですが、ループを使って検索すると時間が掛かってしまうので、それをループを使わずに検索時間を短縮したいと思い、質問しました。
当方VBAについては素人同然であり、ネットで検索してみたところループを使わずに検索が出来そうなので利用できないかと思い質問させていただきました。
今までは、「特定の文字列」以外はワイルドカードを使い指定していたつもりでした。
 
VBAの知識が豊富なsimple様が出来ないという判断でしたら、自分には到底無理と思われます。
少しでも知識・助力を頂けたらと思いましたが、無理そうですね。
質問をもう少し残し、他の方からの回答がなければ諦めます。
ありがとうございました。

回答
投稿日時: 19/05/21 22:58:51
投稿者: simple

どのくらいの時間がかかっているのですか?

回答
投稿日時: 19/05/21 23:11:17
投稿者: 半平太

現在のシート数も教えて頂けませんか?
 
※悩むほどの時間が掛かるとは思えないのですが・・よっぽどなんでしょうね。

回答
投稿日時: 19/05/21 23:16:35
投稿者: WinArrow
投稿者のウェブサイトに移動

ヒントのコード紹介
複数のシートを選択する方法
 
Sub test()
Dim sht, wsht, sx As Long
 
    sx = 0
    ReDim wsht(sx)
    For Each sht In Sheets
        Select Case sht.Name
            Case "Sheet1", "Sheet4", "Sheet6"
                ReDim Preserve wsht(sx)
                wsht(sx) = sht.Name
                sx = sx + 1
        End Select
    Next
     
    Sheets(wsht).Select
    For Each sht In ActiveWindow.SelectedSheets
        Debug.Print sht.Name
    Next
     
End Sub

回答
投稿日時: 19/05/21 23:18:01
投稿者: simple

>今までは、「特定の文字列」以外はワイルドカードを使い指定していたつもりでした。
ということですが、
Sheet名の中に特定文字列が入っているかどうかの判断をLikeを使ってしていた、
ということならそうですね。
 
あなたは、Set ws = wb.Worksheets("Sheet1") '←存在確認したいシートを指定
と同様の書き方で
Set ws = wb.Worksheets("*" & 特定文字列 & "*")
のような書き方にトライしようとしているようですが、
ワイルドカードを使った直接指定はできませんよ、と申し上げています。
誰かが言っている、ということではなく、
ご自分で試して納得することをお薦めします。
 
ちなみに、↓ではまずいのですか?と申し上げています。

Sub 検索2()
    Dim ws As Worksheet
    Dim s As String
    
    s = "特定文字列"
    For Each ws In Worksheets
        If Not ws.Name Like "*" & s & "*" Then
            ws.Visible = False
        Else
            ws.Visible = True
        End If
    Next
End Sub
(常に、すべてのシートが表示された状態から出発するなら、
  ws.Visible = True の所は不要です。)

回答
投稿日時: 19/05/21 23:32:12
投稿者: simple

すべてのシートを非表示にはできない、という点は別途考慮が必要です。

投稿日時: 19/05/21 23:33:27
投稿者: tomisuke

simple様、半平太様、ありがとうございます。
実は全シート数については分かりません。
すみません。
 
検索時間としては3分ほどですが、当方病院勤務で患者様が目の前に来た時点で過去検査の結果を参照することとなり、この3分ほどが患者様をお待たせする時間となってしまっているのが現状です。
 
この時間をできるだけ解消したいと思い、質問させていただきました。
当院は規模も小さく、今だ電子カルテ化が進んでいない状況で検査の過去データをクローズしたPCで管理しています。
過去検査の内容を踏まえた上で検査を行わないと病気の見逃しという事になってしまうため、検索してからの検査が必須となっています。
ですが、自分もVBAの知識がなく無理そうであればその時間を逆に有効活用していく方向で検討します。
ありがとうございました。

投稿日時: 19/05/21 23:38:15
投稿者: tomisuke

simple様、ありがとうございます。
 
>Set ws = wb.Worksheets("*" & 特定文字列 & "*")
>のような書き方にトライしようとしている
 
正にその通りです。
でも、無理なんですね。
先ほど回答した通り、検索時間を逆に有効活用しようと思います。
重ね重ね回答をありがとうございました。
自分の無知の為に回答のお時間を割いていただき、申し訳ありませんでした。
きちんと質問できるように頑張ります。

投稿日時: 19/05/21 23:40:31
投稿者: tomisuke

WinArrow様、申し訳ありません。
無知な自分には、応用できませんでした。
もう少し勉強して、理解できるようになってからまた質問させていただきます。
お時間を割いて回答していただき、ありがとうございました。

回答
投稿日時: 19/05/22 00:01:26
投稿者: simple

シートの表示非表示だけで3分もかかることは普通ありえません。
 
表示、非表示の際に長大なイベントプロシージャが動いている可能性がありますが、
もしそうであれば、
Application.EnableEvents を一時的に Falseにして、
シートの表示非表示を変更して、
最後に Trueに戻せばよいでしょう。

投稿日時: 19/05/22 00:10:23
投稿者: tomisuke

simple様、ご指摘ありがとうございます。
試してみます。
 
これで質問を閉じさせていただきます。
本当にありがとうございました。