年賀状の宛名面作成は、Wordの差し込み印刷を利用するのが一般的です。
ただ、私はWordが苦手でExcelだけで年賀状宛名面を作成したくて用意したマクロの作成手順をご紹介します。
なお、汎用性はありませんので、参考程度にご覧ください。
大まかな仕組み
まず前提として、件数は100以下で住所の分割は試行錯誤で実行して設定する運用を想定します。
宛名面の雛形(テンプレート)シートを用意して、このシートをコピーして実データを反映させて行きます。
雛形(テンプレート)Sheet
このシートに用紙サイズなどの情報もセットした上で、テキストボックス(シェイプ)を配置します。
今回用意した雛形(テンプレート)はこちらです。
テキストボックス(シェイプ)の枠線はなしです。
郵便番号欄もテキストボックス(シェイプ)にしていますが、こちらはセルにしてもいいかもしれません。
この郵便番号の位置調整がもっとも大変な作業でした。
各テキストボックス(シェイプ)に名前をつけておきましょう。
テキストボックス(シェイプ)を選択して、数式バーの左の名前ボックスに入力することで、名前を付けることができます。
差出人情報はデータからセットせず、雛形(テンプレート)に直接入力します。
各テキストボックス(シェイプ)は原則上詰めですが、2つ目の住所だけ下詰めで設定しています。
住所のテキストボックス(シェイプ)の文字列方向は「縦書き」を選択して、半角文字は横向きになるようにします。
各テキストボックス(シェイプ)の文字の大きさ、フォントも設定しておきます。
ここから、テキストボックス(シェイプ)の呼び方はシェイプに統一します。
宛先情報の各シェイプに表示する内容は、セル参照にしてセルに反映させる方法もありますが、今回はプログラムで直接セットします。
住所録Sheet
今回用意した住所録はこちらです。
汎用性がないと申し上げましたが、原則苗字も名前も原則3文字内という制約を設けています。
苗字と名前の文字数の組み合わせパターンを絞って制御できるようにしています。
私の場合、この例外は少なく数件程度は手修正で対応することにしています。
VBAプログラミング - 宛名面作成
コードそのものは必要最小限にして、説明を中心にします。
雛形(テンプレート)Sheetをコピー
コピーしたシート名は分かりやすいものがいいのですが、被ることが許されないので行番号を組み合わせるなど工夫してください。
このシートをアクティベートします。
シェイプに表示内容をセット
シェイプに表示内容をセットするコードです。
ActiveSheet.Shapes(「シェイプ名」).TextFrame.Characters.Text = 「表示させたい文字列」
ただ、住所録から加工してデータをセットする項目もありえるので個別に説明します。
郵便番号
郵便番号が決まったフォーマットで記載されているならいいのですが、いくつかのフォーマットが混在している場合は、こちらの記事を参考に関数(ファンクション)を作成してください。
account-it-dentist.hatenablog.com
正規表現が分からない場合はそのままコードをコピーして使って問題ありません。
個人的に使用するだけなら強制的にエラーにする処理の方がデバッグには便利です。
住所
一般的にアラビア数字を漢数字に変換する機能がある住所録ソフトが多いので、必要な方は組み込んでおきましょう。
アラビア数字のままでいいという方も含めて、半角文字は横向きになってしまうので、StrConv関数を使って半角文字を全角文字に変換しておきましょう。
ここで問題になるのが「4-23-1」といった表示のとき、ハイフンを全角にするとハイフンが横向きに表示されてしまいます。
そのため、その後ハイフンだけを半角に変換する処理をしてください。
大丈夫なはずですが、「コーポ」のように伸ばし棒が住所にあるときは、伸ばし棒が半角に変換されていないか確認してください。
(下の)名前シェイプの上下位置調整
名前系シェイプはデータ変換自体は不要だと思いますが、配置バランスの設定をしたいので、ここからはその内容です。
それぞれ3文字内のパターンで設定しますが、連名があるときは私は文字数が多い方に合わせています。
少ないほうに合わせたい人は雛形(テンプレート)のシェイプを下詰めにするなどちょっと設定が変わるかもしれません。
シェイプの上下移動はマクロの記録が便利です。
コードは次の通りで、プラス数値を指定すると下にマイナス数値を指定すると上に移動します。
ActiveSheet.Shapes(「シェイプ名」).IncrementTop 「数値」
名前系シェイプの垂直方向の拡大・縮小
文字バランスのため、縦方向に長くしたり短くしたりしたい場合も、マクロの記録が便利です。
コードは次の通りで、数値は倍率を表し1以上は拡大で1以下は縮小です。
"msScaleFromTopLeft"と指定することで、シェイプのトップ位置を固定して拡大・縮小されます。
ActiveSheet.Shapes(「シェイプ名」).ScaleHeight _ 「倍率数値」,msoFalse, msoScaleFromTopLeft
名前系シェイプの文字間隔調整
残念ながら、Excelでは縦書きシェイプの文字を均等割り付けする機能がありません。
そのため、シェイプの拡大・縮小だけでなく文字間隔も調整しないと文字のバランスがとれません。
文字間隔の調整はマウスを使って調整できるものではないので、マクロの記録よりコードを作って数値調整するほうが効率的です。
数値は、プラスなら間隔を広げ、マイナスなら間隔を詰めます。
ActiveSheet.Shapes(「シェイプ名」).TextFrame2 _ .TextRange.Characters.Font.Spacing = 「数値」
VBAプログラミング - 印刷シート作成
追加した人の住所の表示確認や4文字以上の名前の人の手動調整をしたりします。
手動調整したひとは、別のファイルにコピー退避しておいて次年度はこのバックアップからコピー取り込みするようにしています。
あとは対象シートを選択してプリントすればいいのですが、シートの選択漏れがあったりすることがあり、印刷用シートを用意して宛名面の各シートをこのシートにコピー集約するマクロを用意しています。
この印刷シートをプリントすることで漏れが出ないようにしています。
(私は、雛形(テンプレート)のすべての行幅を同一にしているので)
まず、雛形(テンプレート)シートをコピーしてシート上のすべてのシェイプを削除します。
ブック内のすべてのWorksheetにループします。
私はコピーしたあとのシートを削除するので、このようなコードにしています。
Dim objSheet As Worksheet 'ワークシートオブジェクト 'シート削除時に警告表示しないように Application.DisplayAlerts = False For Each objSheet In Worksheets '処理内容を記述 Next objSheet Set objSheet = Nothing Application.DisplayAlerts = True
すべてのシートに対してループしていますが、住所録のシートや雛形(テンプレート)シート、いま作成している印刷シートなどは処理対象外です。
VBAには'Continue'コマンドがないので、このようにコーディングしました。
Dim blnON As Boolean blnON = True With objSheet If .Name = 「処理対象外シート名」 Then blnON = False If blnON Then '処理内容を記述 'シート削除 .Delete End If End With
Cut(Copy)&Pasteする処理を記述します。
100件以内のため、私は縦に連続して貼り付けていってもオーバーフローする心配はありません。
私は設定していませんが、印刷範囲指定やページブレイクの処理を必要に応じてコーディングしてください。
参考までに2ページ目以降貼り付け後にページブレイクする処理を組み込んでみたのですが、私の環境では'DoEvents'を記述しないとエラーになってしまいました。
あとがき
冒頭で記述したとおり汎用性がないのですが、4文字以上の名前や連名が3名以上などのレアケースは手動対応することは個人利用では合理的だと思っています。
一方で会社名や部署、役職名が必要なケースは相当件数あるのが実際です。
ただこのパターンは自作せず、APRINTというフリーソフトを利用しています。
もともとすべての宛名印刷はAPRINTで行っていて、優秀なソフトだと思っています。
ただ、
- フォントが選べない(小さな不満)
- 連名のとき位置調整が面倒(大きな不満)
があり、連名のときにトップ位置が並ぶようにこのマクロを作成しました。
しかし、会社名などが必要なものはパターンがいくつもあり自作するのは不可能なので、引き続きフリーソフトを使用しています。
個人が汎用性のあるものを自作することは現実的ではないと思いますが、ある程度パターンがしぼれるなら、自作することで有償または無償のソフトウェアの不満点を解消できるので、VBAが苦手な方も挑戦してください。
(ただWordが苦手でないなら、均等割り当てでき印刷シート作成などしなくてすむWordを使った方が面倒が少ないと思います。)
ご質問は下の 「コメントを書く」 からお願いします。
ExcelやVBA全般に関わる質問で、比較的簡単にお答えできるものはできる限り回答したいと思います。
回答を公開でなくメールでやり取りしたいという場合は、その旨記載していただければ非公開で回答することも可能です。
有償での作業依頼は非公開にしますので、条件等をお知らせください。