[[20210128144815]] 『VBAで別bookを印刷』(プリン) ページの最後に飛ぶ

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

 

『VBAで別bookを印刷』(プリン)

お世話になります。
最近VBAの勉強を始めたばかりの初心者です。そのため頓珍漢な部分が多数あると思います。
VBAで組みたい内容は以下です。
"Desktop"に保存されている"△.xlsx"のシート名"△"を指定したプリンター"〇"で印刷。印刷後、デフォルトのプリンター"×"に戻す。

以下はデスクトップの△というエクセルを〇というプリンターで指定枚数印刷する
という内容をこんな感じかな…と組み途中のものです。
どこを訂正していけば良いのかよく分からず困っております。
非常に見づらいマクロで申し訳ありませんが、アドバイスいただけませんでしょうか。

Sub 印刷()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableEvents = False

Dim ws As Worksheet
Dim P As Long '//P:ページ数指定
Dim ans As String
Set ws = △.xlsx.Worksheets("△")

    Workbooks.Open "C:\Users\a\Desktop\△.xlsx"
    ws.Activate
    ans = InputBox("ページ数を入力", "印刷枚数は?", "")
    If ans <> "" Then
    P = ans
    End If
    Application.ActivePrinter = "プリンター名〇 on Ne〇:"
    ws.PrintOut Copies:=ans
    Application.ActivePrinter = "プリンター名× on Ne×:"
    Call ws.Close

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub

よろしくお願いします。

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


とりあえず、一点だけ指摘します。

Set ws = △.xlsx.Worksheets("△")
↑とされていますが、この時点で、「△.xlsx」が Workbook であることをVBA君は認識していません。
ここまでで、「△.xlsx は Workbook ですよ」ということをVBA君に伝えていないからです。

ですので、「なんだかよくわからないモノ の Worksheet」を指定されても「わかりません」という状態になっています。
Worksheet を指定しようとする前に、「△.xlsx は Workbook ですよ」というコードを書いてあげてください。
(じゃふ) 2021/01/28(木) 15:53


すでにコメントされていますが、ブックを開く前に、そのブックに属するシートをセットするのは無理がありますから、まずはそこを修正しましょう。
また、どうせプリンタを戻すなら、決め打ちじゃなくて、変更前のものを一時的に覚えておくようにしたほうが汎用性が高いとおもいます。

    Sub 印刷()
        Dim 部数 As Long '←部数だから数値型が妥当
        Dim ws As Worksheet
        Dim buf As String 'ActivePrinter退避用

        部数 = InputBox("ページ数を入力", "印刷枚数は?", "")
        If 部数 > 0 Then
            Set ws = Workbooks.Open("C:\Users\a\Desktop\△.xlsx").Worksheets("△")

            'プリンタを一時的に切り替えて印刷
            buf = Application.ActivePrinter
            Application.ActivePrinter = "プリンター名〇 on Ne〇:"
            ws.PrintOut Copies:=部数
            Application.ActivePrinter = buf

            ws.Parent.Close False
        End If

    End Sub

(もこな2) 2021/01/28(木) 19:51


お二方ともありがとうございます。
大変勉強になります。

プリンターの"Ne"部分が変わってしまう場合がある為、
Neを指定しなくても動作するように"もこな2 様"のコードを元に以下のコードを組んでみました。

Sub 印刷()

        Dim 部数 As Long
        Dim ws As Worksheet
        Dim tmp As String
        部数 = InputBox("ページ数を入力", "印刷枚数は?", "")
        If 部数 > 0 Then
            Set ws = Workbooks.Open("C:\Users\a\Desktop\△.xlsx").Worksheets("△")
            With Application
                tmp = .ActivePrinter 'デフォルトプリンターを記憶
                .ActiveSheet.PrintOut ActivePrinter:="プリンター名〇"
                ws.PrintOut Copies:=部数
                .ActivePrinter = tmp '印刷後に元のデフォルトプリンターに戻す
            End With
        End If
        ws.Parent.Close False
End Sub

印刷枚数入力時、やっぱり印刷をやめよう。と思ってキャンセルを押した場合、

実行時エラー'13':
型が一致しません。

というポップアップが表示されてしまいます。
これはどうすれば解決できますでしょうか。
キャンセルを押した場合、プリンターはデフォルトのままにしたいです。

よろしくお願いします。
(プリン) 2021/01/29(金) 09:12


http://officetanaka.net/excel/vba/tips/tips37.htm
とかが、参考になるかと。
戻り値が何かを、確認して対応されると
宜しいかと。
ロング型で受けずに、バリアント型で受けて、ステップ実行で
ご確認を、↑の場合キャンセルだと "" が返っていると思います。
後、テキストでも受けてしまいますので、数値か確認処理もいるかと
Application.Inputbox
の方が使いやすいかもです。
(隠居じーさん) 2021/01/29(金) 09:44

「VBA InputBox キャンセル」というキーワードで検索してください。
と書いていたら、既に検索してくださっている方がいらっしゃいました。

>やっぱり印刷をやめよう。と思ってキャンセルを押した
>キャンセルを押した場合、プリンターはデフォルトのままにしたい
つまり、キャンセルの場合、印刷はしないようにしたいのですよね?
「キャンセルならプロシージャを抜ける」という流れで書けば、
そもそもプリンターの変更命令を実行しませんから、ご希望のとおりになると思います。
(じゃふ) 2021/01/29(金) 09:46


ちんたら書いてたら編集が被っちゃいましたが・・・そのまま投稿します。

>型が一致しません。
キャンセル押した時は""(文字列)になりますからねぇ・・・
あんまり真面目に考えてませんが、「部数 > 0」という判定をしているので、エラーは無視しちゃったらどうですか?

また、PrintOutメソッドの引数でプリンタを指定するなら、覚えておく必要や元に戻す必要って無いような・・・(試せる環境にないのでちょと自信なし)

    Sub 印刷()
        Dim 部数 As Variant
        Dim ws As Worksheet

        On Error Resume Next
        部数 = InputBox("ページ数を入力", "印刷枚数は?", "")
        On Error GoTo 0

        If 部数 > 0 Then
            Set ws = Workbooks.Open("C:\Users\a\Desktop\△.xlsx").Worksheets("△")
            ws.PrintOut ActivePrinter:="プリンター名〇", Copies:=部数
            ws.Parent.Close False
        End If
    End Sub

>キャンセルを押した場合、プリンターはデフォルトのままにしたいです。
キャンセルした場合は、「Application.ActivePrinter」を書き換えなきゃいいですよね。

(もこな2) 2021/01/29(金) 10:14


 試してみましたが(win7(64),Excel2010(64))

 >PrintOutメソッドの引数でプリンタを指定
 すると ActivePrinterは切り替わるようです。 
(チオチモリン) 2021/01/29(金) 13:58

>ActivePrinterは切り替わるようです。
なるほど。検証ありがとうございます。
そしたら、覚えておいて戻さないとダメですね・・・

(もこな2) 2021/01/29(金) 14:20


みなさまありがとうございます。

現状以下のようになっております。
問題なく動作していますが、何か改善点等はありませんでしょうか?
今後に生かしたいですので、
アドバイス、ダメだし、些細な事でもよろしくお願いします。

Sub 印刷()

        Dim 部数 As Variant 'Long型だとFalse部分でエラーになる
        Dim ws As Worksheet
        Dim tmp As String
        部数 = Application.InputBox(Prompt:="印刷枚数は?", Type:=1)
        If 部数 = "False" Then Exit Sub
        If 部数 >= 1 Then  '> 0でも良さそうですが、こちらにしました。
            Set ws = Workbooks.Open("C:\Users\a\Desktop\△.xlsx").Worksheets("△")
            With Application
                tmp = .ActivePrinter 'デフォルトプリンターを記憶
                .ActiveSheet.PrintOut Copies:=部数, ActivePrinter:="プリンター名〇"
                .ActivePrinter = tmp '印刷後に元のデフォルトプリンターに戻す
            End With
        End If
        On Error Resume Next
        ws.Parent.Close False
End Sub

(プリン) 2021/01/29(金) 17:57


 内容修正のため一旦削除

(もこな2) 2021/01/29(金) 18:20


こうでは
If 部数 = False Then Exit Sub

(マナ) 2021/01/29(金) 18:45


マナさんの指摘とかぶっちゃいましたが、まとめて投稿しなおします。

ダメだしというか。

■1
なんで↓にしたいんですか?

 Application.ActiveSheet.PrintOut

そうするなら↓いらなくないですか?

 〜.Worksheets("△")
   ~~~~~~~~~~~~~~~~~~
■2
↓は消し忘れですか?
 On Error Resume Next

■3
厳密にいえば、キャンセルしたときは、"False"という文字列ではなく、Falseという論理値が返ってきてますよ

 部数 = Application.InputBox(Prompt:="印刷枚数は?", Type:=1)
 If 部数 = "False" Then

■4
「With Application」にしたい理由もピンときません。
そもそも"Excel"VBAの中で話が完結してるので、Applicationは省略可能だとおもいます。
(無論それが分かりやすいかどうかは別でしょうけど・・・・・)

■5
開いたブックは必ず目的のシートがアクティブになってるんでしょうか?
それなら、ActiveSheet.PrintOutでも問題無いでしょうけど

シートが1つしかないなら【ワークブックオブジェクト】.WorkSheets(1).PrintOutで指定が可能です。

■6
ふまえて私ならこんな感じでしょうか。

    Sub 私なら()
            Dim 部数 As Variant
            Dim tmp As String
            部数 = Application.InputBox(Prompt:="印刷枚数は?", Type:=1)
            '↑キャンセルしたときは、False(Boolean型)が格納される

            If 部数 <> False Then 'Boolean型として判定【分かっていれば「If 部数 Then」でも可】
                tmp = ActivePrinter 'デフォルトプリンターを記憶

                With Workbooks.Open("C:\Users\a\Desktop\△.xlsx")
                    .Worksheets(1).PrintOut Copies:=部数, ActivePrinter:="プリンター名〇"
                    .Close
                End With

                ActivePrinter = tmp '印刷後に元のデフォルトプリンターに戻す
            End If
    End Sub

ちなみに、修正コードについて部数にマイナス値を入れることは可能なので、変り者が居るようでしたら、また問題になりますね。
(0はFalseとみなされてトラップされます。)

(もこな2) 2021/01/29(金) 19:04


 こんばんわ。私の意見です。

 (1) InputBox 関数は文字列を返します。
   キャンセル時は空の文字列です。"" 
    Dim 部数 As Long 
     部数 = InputBox("ページ数を入力", "印刷枚数は?", "")
     では、代入時に暗黙の型変換が起こりますが、
   	""は型変換できないので、エラーになります。
   Val関数を使って明示的に変換してしまえばOKです。
   
     Dim 部数 As Long
     部数 = Val(InputBox("ページ数を入力", "印刷枚数は?", ""))
     If 部数 > 0 Then
     これでOKです。

 (2) Application.InputBoxメソッドでは、型を指定できます。
   Type:=1 では、数値が返ります。
     キャンセル時は Boolean型のFalseが返ります。
     これを整数型で受けてしまえば、暗黙の型変換によって0になります。

     Dim 部数 As Long
     部数 = Application.InputBox(Prompt:="印刷枚数は?", Type:=1)
     If 部数 > 0 Then
     これでOKです。False と比較する必要がなくなります。
(´・ω・`) 2021/01/29(金) 19:14

コメント返信:

[ 一覧(最新更新順) ]


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