Excel (VBA)

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

 
(Windows 11 Pro : Microsoft 365)
所定数のページ印刷について
投稿日時: 25/07/22 12:41:48
投稿者: えっくん

お世話になります。
 
シート名が【Shee1】、【Shee2】、【Shee3】、【Shee4】と連なった状態のファイルがあります。最大10シートあります。
 
【Shee1】のA1セルに1が入っていれば【Shee1】のみ
【Shee1】のA1セルに2が入っていれば【Shee1】と【Shee2】
【Shee1】のA1セルに3が入っていれば【Shee1】と【Shee2】と【Shee3】
のように続けて印刷するマクロを作りたいと考えていますが、どのような構造になるのでしょうか。
シート名を【1】、【2】、【3】、【4】、としたほうが簡単でしょうか。
 
 
よろしくお願いします。
 

回答
投稿日時: 25/07/22 13:45:48
投稿者: Suzu

ご自身では、どこまでできているのでしょうか?
 
使うメソッドは
Worksheet.PrintOut メソッド (Excel)
https://learn.microsoft.com/ja-jp/office/vba/api/excel.worksheet.printout?f1url=%3FappId%3DDev11IDEF1%26l%3Dja-JP%26k%3Dk(vbaxl10.chm175160)%3Bk(TargetFrameworkMoniker-Office.Version%3Dv16)%26rd%3Dtrue
 
になると思います。
 
これを、Shee1 から、最大 Shee10 までのWorkSheet に対し実行します。
 
ワークシート指定部のループに関しては、
For i = 1 To WorkSheets("Shee1").Range("A1").Value
  Worksheets("Shee" & i).〜〜〜〜
Next
 
の様になるかと。

投稿日時: 25/07/22 14:16:51
投稿者: えっくん

 Suzu さん
情報ありがとうございます。
 
掲示板書込み後にネット検索して下記コードを見つけました。
www.extendoffice.com からの
https://ja.extendoffice.com/documents/excel/4623-excel-print-sheet-based-on-cell-value.html
を参考にべたですが下記のように作っています。
 
Sub 指定数印刷()
 
'UpdayebyExtendoffice20180811
    Dim xRgVal As Variant
    Dim xSheets As Sheets
    Set xSheets = ActiveWorkbook.Worksheets
    xRgVal = xSheets(1).Range("A1").Value
    If (IsNumeric(xRgVal)) And (Len(xRgVal) = 1) Then
        Select Case xRgVal
            Case 1
                xSheets(1).PrintOut
            Case 2
                xSheets(1).PrintOut
                xSheets(2).PrintOut
            Case 3
                xSheets(1).PrintOut
                xSheets(2).PrintOut
                xSheets(3).PrintOut
             Case 4
                xSheets(1).PrintOut
                xSheets(2).PrintOut
                xSheets(3).PrintOut
                xSheets(4).PrintOut
              Case 5
                xSheets(1).PrintOut
                xSheets(2).PrintOut
                xSheets(3).PrintOut
                xSheets(4).PrintOut
                xSheets(5).PrintOut
             Case 6
                xSheets(1).PrintOut
                xSheets(2).PrintOut
                xSheets(3).PrintOut
                xSheets(4).PrintOut
                xSheets(5).PrintOut
                xSheets(6).PrintOut
             Case 7
                xSheets(1).PrintOut
                xSheets(2).PrintOut
                xSheets(3).PrintOut
                xSheets(4).PrintOut
                xSheets(5).PrintOut
                xSheets(6).PrintOut
                xSheets(7).PrintOut
             Case 8
                xSheets(1).PrintOut
                xSheets(2).PrintOut
                xSheets(3).PrintOut
                xSheets(4).PrintOut
                xSheets(5).PrintOut
                xSheets(6).PrintOut
                xSheets(7).PrintOut
                xSheets(8).PrintOut
             Case 9
                xSheets(1).PrintOut
                xSheets(2).PrintOut
                xSheets(3).PrintOut
                xSheets(4).PrintOut
                xSheets(5).PrintOut
                xSheets(6).PrintOut
                xSheets(7).PrintOut
                xSheets(8).PrintOut
                xSheets(9).PrintOut
             Case 10
                xSheets(1).PrintOut
                xSheets(2).PrintOut
                xSheets(3).PrintOut
                xSheets(4).PrintOut
                xSheets(5).PrintOut
                xSheets(6).PrintOut
                xSheets(7).PrintOut
                xSheets(8).PrintOut
                xSheets(9).PrintOut
                xSheets(10).PrintOut
            Case Else
                MsgBox "Enter1, 2 or 3 into A1 (1 print Sheet1 2 print Sheet2 3 print Sheet1 and Sheet2 ", , "KuTools For Excel"
                Exit Sub
            End Select
    Else
        Exit Sub
    End If
 
    ThisWorkbook.Worksheets("Sheet1").Activate '印刷後にアクティブシートがかわってしまうのでSheet1に移動
 
 
End Sub
 
Suzuさんの書かれているループ方式が見た目や作業性には良いと思うのですが、、、、
とりあえず上のコードでも動いているようです。
 

回答
投稿日時: 25/07/22 16:41:57
投稿者: Suzu

引用:
とりあえず上のコードでも動いているようです。

 
テストが不足しています。希望通りにはならないはずです。
A1 『10』 入力時、どれも印刷されません。
 
    xRgVal = xSheets(1).Range("A1").Value
    If (IsNumeric(xRgVal)) And (Len(xRgVal) = 1) Then

 
10 入力時、2つめの条件式
左辺 Len(xRgVal) は 2 を返すので、「1」との比較で False を返すので
 
If 真 And 偽 Then の判定は、
全体として、偽となりますから、Select Case に進まず、End If まで 処理が飛び
 Select Case  の  Case 10 は 処理されませんので、 1 〜 10 の印刷がされません。
 
ループ方式が との事ですが、参考コードは既に提示しています。
試行錯誤してみてください。

回答
投稿日時: 25/07/22 17:22:07
投稿者: gombohori

365ならSEQUENCE関数で連番を作れるので

 Sub test()
    SheetsPrint 5
 End Sub
 Sub SheetsPrint(ByVal to_no As Long, Optional ByVal fr_no As Long = 1)
    to_no = WorksheetFunction.Min(to_no, Worksheets.Count)
    Worksheets(WorksheetFunction.Sequence(Arg2:=to_no - fr_no + 1, Arg3:=fr_no)).PrintPreview
 End Sub

投稿日時: 25/07/24 08:22:46
投稿者: えっくん

suzuさん
下記のように作成しました。印刷自体は正常に所定枚数印刷されているようです。
Excelシート名が 1枚目、2枚目、3枚目となってるのでそれに変更しています。
 
一点追加で教えてください。A2セルに数字を入力するコードを先端に入れています。
空白のままOKを押すとExcelのエラー表示【個の数式には、、】が出てきます。
この時はOKボタンを押して再入力が可能なので問題ないのですが、
キャンセルを押すとそのまま印刷に移ってしまいます。
キャンセル押した時はマクロを停止させたいのですが、どのようなコードになるのでしょうか。
よろしくお願いします。
 
Sub 指定数印刷()
 
  frmPage = Application.InputBox("連番を挿入して印刷します" & Chr(13) _
          & "開始番号「数字のみ」を入力してください", Type:=1)
      Range("A2").Value = frmPage
 
'ワークシート指定部のループに関しては、
For i = 1 To Worksheets("1枚目").Range("A1").Value
  Worksheets(i & "枚目").PrintOut
Next
  
End Sub
 
 
gombohoriさんへ
コードの提示ありがとうございます。
全ページプレビューしてからの印刷なので間違い確認等に使えますね。
ありがとうございました。
 
 

投稿日時: 25/07/24 09:45:24
投稿者: えっくん

 Dim frmPage As String
         
  frmPage = InputBox("連番を挿入して印刷します" & Chr(13) _
          & "開始番号「数字のみ」を入力してください")
       
         
        If StrPtr(frmPage) = 0 Then
            'キャンセル又は右上の×をクリックした場合
            MsgBox ("キャンセル、終了します。")
         
        ElseIf frmPage = "0" Then
            'なにも入力しないでOKをクリックした場合
            MsgBox ("0は無効です、終了します。")
 
        ElseIf frmPage = "" Then
            'なにも入力しないでOKをクリックした場合
            MsgBox ("未入力、終了します。")
        Else
            '上記以外
            MsgBox ("続けます")
 
で解決したと思います。おかしな点があれば指摘して頂くと助かります。

回答
投稿日時: 25/07/24 11:31:37
投稿者: Suzu

おかしい と すれば
 
参照先が違う 

引用:
A2セルに数字を入力するコードを先端に入れています。
引用:
Range("A2").Value = frmPage
  ここでは、アクティブシートの A2 に 代入
 
引用:
For i = 1 To Worksheets("1枚目").Range("A1").Value
  ここでは、1枚目シートの A1 に代入。
 
 シートに関しては、必ず 1 枚目シートが、アクティブシートになるのであれば問題ありませんが
 セル A1、A2 では、参照先が違います。
 
 
以降、問題とはならないでしょうが、参考までに・・
・セルに値を代入するということは、セルの値を書き換えます。
 「印刷だけ」を行うユーザーでも、ブックを閉じる時に 上書きしますか? と問われる事になります。
 セルに代入を行う必要があるか、検討ください。
 
・キャンセルと、何も入力しないでOK を ユーザーレベルの視点で見たとき分ける必要があるでしょうか?
  なにも入れず OK の時は、再入力を求める制御を行う様な時には必要があると思いますが
  今回の中では、分ける必要はないと思います。
 
色々な場合のエラーに対してもメッセージを出されているので、
ある程度の問題に対し、内部判定を行いメッセージを出すようなコードを参考に提示します。
 
正常な場合のみ 印刷を行い、不正な場合はメッセージなしで終了するなら
「ここから」-「ここまで」は不要でも良いでしょう。
  (印刷対象シートの存在確認を行ってから印刷を行っています。
   入力値に問題があれば、存在しているシートが、印刷対象にならないだけ。
   これだと、ユーザーが入力に問題がある事に気づきづらいので
   ステータスバー表示、終了時メッセージを追加しています)
 
Sub Sumple()
  Dim frmPage As String
  Dim strMessage As String

  Dim i As Long
  Dim wst As Worksheet

  frmPage = InputBox("連番を挿入して印刷します" & Chr(13) & "終了番号「数字のみ」を入力してください")

’ここから------------------------------
  If StrPtr(frmPage) = 0 Then
    'キャンセル又は右上の×をクリックした場合
    strMessage = "キャンセル、終了します。"
  ElseIf frmPage = "0" Then
    'なにも入力しないでOKをクリックした場合
    strMessage = "0は無効です、終了します。"
  ElseIf frmPage = "" Then
    'なにも入力しないでOKをクリックした場合
    strMessage = "未入力、終了します。"
  ElseIf IsNumeric(frmPage) = False Then
    '数字でない値が入力されてOKをクリックした場合
    strMessage = "数字以外が入力されています、終了します。"
  ElseIf Abs(frmPage) > 32767 Then
    '桁数が大きすぎる数値が入力されてOKをクリックした場合
    strMessage = "桁数が大きすぎる値が入力されています、終了します。"
  ElseIf CInt(frmPage) <> frmPage Then
    '小数点を含む値が入力されてOKをクリックした場合
    strMessage = "小数点を含む数字が入力されています、終了します。"
  ElseIf CInt(frmPage) < 0 Then
    '負の値が入力されてOKをクリックした場合
    strMessage = "負の整数が入力されています、終了します。"
  End If

  If strMessage = "" Then
    MsgBox "続けます"
  Else
    MsgBox strMessage
    Exit Sub
  End If
’ここまで------------------------------

  If IsNumeric(frmPage) Then
    For i = 1 To CInt(frmPage)
      For Each wst In ThisWorkbook.Worksheets
        If wst.Name = i & "枚目" Then
          Application.StatusBar = wst.Name & "印刷中"
          wst.PrintOut
          Application.StatusBar = False
          Exit For
        End If
      Next wst
    Next i
  End If
  MsgBox "終了します"
End Sub

投稿日時: 25/07/24 16:41:56
投稿者: えっくん

Suzu さん
以下コメントします。
 
説明不足ですみません。
A1セルとA2セルは別用途です。
A1セルには当初のようにシート印刷枚数条件が入っています。
後だし記載ののA2セルは別用途用(各シート内のシリアル数字の”連番開始番号")の数値を入力しています。
 
>「印刷だけ」を行うユーザーでも、ブックを閉じる時に 上書きしますか? と問われる事になります。
>セルに代入を行う必要があるか、検討ください。
マクロファイルは読み取りモードで開くようにしています。上書きケアセージの件は作業者に提示しています。
複数回マクロ印刷するため、入力した数字をユーザに知らせるためにあえてセルに記載しています。
 
 
>キャンセルと、何も入力しないでOK を ユーザーレベルの視点で見たとき分ける必要があるでしょうか?
運用が安定すればここまでメッセージを出す必要はありませんが、過去案件で作業当初にどのような操作をするか見えない部分もあったので、あえて表示させています。慣れた運用になれば問題なくなると思います。
 
 
新しいコードもありがとうございます。勉強になります。
 
今回はこれで解決済みとします。
不具合や改善案が出てきた場合には改めて投稿しようと思います。ありがとうございました。