VB−エクセルでシート複数選択時の印刷について

解決


ゆじゅ  2003-07-08 04:53:55  No: 107716

マクロで記録したコード①のような(すべてのシート(仮に5つ)を選択して一括でページ設定を行い印刷)処理を、VBでコード②のような感じで、Sheetsオブジェクトを関数に渡して、ページ設定を行い印刷しようとしているのですがどうもうまくいかず、印刷すると1つ目のシートだけ指定した設定で印刷され、残りのシートは何も設定されてない状態で印刷されます。
マクロのSheets(〜).Select部分をVBで、シート名ではなくインデックス的なもので一括設定するように書こうとするとどうすればいいのでしょうか?

シートの数だけループさせて1シートずつ設定していくしかないのでしょうか?
ご教授よろしくお願いいたします。

*コード①  …マクロ
    Sheets(Array("s1", "s2", "s3", "s4", "5")).Select
    Sheets("s1").Activate
    With ActiveSheet.PageSetup
        .Orientation = xlLandscape
        .PaperSize = xlPaperA4
    End With
    ActiveWindow.SelectedSheets.PrintOut Copies:=1, Collate:=True

*コード②*  …  VB(gl_XlsAppはグローバル)
Function XlsPrintSheets(ByRef XlsSheets As excel.Sheets, ByVal Tateyoko As Integer, ByVal Saizu As Integer) As Boolean
On Error GoTo errorHandler

    XlsPrintSheets = False
    
    XlsSheets.Select
    
    With gl_XlsApp.ActiveSheet.PageSetup
        .Orientation = Tateyoko     '印刷向き
        .PaperSize = Saizu          '用紙サイズ
    End With
    
    XlsSheets.PrintOut    '印刷
    
    XlsPrintSheets = True
    
    Exit Function
errorHandler:
    Call ErrorHandling
End Function


ぢゃわ  2003-07-10 23:44:42  No: 107717

VBAでのコーディングノウハウで回答させていただきます。
VBでもおそらくそのまま活用できると思いますが確認してませんので。。。

シートの選択の方法ですが、シート名で指定するほか、インデックス番号や
オブジェクト名でも指定できます。
インデックス番号はシートの並び順の番号で、EXCELで見たときに左側のシートから
順番に1,2,・・・と振られています。
オブジェクト名は特に指定しなければ、シートを作成した順に
Sheet1、Sheet2・・・とつけられていくようです。

で、複数シートに同じ設定をするときなどはインデックス番号で
ループするのが手っ取り早いです。
例:シート1〜5を順に選択
    For i =1 to 5
       sheets(i).select
    Next i
例:シート1と3を同時選択
   sheets(Array(1,3)).select

全シート選択する場合は、単に
  sheets.select
でできます。印刷も同様です。(.selectを.PrintOutに置き換えるだけ)

コード①について。
EXCELの操作で「シート全選択(もしくは複数選択)」→「ページ設定」
とすると、選択したシート全てにページ設定の設定内容が反映されます。
この操作をマクロの自動作成で記録すると、たしかにコード①のような
マクロを作ってくれます。
しかしこのマクロ、実際に実行してもアクティブシートにしかページ設定が
反映されません。
>    Sheets("s1").Activate
>    With ActiveSheet.PageSetup
となっているからです。
選択されているシートに一括でページ設定する方法は私も知りません。
私は個々にループして設定をいれる方法で対応しています。
例:全シートにページ設定
    For Each sh In Sheets
        With sh.PageSetup
            .Orientation = xlPortrait
        End With
    Next sh
指定のページ(例えば2と3)にのみページ設定をする場合は、最初の1行を
    For Each sh In Sheets(Array(2, 3))
のようにしてあげればOKです。

コード②については、どのようにしてモジュールが呼ばれているか
詳細が不明なのですが、シート単位でモジュールに渡しているので
シート単位での印刷になっているんじゃないでしょうか?

複数シートまとめてページ設定・印刷するのであれば、引数として
もらうのはSheetではなくworkbookであり、対象とする全シートの
インデックス番号だと思います。

仮にgl_XlsAppが現在使用しているworkbookを使い、そこにある全シートを
設定・印刷するのであれば、現状のロジックを応用して以下のようにすれば
できるのではないかと思います。
#机上論であって、申し訳ないですがVBでの動作確認はしていません(滝汗

Function XlsPrintSheets(ByVal Tateyoko As Integer, ByVal Saizu As Integer) As Boolean

On Error GoTo errorHandler

    Dim Sh as As excel.Sheets

    XlsPrintSheets = False
    
    For Each Sh in gl_XlsApp.Sheets
        With Sh.PageSetup
            .Orientation = Tateyoko     '印刷向き
            .PaperSize = Saizu          '用紙サイズ
        End With
    Next Sh 
     
    gl_XlsApp.Sheets.PrintOut    '全印刷
    
    XlsPrintSheets = True
    
    Exit Function
errorHandler:
    Call ErrorHandling
End Function

以上、ながながと書きましたがお役に立てれば幸いです。


ゆじゅ  2003-07-11 19:49:42  No: 107718

ぢゃわさん詳細なご回答ありがとうございます。

コード②はシステム内の共通関数的な役割のもので、
約50種の帳票があるのですが、どれからも引数つきで呼び出すだけで、
設定・印刷できるモジュールです。(のつもり(笑))

*帳票は数人の新人が開発するのですが、基本となる部分を作成しています。

実際にはSheetsオブジェクトが引数じゃなくて、
Sheetsコレクション(複数シート)ですね。すみません。
一応単体シートではなくて、複数シートを扱っていると思います。
(workbook.sheetsなので)
おのおののプロシージャでSetしたSheetsコレクションを、
参照渡しでこのモジュールに送ってます。

'グローバル
Global gl_XlsApp As Excel.Application
Global gl_XlsBook As Excel.Workbook

'共通関数
Function XlsStart() As Boolean  '(一部抜粋)
    Set gl_XlsApp = CreateObject("Excel.Application")
    With gl_XlsApp
        .DisplayAlerts = False              '警告やメッセージなし
        '.....など
    End With
    Set gl_XlsBook = gl_XlsApp.Workbooks.Add
End Function

Private Sub cmd_1_Click()  'こんな感じ
    Dim XlsSheets As Excel.Sheets
    Call XlsStart
    Set XlsSheets = gl_XlsBook.Sheets
    Call XlsPrintSheets(XlsSheets, cs_Xls_YOKO, cs_Xls_A4)
    Call XlsEnd 'という開放関係の処理
End Sub

本当は下のような感じでいけるかなと思っていたんですが・・・。
わざわざ配列を作って渡してます。
要はXlsSheets.Selectのような気もしますが・・・。
まぁ、指定範囲シート(5〜10など)設定時は応用して使えるかなっと。

    Dim i As Long
    Dim WK() As Long
    ReDim WK(1 To XlsSheets.Count)
    For i = 1 To UBound(WK) Step 1
        WK(i) = i
    Next i
    XlsSheets(WK()).Select
    '以下同じ

とりあえず今はループさせる方法でやっています。
ということで「解決」です。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加