マクロで記録したコード①のような(すべてのシート(仮に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
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
以上、ながながと書きましたがお役に立てれば幸いです。
ぢゃわさん詳細なご回答ありがとうございます。
コード②はシステム内の共通関数的な役割のもので、
約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
'以下同じ
とりあえず今はループさせる方法でやっています。
ということで「解決」です。
ありがとうございました。
ツイート | ![]() |