• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:VBA 類似シート名 処理)

VBAで類似シート名を処理する方法

このQ&Aのポイント
  • VBAを使用して、複数の類似したシート名を処理する方法について教えてください。
  • シート名が「一覧 (2)」「一覧 (3)」と連続している場合、それらのシートの表データを「一覧」という名前のシートにまとめたいです。
  • For Each を使ってシート名を処理する方法を調べましたが、見つけることができませんでした。他の方法や参考になるサイトがあれば教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.2

こんにちは。お邪魔します。 > For Each を使えば出来るんじゃないかと調べましたが、見付けられませんでした。 必要なパーツそれぞれは簡易なものです。 組み合わせて使うことで少し難しくなりますし、 そのものズバリを掲載しているサイトは期待薄、ということなのでしょう。 "作り方"で答えたい気持ちはあるのですが、 パーツの組み合わせで覚えないと意味がないものは ズバリで答えるしかないので。 For Each...Next ループを使おうというセンスは正しいと思います。 シート名をLike演算子で条件分岐します。  If Sheets(any).Name Like "一覧 (#)" Or Sheets(any).Name Like "一覧 (##)" Then と書いて # 部分に一文字の半角数字を当て嵌めて文字列の比較をしています。 「一覧 (0)」から「一覧 (9)」まで「一覧 (00)」から「一覧 (99)」 一応、こちらとしては「一覧 (マスタ)」のような ありがちなシート名を弾くことも想定しています。  sWshNm = StrConv(oWsh.Name, vbNarrow) について 手作業でシート名を入力していたりすると、思わぬことも起こりますので  一覧 (39)  一覧 (39)  一覧 (39)  一覧 (39) などでもヒットするようにしています(よくある普通の手当てです)。  sWshNm = StrConv(oWsh.Name, vbNarrow) に続けて sWshNm = Replace(sWshNm, " ", "") と書き足して、スペースを抜いた形で比較する方が好いかも知れません。 他、 張り付ける行位置は、毎回検索しなくても加算でいけたり、 ある程度効率的にできる部分は、こちらで書き換えました。 Like 演算子については、VBAヘルプを眺める位でもいいと思います。 何か疑問がありましたら、補足欄にでも書いてみてください。 サンプルは、b、a、2パターンです。 ' ' ================ Sub Re8078570b() ' b 既存データの下の行に続けて連続出力する場合   Dim oWsh As Worksheet ' For Each...Next ループ用ポインタ   Dim sWshNm As String ' 各シート名   Dim nPrintPos As Long ' Sheets("一覧")の書き出し行位置(変動)   Dim tnAppRows As Long ' Application既定の行数(固定)   Dim nYSize As Long ' コピー元の行数 ' ' Application のウィンドウ描画更新抑止   Application.ScreenUpdating = False ' ' Application既定の行数を取得(2回以上使う値は変数に)   tnAppRows = Rows.Count    ' ' Sheets("一覧")のA列だけをポイントしておく   With Sheets("一覧").Columns(1) ' ' 一覧書き出し開始行を取得     nPrintPos = .Cells(tnAppRows).End(xlUp).Row + 1 ' ' Worksheetsを For Each...Next で総なめ     For Each oWsh In Worksheets ' ' 各シート名取得(2回以上使う値は変数に)(全半角混在対策で半角に統一)       sWshNm = StrConv(oWsh.Name, vbNarrow) ' ' Like演算子で "一覧 (#)" "一覧 (##)" 0-99の数字に対応したシートを判別       If sWshNm Like "一覧 (#)" Or sWshNm Like "一覧 (##)" Then ' ' 各シート、コピー元の行数取得         nYSize = oWsh.Cells(tnAppRows, 1).End(xlUp).Row - 1 ' ' 各シート、コピー元に有意なデータがあるなら         If nYSize > 0 Then ' ' 各シート、コピー実行(A:L列*nYSize)           oWsh.Range("A2:L2").Resize(nYSize).Copy ' ' ◆エラー制御、検討が必要な行(貼り付け先の行、足りてる?) ' ' 値のみ貼り付け実行(Sheets("一覧")のA列のnPrintPos行にあるセル)           .Cells(nPrintPos).PasteSpecial Paste:=xlPasteValues ' ' 書き出し行位置にコピー元の行数を加算           nPrintPos = nPrintPos + nYSize         End If       End If ' sWshNm Like "一覧 (#)" Or     Next ' oWsh In Worksheets   End With ' ' Application のコピーモード終了   Application.CutCopyMode = False ' ' Application のウィンドウ描画更新再開(プロシージャの最後では省略可)   Application.ScreenUpdating = True End Sub ' ' ================ Sub Re8078570a() ' a 既存データに上書きして固定行以下に連続出力する場合   Dim oWsh As Worksheet ' For Each...Next ループ用ポインタ   Dim sWshNm As String ' 各シート名   Dim nPrintPos As Long ' Sheets("一覧")の書き出し行位置(変動)   Dim tnAppRows As Long ' Application既定の行数(固定)   Dim nBottom As Long ' Sheets("一覧")の既存データの最下行   Dim nYSize As Long ' コピー元の行数 ' ' Application のウィンドウ描画更新抑止   Application.ScreenUpdating = False ' 一覧書き出し開始行を指定   nPrintPos = 2 ' ' Application既定の行数を取得(2回以上使う値は変数に)   tnAppRows = Rows.Count ' ' Sheets("一覧")のA列だけをポイントしておく   With Sheets("一覧").Columns(1) ' ' 既存データの最下行取得     nBottom = .Cells(tnAppRows).End(xlUp).Row ' ' 既存データをクリア     If nBottom >= nPrintPos Then       .Cells(nPrintPos).Resize(nBottom - nPrintPos + 1).ClearContents     End If ' ' Worksheetsを For Each...Next で総なめ     For Each oWsh In Worksheets ' ' 各シート名取得(2回以上使う値は変数に)(全半角混在対策で半角に統一)       sWshNm = StrConv(oWsh.Name, vbNarrow) ' ' Like演算子で "一覧 (#)" "一覧 (##)" 0-99の数字に対応したシートを判別       If sWshNm Like "一覧 (#)" Or sWshNm Like "一覧 (##)" Then ' ' 各シート、コピー元の行数取得         nYSize = oWsh.Cells(tnAppRows, 1).End(xlUp).Row - 1 ' ' 各シート、コピー元に有意なデータがあるなら         If nYSize > 0 Then ' ' 各シート、コピー実行(A:L列*nYSize)           oWsh.Range("A2:L2").Resize(nYSize).Copy ' ' ◆エラー制御、検討が必要な行(貼り付け先の行、足りてる?) ' ' 値のみ貼り付け実行(Sheets("一覧")のA列のnPrintPos行にあるセル)           .Cells(nPrintPos).PasteSpecial Paste:=xlPasteValues ' ' 書き出し行位置にコピー元の行数を加算           nPrintPos = nPrintPos + nYSize         End If       End If     Next ' For Each oWsh In Worksheets   End With ' ' Application のコピーモード終了   Application.CutCopyMode = False ' ' Application のウィンドウ描画更新再開(プロシージャの最後では省略可)   Application.ScreenUpdating = True End Sub

その他の回答 (2)

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.3

すみません。 夢の中でポカしていたことに気が付きました。 Sub Re8078570a() についての一部訂正です。 誤) |' ' 既存データをクリア |    If nBottom >= nPrintPos Then |      .Cells(nPrintPos).Resize(nBottom - nPrintPos + 1).ClearContents |    End If 正) ' ' 既存データをクリア     If nBottom >= nPrintPos Then       .Cells(nPrintPos).Resize(nBottom - nPrintPos + 1, 12).ClearContents     End If それから、少し説明が雑だったようなので、、、。 >  sWshNm = StrConv(oWsh.Name, vbNarrow) > に続けて > sWshNm = Replace(sWshNm, " ", "") > と書き足して、スペースを抜いた形で比較する方が好いかも知れません。 b、a、2パターン共通で、 ' ' 各シート名取得(2回以上使う値は変数に)(全半角混在対策で半角に統一)       sWshNm = StrConv(oWsh.Name, vbNarrow) ' ' 各シート名の中のスペースに過不足がある場合を想定してスペースを抜いて比較。       sWshNm = Replace(sWshNm, " ", "") ' ' Like演算子で "一覧 (#)" "一覧 (##)" 0-99の数字に対応したシートを判別       If sWshNm Like "一覧(#)" Or sWshNm Like "一覧(##)" Then という意味のことを書きましたが、不明瞭でした。 全半角やスペースの有無の入力時錯誤、この手の対処は私自身多くの経験があります。 職場によっては全く必要ない場合もありますし、 保険を掛ける意味でVBAの確度を高めようとする場合もあります。 シート名の判別をより正確にしたい場合などは正規表現(RegExp)を使うニーズもあるでしょう。 「一覧 (0)」というシートがあって、それだけはコピーしたくない、 なんてニーズもあるかも知れません。 何か不足があったら補足欄にでも書いてみてください。 訂正の件。失礼しました。

club88
質問者

お礼

夢の中まで、本当にありがとうございます。

  • tom04
  • ベストアンサー率49% (2537/5117)
回答No.1

こんにちは! 標準モジュールにコピー&ペーストしてマクロを実行してみてください。 Sub Sample1() Dim i As Long, k As Long For k = 1 To Worksheets.Count With Worksheets(k) If .Name <> "一覧" And InStr(.Name, "一覧") > 0 Then i = .Cells(Rows.Count, 1).End(xlUp).Row Range(.Cells(2, 1), .Cells(i, 12)).Copy Worksheets("一覧").Cells(Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial Paste:=xlPasteValues End If End With Next k End Sub こんな感じでよろしいのでしょうか? 外していたらごめんなさいね。m(_ _)m

関連するQ&A