2024-03-02

エクセルマクロのお作法計算用シートという諸悪の根源について)

前置き

この日記の内容は、会社の後輩から最近エクセルマクロ勉強し始めて(キラキラ)」という話を聞いて、先輩ムーブかますために話した内容になります

とにかくこれから説明する「計算用シート」が憎くて憎くてたまらず、ちょっと引かれるほど熱弁してしまいました。

ただ、他の方がどうされているのかや、逆に「計算用シート」を愛用する方の意見も聞きたくなり、増田に書いてみました。

増田の経歴

この記事趣旨

エクセルマクロのお作法とか書きましたが、要するにエクセルマクロで「計算用シート」って色々な意味でよくないよね、という話をしたいです。

3行でまとめます

〇 エクセルシートはユーザーインターフェースインプット)か出力結果(アウトプット)のためのものとすべき

〇 データ加工をする場合には、原則配列辞書配列連想配列)に格納して加工を行い、最後の結果だけシートに出力するべき

〇 何事にも例外はある。

計算用シートとは

この記事では、エクセルシートを下記の通り分類します。

エクセルマクロにも色々あると思いますが、今回は下記を想定します。

日付や人物名などを入力し、データベースや別のエクセルファイル、別のシートから取得したデータ入力された値を基に加工し、加工後のデータをシートに出力する

この場合入力欄があり編集可能なシートがユーザーインターフェース、最終的に加工されたデータが出力されるシートが出力結果です。

(もちろん、ユーザーインターフェースの別の欄(セル)に出力する場合もあるし、その場合ユーザーインターフェース出力結果が一体のものとみなします。)

また、データ用シートは同じエクセルファイル内に基となるデータが含まれ場合を想定します。

(これ自体が非推奨で、SQLデータベースかせめてAccessを使え、という意見はありますがそれは別にして…)

ではここで定義する計算用シートとはなにかというと、文字通り計算を行うためのシートです。

例えばイメージするのはこんなマクロです。

1.元となるcsvファイルエクセルに読み出してシートに格納

2.そのデータは日付が数値型になっているので、日付(数値型)の入った列を文字列に変換した日付(文字列型)列を新たに作成

3.その列をキーとして対象となるデータを取り出すvlookup関数を各行に格納した列を新たに作成

4.その列で特定された列をさらに加工した列を新たに作成し、…

これは極端な例ですが、とにかく変数配列定義せず(あるいはエクセルセルオブジェクト変数のように扱い)、エクセルに値を入力し、それを直接加工することで目的となるデータ加工をしたり、様々な処理をします。

その舞台となるのが、計算用シートです。

なんかこんな感じの処理をしているエクセルマクロ、どこの会社でも腐るほどあるんじゃないでしょうか。

ある程度マクロに慣れた気の利く人なら、このシートはロック非表示にして、ユーザーから触れないようにするでしょう。

・・・これ、やめたほうが良くないですか?

こいつが日本生産性を落とす諸悪の根源だと思います

駄目な理由

ある程度詳しい人なら同意してくれると思いますが、このやり方でダメ理由はいっぱいあります

後で説明する配列辞書配列連想配列)と比べると格段に処理が遅いです。

わざわざエクセル操作しているから当然ですね。

ちょっと詳しい人が知っている「画面更新非表示」を駆使しても、配列を使った処理からみれば止まったハエです。

(参考)VBAで作ったマクロの高速化① 配列を使う

  • 可読性が下がる

いったんエクセルシートにデータを格納して加工しているので、コードエクセルシートを両方見る必要があり、とても読みにくいです。

変数として命名されていないのも致命的で、処理の意図が余計に分からなくなります

計算用シートを事前に用意して、別のセル関数を格納しておき、マクロ関数を使ってデータ加工をするものも見たことがあります

これは懲役刑に処したほうがいいと思います

まり知られていませんが、セルの最大文字数は32,767 文字です。

セルの最大文字数を超えると自動的に隣のセルに値が入り、シートが滅茶苦茶になります

他にもエクセルの数値を丸め自動変換の仕様とか文字列→日付の自動変換とか、いくつものバグに苦しめられます

できる人だと、いちいち最大文字数が多い場合の処理を書いたり自動変換機能を殺したりしてくれますが、そんなことに手間をかけているか日本GDPは上がらないんだと思います

他にも、データが大きくなると処理が重くなり不安定になる、計算用シートを人が触ってしまリスクがある、などいくらでも理由は上げられます

(逆に利点は、目の前でガチャガチャ動いてスーパーハッカーになった気分になれるくらいしか思いつかない・・・

じゃあどうするの

配列を使いましょう。

配列とは何ぞや、という人はググってください。

配列データを入れて、データ加工は配列変数に対して行い、一番最後の出力だけセルに値を格納する。

他のプログラミング言語なら普通にやっていることです。

個人的オススメしたいのは辞書配列連想配列)で、うまく使うとデータ管理簡単になり、処理も爆速になります

(参考)【VBA】大量データから高速で値を検索【Dictionaryを使う】

csvファイルもなまじエクセルで開けるだけに別のブックやシートで開きがちですが、これは悪魔のささやきです。

直接ファイルを読み出してLine InputやSplitで配列に格納しましょう。

エクセルとして開くやり方はコード書くのは簡単でも、実行時間に天と地ほどの差が出ますエクセル開くと処理もめちゃ不安定です。

(参考)Excel VBAでCSVオープンするときのパフォーマンス比較

いや、冒頭のマクロを書く人の気持ちも分かるつもりです。自分コードを書き始めたころは全部シート上で操作していました。

冒頭のマクロのほうが直感的なんですよね。自分が手で書くことをマクロやらせる、というマクロ本来趣旨にはあっていますし。

途中の計算過程もすべて目の前で展開されるから分かりやすいです。

ただ、それではダメなんです。。。処理は遅いし挙動不安定だし後で改修・保守する人が死にます

あと、エクセルシートやセルは当然エクセルしかないので、エクセルマクロVBAから他の言語に移れなくなります

自分エクセルマクロの里の出なので、計算用シート脱却には苦労しましたが、苦労して会得した配列辞書配列連想配列)のスキルはそのまま他の言語に活かすことができました。

配列の中身を見る方法別にある(ローカルウィンドウやDebug.printを使うなど)ので、リハビリに取り組んでほしいです。

(参考)VBA デバッグの仕方

もちろん例外もあります

計算用シートを許容できる、使うべきケースもあると思います。。

個人的には、

最後のは、なんでも自分確認しないと気が済まない上司発注で、意味不明と思いましたしたがしぶしぶやりました。)

などの場合計算用シートを使ってもよいと思います

この場合インプットエクセルシートに直接加工するのは論外なので、計算用(加工用)のシートを用意してそこで操作を行うことは必要だと思います

他にも、こういうときは「計算用シート」があったほうが良い、という状況があれば教えてもらえると嬉しいです。

最後

そもそもツッコミとして、「データ加工するならエクセルマクロを使わずpythonとかRとかもっとまともな言語使えよ」という言葉が来そうな気がします。

ただ、個人的にはエクセルマクロVBA)は大好きですし、初心者にもおすすめしたいです。

自分のような非エンジニアだと、セキュリティ関係などでPythonの開発環境とかすごく用意しにくいんですよね。

(あと、コマンドプロンプトの真っ黒な画面が怖かった)

その点エクセルマクロは、開発環境の用意はプロパティでチェック項目を一つオンにするだけだし、入門書がたくさんあるし、セル挙動を追えば視覚的にプログラム理解できるし、初心者に優しいです。

(そのやさしさが上述したとおり悪魔の罠なわけですが。)

最初計算用シートに頼ってでもエクセルマクロからプログラミングを始めて、本格的なデータ加工をし始めたあたりで計算用シートという諸悪の根源から脱却する。

さらに本格的なデータ処理を行うために、PythonやRなど別の言語習得したり、エクセルからSQLデータベースやACCESSなどに切り替えていく、というプロセスがいいのではと個人的に思います

  • 後で読みます

    • 住友情報システムがExelをWeb上でやるSaaSを作って、伝票とかにも対応してるのすごい労力だなと思った。 Reinventing the wheelは功罪言われるけど個人的には日本人のああいう努力は好き。

  • EXCEL原理主義からするとマクロを入れる時点でワークシート関数は入れない。 マクロがあるEXCELは読み取り専用。 アウトプットはEXCELでもCSVでも別ファイル。 入力画面はフォームにする...

  • Application.WorksheetFunction. て何度もコードに書いてると、じゃあ直接シートでやるか…って気持ちになるのだ

  • マクロぜんぜんわからんけどこの人が優秀で「わかってる」エンジニアなことは間違いない。

  • 原則関数とピボットテーブルのみで完結させ、マクロは使わない。ってのが良いと思う。 DBからデータぶっこ抜いたり(今のご時世は出来ないと思うが)、外部ファイルを読み込むとかしな...

    • DB直じゃなくてPowerBIのセマンティックモデルとし認証認可付きでデータ公開してExcelからPowerQueryとかで接続するのが今時じゃないかな

      • DBに保存するようなデータをExcelから編集する事自体今時じゃないやろ

        • 主要な目的は編集ではなく分析だね。一般ユーザにうかつにアクセスさせたくDBだけど、そのうちの一部のデータを見せてプロジェクト企画とか評価とかで使わせるのは有用なケースでは...

  • 太字のところが要点やな。どれどれ。 ……止まったハエ?懲役刑? なんやこれ?

  • Excelマクロって99割が技術的負債になるよねという話

  • VBA嫌いのExcel師(営業事務)なんだけど、その程度のことをVBAでやろうとするヤツを駆逐したい。 お前は営業や他のユーザーの理解度を自分レベルだと勘違いするのをやめるべき。 うちの...

    • 関数でできることは関数でやれ、というのには同意 最近は便利な関数も増えた 昔はVBAで処理したり関数作ってたようなものも、Excel側で用意されるようになった 業務で何かしらの処理を...

      • 複雑な関数はコードに劣る

      • 素人の書くクソ関数より、VBAの方が把握しやすいことが多い

        • 素人の書くクソVBAより、関数の方が把握しやすいことが多い

          • 同じ様な関数が全部の行に入ってるけどソートしたり行を削除したせいか途中でズレてたりするのが地獄

            • 一番上の正しいセルから全コピするだけ 1秒で直る

            • テーブルかと思ったらただのフィルター 同じ列には同じ式かと思ったらたまに違う こんなのばっかりやぞ

  • listobjectを普通に使って不規則な並びの表を作らない LET関数を使って読みやすく書く これだけやってくれればそんなに凝らなくてもいいのにな エクセルは余計なことをするやつが多く...

  • Excelの作法というか極意は知らないフリだろJK 他人のことは放っておけ たまに自然発生するExcel先生に適当にやらせときゃいい 手作業頑張った感が出る中間ファイル生成させるとかや...

    • これ自分もやる 相手が手作業でやる前提の見積もりしてるなら、わざわざそれを減らす必要ない VBAは便利だけど実際の業務に組み込むとなると賛否あるし面倒も多い 外向きには手作業...

  • 全てをエクセル上でやろうとする日本のやり方は最早悪癖を超えて一種の文化とすら言える

  • はてなで技術者気取りのオナニー説法とか鼻で笑うわ

  • エクセルVBAってさ、「そんなに頭良くない奴でも1週間勉強すれば”何か動く”ものが作れる」ってとこが最大の功罪なんだよね。 ウチの職場にポンコツすぎて干されたじぃさんとおばさ...

  • Excelでシステム構築することは良くないと言われがちだけど、何故良くないのかを説明するのは難しいな。 自分はExcelでシステム構築とかしたことがないから、何を話しても具体性の無い...

  • 経営者としてお答えしよう ファック死ね   てめぇの趣味に給料払うのがどれほど不愉快か想像してほしい。 業務時間を割いてなにかやってるのは知っていが注意すると拗ねてモチベ下...

  • イベントリスナー実装するの面倒。 セルにデータ入力したらリアルタイムでチェック欲しいときに、Worksheet_Changeイベントのプロシジャをシートに書かないかんの面倒すぎる。

  • 処理遅いのは表示更新してるからでしょ? 表示更新オフにすればいいじゃん。

  • 増田が自分で言及している通り、 そもそも本格的なデータ加工や解析、統計だったらAccessなりOracle DBなりを使うべきであって、エクセルVBAはしょせんエクセルVBAなのよ。 エクセルVBAが上...

記事への反応(ブックマークコメント)

ログイン ユーザー登録
ようこそ ゲスト さん