Slide 1

Slide 1 text

VBA ナメてた @narazaka

Slide 2

Slide 2 text

奈良阪 自己紹介 Twitter: Github: npm: CPAN: RubyGems: ドリコム2015 新卒入社 サーバーサイドRuby 好きな言語: Perl / CoffeeScript / Ruby / C# / Ceylon? その他: 伺か/ 漫画読み描き/OP アニメ愛好家/ 鉄 @narazaka @Narazaka @narazaka NARAZAKA Narazaka

Slide 3

Slide 3 text

VBA (Visual Basic for Applications) 1994 年のExcel5.0 から付属したマクロ用言語 Excel が有名だがWord やPowerPoint 等でも使える

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

VBA ナメてました

Slide 7

Slide 7 text

「Excel マクロつらい」

Slide 8

Slide 8 text

謎のセル指定

Slide 9

Slide 9 text

なるほど…… ?

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

……

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

でもそういう問題ではなかった

Slide 16

Slide 16 text

VBA || 20 世紀のMS 製品

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

生産性が惨殺される体感

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

7 連発

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

1. 不完全な型システム

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

型情報最高!!

Slide 27

Slide 27 text

にもかかわらず

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

?

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

プリミティブ型とオブジェクト型 C++ やJava と同じ感じ プリミティブ型: Integer, Boolean 等 オブジェクト型: Range, ユーザ定義等

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

?

Slide 40

Slide 40 text

プリミティブ型は Value = 1

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

似たようなつらみ 関数とサブルーチン 返値あり -> 関数 (Function) 返値なし -> サブルーチン (Sub) の別もある(Fortran にもある)

Slide 46

Slide 46 text

呼び出し書式が違う

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

つらい

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

3. 関数が第一級オブジェク トではない

Slide 54

Slide 54 text

自分がこれまで使った言語 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 スクリプト

Slide 55

Slide 55 text

VBA 、バッチファイル、シェルスクリプトのみ 関数が第一級オブジェクトとして扱えない

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

For Next 回すしかない

Slide 58

Slide 58 text

つらい

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

関数を書こう

Slide 65

Slide 65 text

if 文を書こう

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

カーソルを別の行へ

Slide 68

Slide 68 text

!?

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

……

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

6. 継承ができない

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

クラスの継承が出来ない

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

インターフェースは継承をすることは 可能 ' 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

Slide 85

Slide 85 text

つらい

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

Set Obj = New MyClass(hoge) '

Slide 88

Slide 88 text

Set Obj = New MyClass Obj.Setup(hoge)

Slide 89

Slide 89 text

つらい

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

最高にヤバい

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

in VBA

Slide 99

Slide 99 text

エラー発生!

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

以上

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

エラー内容詳細を見たい ヘルプを押しても

Slide 105

Slide 105 text

No content

Slide 106

Slide 106 text

検索しても

Slide 107

Slide 107 text

ググるしかない

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

苦行

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

※許せない

Slide 112

Slide 112 text

7 つの大罪 1. 不完全な型システム 2. プリミティブ型とオブジェクト型で代入の方法が異なる 3. 関数が第一級オブジェクトではない 4. エディタで1 行ごとに構文チェックが走る 5. ソースがxlsx バイナリの中に保存される 6. 継承ができない 7. スタックトレース不在 呼び出し元しかわからない

Slide 113

Slide 113 text

7 つの知見 1. 合理的な型システム 2. 代入や呼び出しの方法が一貫している 3. 第一級関数 4. 柔軟なIDE 5. テキストでソースが保存できる 6. 継承ができる 7. スタックトレースがある 素晴らしい

Slide 114

Slide 114 text

当たり前に感謝

Slide 115

Slide 115 text

教訓

Slide 116

Slide 116 text

次はVBA 以外で やる