「作業グループ」状態をVBAで作るには[Excel]

「作業グループ」状態にする

複数のシートにまとめて変更を加えたいときには「作業グループ」状態にする。

しかし、VBAからExcelを操作するときに、あまり「作業グループ」状態を使うことがなかった。

そういえば、どうやるんだろう?

で、確かめてみた。

マクロの記録

f:id:akashi_keirin:20180303103905j:plain

ちょっと分かりにくく、かつわけのわからない画像ですまない。

とにかく、2番目~4番目のシートを選択して、「作業グループ」状態にしてある。

これだけで操作をやめ、マクロの記録を終了。んで、できたコードがコチラ。

リスト1 標準モジュール
Sub Macro1()
'
' Macro1 Macro
'

'
    Sheets(Array("ち~んw 1 号(笑)", "ち~んw 2 号(笑)", "ち~んw 3 号(笑)")).Select
    Sheets("ち~んw 1 号(笑)").Activate
End Sub

へえ! 知らんかった!Sheetsコレクションのインデックスに配列をぶち込んだら複数シート選択状態になるのか!

記録マクロだと、シート名の配列を作っているみたいだけれど、これでいけるんなら別にインデックス番号でもいいはず。

で、これを用いてちょっとやってみた。

データを差し込んでは新しいシートを追加し、最後にまとめて印刷するマクロ

Wordの差込印刷みたいな要領で、シートの一部にそれぞれ異なるデータを差し込みつつ新規シートとして追加していき、全部追加し終わったところで一気に印刷プレビュー表示→印刷、という流れの簡単なコードを書いてみた。

f:id:akashi_keirin:20180303103914j:plain

シート「Main」には、こんなふうに準備しておく。

A2セルにデータ(笑)を差し込んでいく、という設定。

スト2 標準モジュール
Public Sub insertionPrintByAddSheets()
  Dim Sh As Worksheet
  Set Sh = ThisWorkbook.Worksheets("Main")
  Dim i As Integer
  For i = 1 To 3
    With ThisWorkbook    '……(1)'
      Sh.Copy After:=.Worksheets(.Worksheets.Count)    '……(2)'
      With .Worksheets(.Worksheets.Count)    '……(3)'
        .Range("A2").Value = "ち~んw " & i & " 号(笑)"    '……(4)'
        .Name = .Range("A2").Value    '……(5)'
      End With
    End With
  Next
  Dim ar(2) As Integer    '……(6)'
  For i = 0 To 2
    ar(i) = i + 2
  Next
  With ThisWorkbook.Worksheets(ar)    '……(7)'
    .PrintPreview
    .PrintOut
  End With
  Sh.Select    '……(8)'
End Sub

とりあえず実験なので、追加するシートは3つだけにした。

まず(1)からの9行

For i = 1 To 3
  With ThisWorkbook
    Sh.Copy After:=.Worksheets(.Worksheets.Count)    '……(2)'
    With .Worksheets(.Worksheets.Count)    '……(3)'
      .Range("A2").Value = "ち~んw " & i & " 号(笑)"    '……(4)'
      .Name = .Range("A2").Value    '……(5)'
    End With
  End With
Next

のForループでは、「Main」シートの内容をコピーして新しいシートを追加しつつ、データ(笑)を差し込む。

まず(2)の

Sh.Copy After:=.Worksheets(.Worksheets.Count)

で現時点での最終シートの次に新しいシートを追加していく。

引数「After」の指定の仕方は、今回の場合は別に

.Worksheets(i)

でも大丈夫だと思うけれど、後で「Main」意外にも固定のシートが生じた場合に書き換える必要が生ずるので、このようにした。

(3)からのWithブロック

With .Worksheets(.Worksheets.Count)
  .Range("A2").Value = "ち~んw " & i & " 号(笑)"    '……(4)'
  .Name = .Range("A2").Value    '……(5)'
End With

は、新しくできたシートに対する処理。Worksheetsコレクションのインデックス番号に、この時点でのWorksheetsコレクションの数を指定しているので、確実に追加されたばかりのシートを指定することができる。

まず(4)の

.Range("A2").Value = "ち~んw " & i & " 号(笑)"

で、新しく追加されたシートのA2セルにデータ(笑)を差し込み、

(5)の

.Name = .Range("A2").Value

でシート名を差し込んだデータ(笑)に変えている。

ここまでで必要なシートが出そろったことになる。

お次は、(6)からの4行。

Dim ar(2) As Integer
For i = 0 To 2
  ar(i) = i + 2
Next

新しく追加したシートをまとめて指定するのに使う配列を準備する。

今回は2シート目~4シート目(最終シート)なのでこんな感じにする。

「2」とか、マジックナンバー丸出しだが、あくまで実験用なのでご容赦を。実際には引数で対応することになるだろう。

後は(7)からの4行

With ThisWorkbook.Worksheets(ar)
  .PrintPreview
  .PrintOut
End With

で配列「ar」で指定されたインデックス番号のシート(今回の場合は、「2」「3」「4」番目のシート)に対してPrintPreviewメソッドとPrintOutメソッドを実行する。

これで処理そのものは終わりだが、「作業グループ」状態になっていることに気づかずにシートを加工して大惨事、ということになったら困るので、

(8)の

Sh.Select

で、元のシートをSelectして終わるようにした。

実行結果

紙でプリントアウトしてもブログでは表現が難しいので、プリンタはJUST PDFを指定してある。

f:id:akashi_keirin:20180303103923j:plain

まずプレビューが表示される。画像では全く伝わらないが、ちゃんと3ページ分ある。

しかる後、印刷が実行されて、PDFが表示された。

f:id:akashi_keirin:20180303103934j:plain

ちゃんと3ページ分一気に表示されている。

おわりに

「直接操作でしかやらないような動作」というのがあって、そういうのは簡単な操作なのに、案外VBAでどうやるか知らないもんだなあ、ということです。

コレクションのインデックスを配列で指定するという発想は、正直全くありませんでした。

@akashi_keirin on Twitter