素人がExcelVBAによる「一人働き方改革」に挑むブログスマートフォン用の表示で見る素人がExcelVBAによる「一人働き方改革」に挑むブログExcelVBAネタです。VBA自作クラスワークシートを新規Excelブックとして出力するクラスワークシートを新規Excekブックとして出力する名簿なんかの一覧表をマクロで自動作成して、相手方にPDFで提供すると、しばしば加工したいからExcelのままでくれ!と言われることがよくある。大量(っつっても大した量でもないけど)の元データやマクロだらけのブックをそのまま送りつけるわけにも行かないので、必要なシートだけを新しいブックにコピペして提供、という形になる。それも1つや2つなら手作業でポンとやっておしまい、なんだが、次から次へ、となるとさすがにめんどくさい。やってみたのがakashi-keirin.hatenablog.comなんだが、今後こうした作業が頻発することが予測されるのでクラス化しといた。Description:="インスタンス生成後にinitメソッドの使用が必要です。Description:="Workbook作成前に使用できません。Subかなりタテ長になってしまったので、パーツごとに解説する。2今のところ定数を2つ設定している。誤った使い方をした場合にエラーを起こすようにしているが、どのエラーを起こすのかを区別するためのもの。Booleanそれぞれの変数は、targetSheet_Excelブック化する対象のワークシートを格納する。filePath_新規Excelブックのフルパスを格納する。newWorkbook_新規Excelブックを格納する。isInitialized_擬似コンストラクタinitメソッドが実行されたかどうかを格納する。initメソッド実行済みであればTrue。Property今のところ、外部に公開するプロパティとしては、新しく作成されたブックが格納されているnewWorkbook_フィールドだけで良いと思っている。必要があれば再検討する。Subおなじみ、擬似コンストラクタ。引数としてExcelブック化したい対象のWorksheetオブジェクトを渡して実行する。Shで、引数として受け取ったWorksheetオブジェクトを変数targetSheet_に格納。Trueで変数isInitialized_をTrueにして、initメソッド実行済みかどうか分かるようにしている。True)で、引数を2つ設定している。第1引数fullPathは、新規に作成するExcelブックのフルパス。第2引数isOnlyToCreateは、Trueにすると指定したシートをそのままExcelブック化する。シートに何らかの加工をしてからExcelブック化したいなら、この引数をFalseにしておく必要がある。raiseError(NOT_INITIALIZED)では、このクラスのインスタンス生成後、initメソッドが実行されているかどうかを判定し、未実行ならraiseErrorメソッドを呼び出してエラーを起こさせるようにしている。このメソッドのメインの処理については、前に書いたのと全く同じなので、詳しいことはakashi-keirin.hatenablog.comをどうぞ。closeCreatedFileでは、第2引数の値によって、このまま新規ブックの保存・終了に進むのかどうかを分岐している。isOnlyToCreateがTrueならば、後は新規ブックを保存して終了するだけなので、closeCreatedFileメソッドを呼び出して終了。Falseだったら一旦ここで処理を中断して標準モジュールのメインのコードに戻ることになる。Subこちらは、新しく作成されたExcelブックに新しいファイル名を付けて保存し、ファイルを閉じる、という処理をしているだけ。raiseError(NOT_CREATED)で、新規ブック未作成ならcloseCreatedFileメソッドを呼んでエラーを起こさせるようにした。Description:="インスタンス生成後にinitメソッドの使用が必要です。Description:="Workbook作成前に使用できません。Integer)では引数typeOfErrorを設定している。あとは、受け取ったtypeOfErrorの値に応じてErrオブジェクトのRaiseメソッドを用いてエラーを吐かせているだけ。今後、新たなエラー原因が分かったら逐次追加していけば良い。その1こんなシートをアクティブにして次のリスト2-1のコードを実行してみる。ActiveSheetで、アクティブシートを一旦変数Shに格納。"都道府県別1.xlsx"では、新しく作成するブックのフルパスを変数strに格納。2回に分けているのは、可読性とメンテナンス性のため。別に1回で書いてもいい。ExcelFileCreatorでExcelFileCreatorクラスのインスタンスを生成して変数xlsxCreatorに格納。ShでExcelFileCreatorクラスのinitメソッドにSh(対象のWorksheetオブジェクト)を渡して実行。TrueでExcelFileCreatorクラスのcreateExcelFileメソッドにstr(新規ブックのフルパス)を渡して実行。第2引数がTrueなので、指定したWorksheetオブジェクトに何も加工せずに保存・終了することになる。実行結果このように、「超人墓場」フォルダに「都道府県別1.xlsx」ができていて、開くとこの通り、シートがそのまま保存されている。このままだと、いかにもA~C列が邪魔。いって手動で削除するとなると果てしなくダルい。そこで、新しいブックを作った後、A~C列を削除した後で保存・終了する、という処理にしてみる。その2リスト2-1を次のように書き換える。Withこの部分だけ。(1)でcreateExcelFileメソッドを呼び出すときの第2引数をFalseにし、(2)でA~C列を削除してから、(3)でcloseCreatedFileメソッドを呼び出して新規ブックを保存・終了している。実行結果このように、「超人墓場」フォルダに「都道府県別2.xlsx」ができていて、開くとこの通り、A~C列だった部分が削除されてシートが保存されている。おわりに今回紹介した程度の処理なんて、フツーに考えたらSubとかFunctionのレベルで再利用すればよいものだと思うが、一連の作業をやっていて、改めて「クラス」って便利だなーと思った次第。実は、closeCreatedFileメソッドというのは、もともと一連の処理だったものの最後の部分だけを切り出したものなんだが、クラスにしたおかげでめちゃくちゃ簡単に切り出すことができた。いうのも、保存して閉じる、という作業に必要なデータである新規ブックのフルパスを、このクラスのインスタンスが既に保持しているので、いちいちこのメソッドにフルパスを引数として与えなくても済むから。処理に必要なパラメータが多いときに、プロシージャ間でのデータのやりとりがめちゃくちゃ煩雑になってしまうのだ。変数のスコープを広げたら済む話なんだが、むやみやたらと変数のスコープを広げるのはやっぱり怖い。その点、クラスのインスタンスにデータを持たせていたら安心。インスタンスが生きている限りいつでもデータを参照できるので。単独のSubとかFunctionの場合、ファイル単位ではエクスポートできないけど、クラスモジュールならファイル単位でエクスポートできる。ハードVBAerならクラスモジュールを使わない手はないよなあ。「改良」なのかどうかはわからんが。»プロフィールid:akashi_keirinExcelVBAネタです。SyntaxHighlighter.all();注目記事はてなブログをはじめよう!akashi_keirinさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。