[[20201211115435]] 『印刷実行時にページ数指定のVBA』(VBA初心者) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『印刷実行時にページ数指定のVBA』(VBA初心者)

印刷ボタン押下時に
シート1のセルA1の左から1文字目が「A」なら1〜3ページを印刷、
それ以外は1ページ目のみを印刷する。
というVBAを組みたいのですが…可能でしょうか?

なんとなく作成してみたのですが上手く行かず…。

Private Sub Workbook_BeforePrint(Cancel As Boolean)

If Sheets("1").Range("A1").Value = Left("A1", 1) = "A" Then

ActiveWindow.SelectedSheets.PrintOut From:=1, To:=3

Else

ActiveWindow.SelectedSheets.PrintOut From:=1, To:=1

End If
End Sub

できれば、複数のシートがあり、
シート1がアクティブな状態で印刷を押下した時のみ
VBAを実行させたいです。

ご教示いただけると助かります。
よろしくお願いいたします。

< 使用 Excel:Excel2010、使用 OS:Windows10 >


 If Sheets("1").Range("A1").Value = Left("A1", 1) = "A" Then
 は
 If Left(Sheets("1").Range("A1").Value, 1) = "A" Then
 かな?
(QS) 2020/12/11(金) 12:34

 >シート1がアクティブな状態で印刷を押下した時のみ
 >VBAを実行させたいです。

 処理の先頭に
 If ActiveSheet.Name <> "1" Then Exit Sub
 を追加でしょうか。

 シート名が"1" Worksheets("1") と Worksheets(1) は意味が異なるのでご注意を。
 文字列はシート名ですし、数字はシートの位置です。
(QS) 2020/12/11(金) 12:49

編集がかぶりましたが、そのまま。

既に、指摘がありますが↓の条件式がおかしいですね。

 Sheets("1").Range("A1").Value = Left("A1", 1) = "A" Then

右辺と左辺の2つを比較するように書いてみてください。

また、「シート1がアクティブな状態で印刷」ということは、アクティブシートの名前で判定すればよいですね。

踏まえるとこんな感じ。

    Private Sub Workbook_BeforePrint(Cancel As Boolean)
        Dim MySH As Worksheet: Set MySH = Worksheets(1)

        '▼アクティブシートの名前で処理対象か判定
        If ActiveSheet.Name <> MySH.Name Then
            MsgBox ActiveSheet.Name & "シートは印刷しちゃだめなのです"
            Cancel = True
            Exit Sub
        End If

        '▼A1セルの値で条件分岐
        If Left(MySH.Range("A1").Value, 1) = "A" Then
            MySH.PrintOut From:=1, To:=3
        Else
            MySH.PrintOut From:=1, To:=1
        End If

    End Sub

(もこな2 ) 2020/12/11(金) 12:59


 問題提起だけですが、複数シート選択されていたらどうされたいです?
(稲葉) 2020/12/11(金) 13:10

QS様
もこな2様

ご回答ありがとうございます。
多々、式等がおかしくて申し訳ありません。
ご指摘ありがとうございます。

もこな2様に記述いただいたVBAで実行しましたが
当初のVBAでも、もこな2様のVBAでも
A1の左1文字目が「A」以外であった場合、
1枚印刷された後に全てのページが印刷されてしまいました。

また、稲葉様よりいただいた問いですが。
複数シート選択時はVBAでのページ数指定はしなくて大丈夫です。

意味合いとしてはシート"1"を印刷する時だけ
VBAでのページ数指定を行いたいという事です。

文章で書くのが難しいのですが…伝わりますでしょうか…。

お手数をお掛けし申し訳ありません。
(VBA初心者) 2020/12/11(金) 13:37


ちょっと余力が無くて試せてませんが、最初の印刷命令はキャンセルしないとマズイかもしれません

    Private Sub Workbook_BeforePrint(Cancel As Boolean)
        Dim MySH As Worksheet: Set MySH = Worksheets(1)

        '▼印刷命令を一旦取り消し
        Cancel = True

        '▼アクティブシートの名前で処理対象か判定
        If ActiveSheet.Name <> MySH.Name Then
            MsgBox ActiveSheet.Name & "シートは印刷しちゃだめなのです"
            Exit Sub
        End If

        Application.EnableEvents = False
        '▼A1セルの値で条件分岐して印刷命令のやりなおし
        If Left(MySH.Range("A1").Value, 1) = "A" Then
            MySH.PrintOut From:=1, To:=3
        Else
            MySH.PrintOut From:=1, To:=1
        End If
        Application.EnableEvents = True

    End Sub

(もこな2 ) 2020/12/11(金) 15:09


    Private Sub Workbook_BeforePrint(Cancel As Boolean)
        Dim MySH As Worksheet: Set MySH = Worksheets(1)

        '▼印刷命令を一旦取り消し
        Cancel = True

 これだと一生印刷できないのでは。
(Why) 2020/12/11(金) 15:30

>これだと一生印刷できないのでは。

そうならないように↓をしているのです

        Application.EnableEvents = False  '←イベントの発生を無効化
           〜省略〜
        Application.EnableEvents = True   '←イベントの発生を有効化

(もこな2 ) 2020/12/11(金) 16:42


もこな様
皆様

沢山のご回答ありがとうございます。
おかげ様で望んだ通りに作成することができました。

QS様ともこな2様の助言を参考に下記で作成しました。

Private Sub Workbook_BeforePrint(Cancel As Boolean)

Cancel = True

If ActiveSheet.Name <> "1" Then
ActiveWindow.SelectedSheets.PrintPreview

Exit Sub
End If

Application.EnableEvents = False

If ActiveSheet.Name <> "1" Then Exit Sub
If Left(Sheets("1").Range("A1").Value, 1) = "A" Then
ActiveWindow.SelectedSheets.PrintOut From:=1, To:=3

Else

ActiveWindow.SelectedSheets.PrintOut From:=1, To:=1

End If

Application.EnableEvents = True

End Sub

シート1以外のシートでは何も指定はしたくなかったので
とりあえずプレビューを入れてしまいました。
(何を入れればいいのか正解が解らず…。)

勉強になりました。ありがとうございました。
また何かあればよろしくお願いいたします。
(VBA初心者) 2020/12/11(金) 16:58


>シート1以外のシートでは何も指定はしたくなかったので

私は↓のように解釈してましたけど

 「1」シートがアクティブな時だけ、「1」シートをA1セルの値で条件分岐して印刷する
 他のシートは印刷しない

もしかして↓だったりしますか?

 「1」シートがアクティブな時だけ、「1」シートをA1セルの値で条件分岐して印刷する
 アクティブシートが「1」ではないときは普通に印刷する
 「1」シートがアクティブであっても、複数シートが選択されているときは普通に印刷する

(もこな2 ) 2020/12/12(土) 11:32


 衝突したけど、コード載せておきますね

 もこな2さん
 私は、
 >できれば、複数のシートがあり、 
 >シート1がアクティブな状態で印刷を押下した時のみ 
 >VBAを実行させたいです。 
 とのことなので、何もしない=指定せずに印刷だと思ってました。
 質問者さんから提示されたコードだと、文字通りシート1以外印刷できないですが。

 以下、質問者さんへ

 ご提示のコードだと、1以外のシートは印刷できないですけど、それでいいんですか?
 こちらで試してもらえませんか?

    Private Sub Workbook_BeforePrint(Cancel As Boolean)
        Dim ws As Worksheet
        Dim pg As Long
        Set ws = Sheets("1")
        '複数シートが選択されていた場合、何も指定せずに印刷開始
        If ActiveWindow.SelectedSheets.Count > 1 Then
            Exit Sub
        End If

        'アクティブシートが "1" 以外なら、何もせずに印刷
        If ActiveSheet.Name <> ws.Name Then
            Exit Sub
        End If

        'アクティブシートが "1" なら、A1の値に応じて印刷ページ数を変更
        With ws
            '条件分岐 変数pgに印刷ページ数を入れる
            Select Case Left(.Range("A1").Value, 1)
                Case "A"
                    pg = 3
                Case Else
                    pg = 1
            End Select
            '印刷のイベントをキャンセル
            Cancel = True
            '印刷のイベントを抑制して、再度印刷命令
            Application.EnableEvents = False
            ws.PrintOut from:=1, to:=pg
            Application.EnableEvents = True
        End With
    End Sub

 複数シート選択時に、印刷 → 何もせずに印刷
 アクティブシートが1以外 → 何もせずに印刷
 アクティブシートが1の時 → A1の値の頭文字がAの時、1-3ページ、それ以外は1-1ページを印刷
(稲葉) 2020/12/12(土) 11:38

皆様、返信が遅くなり大変申し訳ありません。

もこな2様

後者の通りです。
判りにくい記述で申し訳ありませんでした。
色々とご検討・ご回答いただきありがとうございます。

稲葉様

12/11時点では1度実行できたと思ったので
記述したコードで問題ないかと思いましたが
本日再度行いましたら、やはりできませんでした。
私の勘違いだったようです。申し訳ありません。

稲葉様からいただいたコードで解決しました。
とても助かりました。ありがとうございます。

皆様よりいただいた知識も活用させていただき、
より良いものが作れるよう精進してまいります。
皆様ありがとうございました。
(VBA初心者) 2020/12/14(月) 08:49


度々申し訳ありません。
関連内容なのでこちらで合わせて
ご教示いただければと思うのですが…。

いただいたコードとは別に。

標準モジュールへ
他のシート(シート"2")のセルA1へ
シート"1"のA1に入る文字と同じ物を入力し
シート"2"のセルA1の横に「印刷する」コマンドを設置し
こちらを押下するとシート"1"のセルA1へ反映され
印刷プレビューが表示されるというコードを作成しました。

その後に「印刷」を実行した際に
作成いただいたイベントプロシージャを実行させる。
というプロセスで行いたかったのですが…
プレビューが表示されません。

下記コードです。

Sub 反映・印刷()

    Sheets("1").Range("A1").Value = Range("A1").Value

    Sheets("1").Activate
    ActiveSheet.PrintPreview

End Sub

プレビューを表示させる方法を
ご教示いただけると助かります。
よろしくお願いいたします。
(VBA初心者) 2020/12/14(月) 09:51


 プレビューでも実行してしまうからでしょうねぇ・・・
 プレビューかどうかを判断するプロパティが見つからなかったので、マクロから実行した場合のみ有効になるようなコードに変更が必要かもしれないです。

 ただ、Publicで宣言しているので、途中でコードがこけた場合に変数がリセットされず、
 普通に印刷できてしまう可能性も0ではないので、完ぺきではないです。

 ■Thisworkbookモジュールのコードを以下に差し替え
    Public isMacro As Boolean
    Public isPreview As Boolean
    Private Sub Workbook_BeforePrint(Cancel As Boolean)
        Dim ws As Worksheet
        Dim pg As Long
        Set ws = Sheets("1")

        '複数シートが選択されていた場合、何も指定せずに印刷開始
        If ActiveWindow.SelectedSheets.Count > 1 Then
            Exit Sub
        End If

        'アクティブシートが "1" 以外なら、何もせずに印刷
        If ActiveSheet.Name <> ws.Name Then
            Exit Sub
        End If

        'アクティブシートが1の場合、マクロ以外で印刷されたら、注意喚起して印刷をキャンセルする
        If isMacro = False Then
            MsgBox "シート1はマクロから印刷してください"
            Cancel = True
        ElseIf isPreview Then
            'コードから明確にプレビューと指示があれば、何もせずにプレビュー表示する
            '状態のリセット(ここでは、isMacroはTrueの状態なので、プレビューから印刷した場合、次のElseに進む
            isPreview = False
        Else
            'アクティブシートが "1" なら、A1の値に応じて印刷ページ数を変更
            With ws
                '条件分岐 変数pgに印刷ページ数を入れる
                Select Case Left(.Range("A1").Value, 1)
                    Case "A"
                        pg = 3
                    Case Else
                        pg = 1
                End Select

                '印刷のイベントをキャンセル
                Cancel = True

                '印刷のイベントを抑制して、再度印刷命令
                Application.EnableEvents = False
                ws.PrintOut from:=1, to:=pg
                Application.EnableEvents = True
            End With
            '状態のリセット
            isMacro = False
        End If
    End Sub
 ■標準モジュールに
    Sub 反映_印刷()

        Sheets("1").Range("A1").Value = Sheets("2").Range("A1").Value
        '                               ~~~~~~~~↑~
        '                               シート名はシートを跨ぐ処理を行う場合は、明記したほうがいいです。

        ThisWorkbook.isMacro = True
        ThisWorkbook.isPreview = True
        With Sheets("1")
            .Activate
            .PrintPreview
        End With
        ThisWorkbook.isMacro = False
        ThisWorkbook.isPreview = False
    End Sub

(稲葉) 2020/12/14(月) 10:43


稲葉様

コードありがとうございます。
何度も要望を出してしまい申し訳ありません…。

'アクティブシートが1の場合、マクロ以外で印刷されたら、注意喚起して印刷をキャンセルする

シート"1"で通常の印刷ボタンを押下時も
印刷できるようにしたいのですが
両方可能にするのは難しいでしょうか?

度々申し訳ありません。
(VBA初心者) 2020/12/14(月) 12:48


 >シート"1"で通常の印刷ボタンを押下時も 
 >印刷できるようにしたいのですが 
 >両方可能にするのは難しいでしょうか? 
 (Thisworkbookのコードを書き換えずに)できますよ。

 >        'アクティブシートが1の場合、マクロ以外で印刷されたら、注意喚起して印刷をキャンセルする
 の時、何を条件に分岐しているかステップ実行で確認してください。
https://www.239-programing.com/excel-vba/basic/basic023.html

 ヒントは標準モジュールのコードに転がってますので、まずは自分でやってみてください。
 最初に質問したときみたいに、「こうしたけど、出来ませんでした」という質問のほうが好きです。

(稲葉) 2020/12/14(月) 17:02


 あー勘違いしました。
 >シート"1"で通常の印刷ボタンを押下時も 
 これはあれですね、普通の手動操作ですね。

 今現時点で私が調べた限りでは難しいので、識者の回答お待ちください・・・

 話を整理すると
 1)シート1から手動で印刷を押すと、A1の値によって印刷枚数を変更したい。
 2)シート2からマクロで印刷プレビューを表示させ、プレビュー画面の印刷ボタンを押すと、A1の値によって印刷枚数を変更したい
 3)複数のシートが選択されている状態でシート1を含む印刷をする場合は、何も指定せずに印刷したい
 4)シート1以外のシートを印刷する場合、何もせずに印刷したい

 これに対する回答で、下記の案があります。
  手動での印刷をあきらめて、印刷ボタンをシート1に付ける
  手動での印刷を押したときに、判断をユーザーに任せる(マクロで)

 何を目的に制御したいのかに依ります。

(稲葉) 2020/12/14(月) 19:31


 度々すみません
 よく考えたら、isMacroの判定消せばいけそうです

(稲葉) 2020/12/14(月) 19:47


稲葉様

ご返信ありがとうございます。
ステップ実行で確認しながら色々試してみたのですが
プレビューまでは出来るが印刷ができず…。

シート2は入力シートになっており
シート1はシート2の内容が反映される表になっています。
多人数で共有するファイルなので、
マクロからも通常ボタンからも出来ればと欲が出ました。

ヒントもありがとうございます!もう少し自分でも考えてみます。
稲葉様にいただいたコードも望んだ通りではありますので
もしこれ以上答えが見つからなければ活用させてください。

色々と教えていただきありがとうございます!
とても勉強になりました。

(VBA初心者) 2020/12/14(月) 19:55


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.