ワークシートの一部を選択してPDFに変換する
VBA×PDFのシリーズ2つめの記事です。マクロを使って請求書を作られている方から質問をいただきました。
「手作業で範囲指定した場所だけPDFにして保存したい」けど出来ますか?という内容でした。
結論から申し上げますと可能です。ただ出来るのではなく「簡単にできる」を実現させます。
選択した場所だけサクサクPDFとして出力できれば時短になりますよね。
加えて自身で選択した場所だけPDFを発行するのでプレビューを見直す手間も省けそうです。
先程の質問を含めてリストに提示した環境の方にも参考になるコードを用意しました。
- なんらかの仕様で印刷範囲が決まらない、決められない
- ワークシートに情報が揃ってからじゃないとPDF発行の範囲が決まらない
- 単純に作業が面倒なので簡単にしたい
今回もボタンでコードをコピペ出来る様にしておきました。(半自動化といった感じでしょうか)
エクセルのワークシートにボタンを用意してマクロを埋め込んで使っていただくと時短になります。
関連記事
シリーズ最初の記事です。
ワークシートからPDFを発行する際に使うExportAsFixedFormatメソッドの説明をしています。
このメソッドはパラメータがたくさんあります。主要なパラメータについて解説をしています。
ワークシート内の範囲を指定してPDFを発行する
サンプル事例を見ていただきます。一連の操作を紹介しますのでイメージを掴んでください。工程は3つです。
結論としては指定範囲のみを使い「ファイルの種類をPDFに指定」&「名前を付けて保存」を実現します。
1、PDFを発行する際のファイル名を指定します。セルK6に「sampleA」と入力しました。
この値(sampleA)をファイル名として選択された範囲でPDFを発行します。
2、ワークシートの一部を選択します。ここではセルB4からG10を選択しています。
3、PDFを発行します。トリガーはセルK3付近にある「PDF」というボタンです。
これでセルK6に記入したファイル名をもって範囲指定された場所のデータをPDFに変換する事ができます。
簡単にボタンを作る事ができますボタンの作り方についてはコチラをご覧ください
選択された範囲のみでPDFを用意できましたね。では別の範囲選択してPDFを発行してみます。
ファイル名をsampleBにします。加えてセルの選択範囲もB15からG21に変えました。
「PDF」ボタンに埋め込まれたマクロを実行してみます。
sampleAのデータと同様に範囲指定した場所だけでPDFを発行できました。
程々OKなのですが1つ気になるところがあります。
この画像ではPDFファイルにセルK6に用意したファイル名がセットされているのかは分かりません。
ブログを読んでいただいている皆様がこの後に紹介するコードをコピー、実行して確認ください。
コードと解説
先程見ていただきました画像の処理に対応したコードを紹介します。その後解説をしていきます。
最後にこのコードに関連する内容で「出来そうで出来ない事」を紹介します。
コード
まずはコードです。プロシージャは1つです。前回記事からの変化点である3点だけ解説します。
前回記事ではベースとなるコードについて解説していますのでまだ見てない方は適宜ご覧ください。
変化点は以下3点です。
- 変数rngを使う
- ファイル名をセルから取得する様にしました
- ExportAsFixedFormatメソッドでIgnorePrintAreasにFalseを指定しました
それぞれの詳しい説明はコードを見ていただいた後に解説していきます。
Sub ワークシートの一部だけPDF()
'手動で範囲指定された場所だけPDFに変換
Dim ws As Worksheet '対象のワークシートを格納するオブジェクト変数
Dim name As String 'ファイル名を格納する変数
Dim rng As Range '手動で範囲指定されたセルを格納するオブジェクト変数
Set ws = ActiveSheet 'アクティブシートをオブジェクト変数wsに格納
name = ws.Range("K6").Value 'ファイル名を格納
Set rng = Selection '選択範囲をオブジェクト変数rngに格納
Debug.Print rng.Address '必要に応じて削除
ws.PageSetup.PrintArea = rng.Address '選択範囲をPDF生成範囲とする
ws.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=ThisWorkbook.Path & "/" & name, _
IgnorePrintAreas:=False
End Sub
解説
先程提示したポイントをもとに解説していきます。
1_変数rng
変数wsと同じようにオブジェクト変数として使います。手作業で選択した範囲を格納する為の変数です。
どんな値が格納されているのか分かる様に13行目にDebug.Print・・・のコードを用意しておきました。
VBEのイミディエイトウィンドウに指定された範囲が表示されますので確認してください。
(このコードは作業に慣れたら消してください)
この値を見ると自身で選択した範囲がどのような値となって変数に格納されるのかが分かります。
2_ファイル名をセルから取得
セルK6に記入した値(文字列)を変数nameに格納する事にしました。
これで1つのシートから異なる範囲のデータをPDFに変換しても名前を変えてデータを保存できます。
3_IgnorePrintAreasにFalseを指定
IgnorePrintAreasにFalseを設定すると事前に選択された印刷範囲を踏襲する事になります。
(詳しくは前回記事を参照ください)
結果「変数rngに格納された値」=「PDF発行時の対象範囲」になります。
デフォルトはFalseなので書かなくてもよいのですが他者が見ても分かるコードにしておくことも必要です。
しっかりコードとして残しましょう。間違えて引数をTrueにしない様にご注意ください。
出来そうで出来ない事
セルの範囲を指定する時に飛び地を指定すると1枚のPDFにデータを終結させる事ができません。
飛び地を指定してマクロを実行すると各範囲毎にPDFが生成されますのでご注意ください。
(PDFファイルとしては1つですがPDFの中で指定した範囲毎にPDFのデータが用意されます)
実際に作業を見た方が分かり易いので画像を用意しました。
以下画像の様にセルB4からG10、セルB15からG21を選択しファイル名をsampleCとします。
これで「PDF」ボタンを押してみます。
発行されたPDFはsampleCという名前で1つのPDFファイルです。
しかしファイル内でデータは2つに分かれています。
1つのデータ枠の中に2つのリストを終結させる事はできません。
イミディエイトウィンドウを確認してみよう
この時変数rngの値はどうなっているのか?イミディエイトウィンドウの値を見てみましょう。
2つのセル範囲を持っていますね。この様に分割されて別々に範囲を持つことは出来ています。
しかし結合まではしてくれないので2つの範囲をそのままPDFとして出力するという事が起きています。
対策
回答とまではいかないのですが出来る範囲での対策を紹介します。
1つのデータ枠の中に2つのリストをおさめたい時は画像の様に飛び地にならない様に範囲を選択しましょう。
その際2つのリスト間のスペースが気になる方はセルを非表示にする事でスペースを消す事ができます。
具体的な方法としては画像のセル11行目からセル14行目を非表示にしてください。
セルを非表示にする事で印刷範囲として認識されなくなります。
これで2つのリストを近づけてPDFを発行する事ができます。
つまりPDFを発行する前の事前準備が必要という事ですね。
「レイアウトはシート上で決める」という思考を持ってください。
応用編:特定文字を取得してデータ範囲として定義する方法
本記事では事前にセルを選択した後にPDFに変換するコードを用意していますが別の方法もあります。
例えば「***」という文字が居るところまでをPDFの対象範囲にしたいという場合です。
そんな時はFindメソッドがおすすめです。Findメソッドの戻り値はRangeオブジェクトだからです。
戻り値として取得したRangeオブジェクトをそのままPDFの対象範囲(始点or終点)に使う事ができます。
他に特定文字を取得する方法としてはLike演算子がおすすめです。
私はLike演算子を使う事の方が多いです。理由はワイルドカードが充実していて多様性のあるコードが書けるからです。
文字列検索と照合の定番VBAで文字列を比較Like演算子とワイルドカードで完全/部分一致を確認【一覧で表示】
まとめ
1つのシート内のデータから範囲を指定してPDFを発行するという事例を見ていただきました。
範囲指定したセルの情報が変数rngにどうやって格納されているのかが分かると理解が進みます。
これだけでも手作業でやるよりは大幅な時短が望めます。お試しください。
参考:今回の記事はシリーズ化されています。次回記事を紹介します。