VBAナメてた

 VBAナメてた

〜VBAを使ったら絶対に後悔する7つの理由〜
社内でLTしたスライドです

58ab8900254150820e685da7cd0d4d9f?s=128

Narazaka

April 27, 2016
Tweet

Transcript

  1. VBA ナメてた @narazaka

  2. 奈良阪 自己紹介 Twitter: Github: npm: CPAN: RubyGems: ドリコム2015 新卒入社 サーバーサイドRuby

    好きな言語: Perl / CoffeeScript / Ruby / C# / Ceylon? その他: 伺か/ 漫画読み描き/OP アニメ愛好家/ 鉄 @narazaka @Narazaka @narazaka NARAZAKA Narazaka
  3. VBA (Visual Basic for Applications) 1994 年のExcel5.0 から付属したマクロ用言語 Excel が有名だがWord

    やPowerPoint 等でも使える
  4. 顧客が説明した要件 プランナーさん: クエスト作成を便利にしてや 奈良阪: xlsx 使っとるしVBA やと移行コスト低そうか?

  5. プログラマの見積もり プランナーさん: ウィッスオナシャス 奈良阪: メンテコスト高いらしい 奈良阪: 綺麗にかいたらそんなでもないやろ( 慢心)

  6. VBA ナメてました

  7. 「Excel マクロつらい」

  8. 謎のセル指定

  9. なるほど…… ?

  10. VBA 、オブジェクト指向言語らしい? クラス書いたらよくね?

  11. 適切な変数名でマシになるっしょ? table_area = Range(area_begin, area_end)

  12. ……

  13. クラスにもした 変数名関数名とかにも気を配った

  14. None
  15. でもそういう問題ではなかった

  16. VBA || 20 世紀のMS 製品

  17. 最近のMicrosoft に毒気を抜かれて忘れていた

  18. 生産性が惨殺される体感

  19. 古き良きM$ を思い出させてくれる糞仕様の数々

  20. 7 連発

  21. VBA を使ったら絶対に後悔 する7 つの理由 ( 煽りタイトル)

  22. 1. 不完全な型システム

  23. VBA は一応オプショナルな変数型指定 を持ちます

  24. TypeScript のように、変数宣言時や関数宣言時にオプショ ンで型をつけられる これは良い

  25. 型付で宣言された変数はエディタ上でインスペクタが出て 使えるメソッドとかが出てくる これも良い

  26. 型情報最高!!

  27. にもかかわらず

  28. エディタでもコンパイラでも型チェッ クされない

  29. ?

  30. 「型が一致しません ( エラー 13) 」はランタイムエラー

  31. 引数の順番とか間違えてても全部ランタイムエラー

  32. せっかく入力したのに…… 型情報の持ち腐れ

  33. 不完全な型システムややつ らい

  34. dis ばかりでは一面的なので他言語などと比較して ※許せる点 エディタ上だけとはいえインスペクタ働くのは良い 実行時型判定でエラるので早期エラー発見にはなる どちらかといえば「口惜しい」 その他付随したしんどい点 変数名の補完はしてくれないのでめんどい

  35. 2. プリミティブ型とオブジ ェクト型で代入の方法が異 なる

  36. VBA は一応オブジェクト指向言語

  37. プリミティブ型とオブジェクト型 C++ やJava と同じ感じ プリミティブ型: Integer, Boolean 等 オブジェクト型: Range,

    ユーザ定義等
  38. プリミティブ型とオブジェクト型で代 入の方法が異なる

  39. ?

  40. プリミティブ型は Value = 1

  41. オブジェクト型は Set Value = New MyClass

  42. オブジェクト型の場合先頭に をつけなければならない

  43. ミス→ ランタイムエラー エディタは検出してくれない しかもエラーメッセージが謎

  44. 検出困難 なれるとそこまで間違わなくなるが、書き始めた初期はヤ バかった。

  45. 似たようなつらみ 関数とサブルーチン 返値あり -> 関数 (Function) 返値なし -> サブルーチン (Sub)

    の別もある(Fortran にもある)
  46. 呼び出し書式が違う

  47. 関数は引数に括弧をつける Set Data = Table.GetData(Row, True)

  48. サブルーチンではつけない Table.AddData RowData, True

  49. 関数呼び出しの不整合→ ラ ンタイムエラー エディタはスルー

  50. つらい

  51. プリミティブ型とオブジェクト型で代 入の方法が異なる 関数とサブルーチンの呼び出し方法が 異なる つらい

  52. ※許せる点 C++ でも値とポインタとの別があるし、(* をつける場合が 有るので) 代入方法が異なると言えなくもない 関数とサブルーチンの別はFortran にもある( サブルーチン はcall

    を先頭につけて呼び出す)
  53. 3. 関数が第一級オブジェク トではない

  54. 自分がこれまで使った言語 JavaScript(ES3,5,2015) Perl5.8 ~5.22 Fortran95 C C++(03 、11) D Java

    Python3 Ruby(2.0 以降) C#(5.0 、6.0) Excel VBA TypeScript CoffeeScript 華和梨8.2.8(kis) Windows バッチファイル bash スクリプト
  55. VBA 、バッチファイル、シェルスクリプトのみ 関数が第一級オブジェクトとして扱えない

  56. each map lter VBA では本質的に 以外で実装が出来ない

  57. For Next 回すしかない

  58. つらい

  59. 関数が第一級オブジェクトではないの あるのに慣れてるので結構辛い

  60. ※許せる……? 点 eval すれば使える DSL ではそういうこともある

  61. 4. エディタで1 行ごとに構文 チェックが走る

  62. ( 厳密には言語の特徴ではないが) エディタで1 行ごとに構文 チェックが走るのがひどい

  63. Visual Studio とかのIDE も改行したら行整形したりする が……

  64. 関数を書こう

  65. if 文を書こう

  66. FirstRowIndex という定数と比較したい 変数名補完が効かないし長いからコピーしてこよう

  67. カーソルを別の行へ

  68. !?

  69. 行ごとに文完結してないとエラーがダイアログで出る いちいちOK 押さないと別の編集ができない ついでにまともな修正候補は出ない

  70. とりあえず意味のない値で文完結させて別の行へ

  71. ……

  72. きっとこれを面倒がって短いA とかB とかの変数名が書かれ るんだろうと思うと……

  73. エディタで1 行ごとに構文チェックが 走ってしかもいちいちダイアログが出 る つらい

  74. ※許せる? 点 不十分すぎるが文法エラー出してくれるのは良い

  75. 5. ソースがxlsx バイナリの中 に保存される

  76. つまり自然にバージョン管理や差分比較することが出来な い

  77. ※許せる点 xlsx がメインでその付属スクリプトという性格からしょ うがない面がある 比較的許せる

  78. ソースがxlsx バイナリの中に保存され るのつらいけど許せる

  79. 6. 継承ができない

  80. 「VBA は一応オブジェクト 指向言語」

  81. クラスの継承が出来ない

  82. 運用で回避あるある クラスにアクセス制御がなかったりするLL 命名規則とかでなんとかする

  83. 回避できない VBA はアクセス制御があるのに継承がない 委譲しよう→関数が第一級ではないのでつらそう

  84. インターフェースは継承をすることは 可能 ' Class1 Implements Class2 Dim Obj1 As Class1

    Set Obj1 = new Class1 Call Obj1.class2method ' <- Dim Obj1 As Class1 Set Obj1 = new Class1 Dim Obj2 As Class2 Set Obj2 = Obj1 ' !? Call Obj2.class2method
  85. つらい

  86. 他OOP 系のつらみ コンストラクタに引数が渡 せない

  87. Set Obj = New MyClass(hoge) '

  88. Set Obj = New MyClass Obj.Setup(hoge)

  89. つらい

  90. 継承ができない コンストラクタに引数が渡 せない ごっつつらい

  91. ※許せる点 一応クラスは作れる

  92. 7. スタックトレースが存在 しない 呼び出し元しかわからない

  93. エラーにスタックトレースがつかない エラーが起こった処理の呼び出し元しかわからない

  94. 最高にヤバい

  95. 大抵の言語ではエラー時「スタックト レース」が出る

  96. None
  97. スタックトレースのない言語はシェルスクリプト等他に も存在する しかしそれらは最低限実際にエラーになったソース行が わかる。

  98. in VBA

  99. エラー発生!

  100. 情報1: エラー内容とエラーコード ( この時点では行がわからない)

  101. 情報2: 呼び出し元の行情報

  102. 以上

  103. エラー時に分かる情報 情報1: エラー内容とエラーコード ( 型が一致しません ( エラー 13)) くらいの超簡易な情報 情報2:

    呼び出し元の行情報
  104. エラー内容詳細を見たい ヘルプを押しても

  105. None
  106. 検索しても

  107. ググるしかない

  108. エラーのたびに…… 1. エラー内容とエラーコード 2. 呼び出し元の行情報 しか提供されないので エラー内容詳細 ググる エラーの起きた場所 呼び出し元からブレークポイントをふりつつ関数を1

    つずつ 自分でたどって行を絞り込んでいく
  109. 苦行

  110. スタックトレースが存在し ない 呼び出し元しかわからない

  111. ※許せない

  112. 7 つの大罪 1. 不完全な型システム 2. プリミティブ型とオブジェクト型で代入の方法が異なる 3. 関数が第一級オブジェクトではない 4. エディタで1

    行ごとに構文チェックが走る 5. ソースがxlsx バイナリの中に保存される 6. 継承ができない 7. スタックトレース不在 呼び出し元しかわからない
  113. 7 つの知見 1. 合理的な型システム 2. 代入や呼び出しの方法が一貫している 3. 第一級関数 4. 柔軟なIDE

    5. テキストでソースが保存できる 6. 継承ができる 7. スタックトレースがある 素晴らしい
  114. 当たり前に感謝

  115. 教訓

  116. 次はVBA 以外で やる