20170402

VBA (Excel)で、連番を出す

python → VBA

pythonは知っている。Cは、途中で投げた。
そういう経緯の自分が、VBA(Excel)に手を出す。

pythonと同じように使えるようになりたい。
あわよくば、Excelとかwordとかでアニメーションしたい。

Excelの「開発」タブから、VBAができる。

ExcelでVBAが使用できるようにするためには、「開発」タブが必要です。
「開発」タブは、デフォルトで非表示です。
表示するためには、先日の分を参照してください。

「for」構文→「For」構文と、連番

  • pythonを使ったfor繰り返し構文
for i in range(10):
print i

>>> for i in range(10):
… print i

0
1
2
3
4
5
6
7
8
9

forを使えば、繰り返すたびに、インデックス用の変数が変わっていくので、それを参照する分をfor文の中で使えば、ちょっとずつ処理を変えていく事ができる。

上のpythonの例では、print関数の引数に、インデックス用の変数を入れているので、繰り返すたびに、標準出力に表示される内容が変わる。

これをVBAのイミディエイトウィンドウでやる。
繰り返し構文は、何らかのソフトのAPIで画像エクスポート機能があった場合に、連番画像を排出する目的で使う。

  • VBAでFor構文
    Sub test()
    Dim i
    For i = 0 To 9
    Debug. Print i
    Next
    End Sub

0
1
2
3
4
5
6
7
8
9

で、できた。

0 fill(0埋め)のため、formatを使う

Sub test()
Dim i
For i = 0 To 10
a = Format(i, "0000")
Debug.Print a
Next
End Sub

0000
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010

引数を3倍する関数を作った。

pythonでやると、こうなった。

def Abcd(a):
b = a*3
return b

Abcd(10)

>>> def Abcd(a):
… b = a*3
… return b

>>> Abcd(10)
30
>>>

VBだとこう。

Public Function Abcd(ByVal a As Integer) As Integer
Dim b
b = 3 * a
Abcd = b
End Function

Sub test()
Dim a
a = Abcd(10)
Debug.Print a
End Sub

30

やればやるほど、「pythonすげぇ…」なる。
VBAのまだるっこしさときたら…

戻り値のある関数を作る時には、Returnを使うな

VBAで、関数を作る時、戻り値の指定にReturnは使えない。
「構文エラー」になるから。

戻り値の指定をしたければ

関数名 = 戻り値

とする事が、Returnの代わりになる。
VBでは、Returnが使えるが、VBAではReturnが使えない。

VBとVBAは、文法が似ているだけで、違うものなんだと学習できた。
あと、SubもPublic Functionも、プロシージャと呼ばれる何かなのだと知った。

posted by yuchan at 07:00 | Comment(0) | VBA

20170330

VBAに手を出す

pythonが使えない環境

使用していたソフトが、どうもVisual Basicというのが使えるようだ。
VBAにも対応している。
今まで、頻繁に見てきた単語なので、この際だから、片手間に勉強しようと思う。

VB, VBA(本当は、pythonを使いたいが)

個人で好き勝手にできる環境じゃない事が結構ある。
しかし、PC(汎用計算機)なんだから、コマンドライン風の計算が、やって出来ない訳ではない。
入力の手間が省ける云々よりも、CLI的な感じで計算がしたい。

どんなソフトであろうとも、連番画像を排出して、アニメを作りたい。

どんな環境であろうとも、Windowsなら、MicrosoftのOfficeは、大抵入っている。
officeが入っていれば、VBAができる。(はず。)
だから、VBAができると、プログラミング的な作業ができると思った。

関数にキャメルケースが多い。
スネークケースは、見あたらない

ExcelでVBAを試すには

ファイルタブ>オプション>リボンのユーザー設定>「メインタブ」の一覧で、「開発」のチェックボックスを入れる。

すると、開発タブが現れる。
ここでコードを書いたり、実行したりする。
こんなのが隠れていたとは、知らんかった。

Visual Basicと書いてあるボタンを押せば、Editorが起動。

挿入>標準モジュールとでも入れると、空のファイルなのか何なのかが出てくる。

20170329-00.png

ここにプログラムを描いて、上の「緑の三角ボタン」か、「F5キー」でコンパイル。
即座に実行されてしまう。

標準出力的な部分は無いの?
pythonのコマンドライン的なあれが無いと、不安でしょうがない。
(そういう人のために、イミディエイトウィンドウ(後述)がある。)

色々いじっていたせいで、変なエラー(「プロシージャの外では無効です」 )が出たけど、そういう場合は、bookごと消して新規作成して解決した。

とりあえず、ここを参考に やった。
計算はここ
変数は、宣言してから使うようです。

何をするにも、Subだのなんだのと括る必要がある。

何もしないマクロを描きます。
ちなみに、 ’ (シングルクォーテーション)はコメントアウトとして機能します。

Sub test()
' abcd
End Sub

変数に入れた数字やら、文字列やらをメッセージボックスに表示する。

メッセージボックスに文字列を表示させるには、

Sub test()
Msgbox("aaaa")
End Sub

20170329-01.png

20170329-05.png

変数を引数にとる事も出来て、

Sub test()
dim a
dim b

a = 30
b = "mojiretsu"

Msgbox(a)
Msgbox(b)
End Sub

pythonから入ったので、信じられんのだが、全部関数で分断されている事に衝撃を受けている。
SubとかEndとか必要あるの?
段落分けいらないよ!

C言語だと、printすら、includeしないと使えない。
VBAは、まだ良心的な方なのか…

とはいえ、pythonやっていたおかげで、何とかついていけそう。
記憶機能がついているから、それほど、使い勝手も悪くはなさそう。

あくまでも、excelのファイルの一部として、マクロがあるよう。
Excelのブックを保存すると、一緒にマクロも保存される。
ただし、保存時に、xlsxのままだと、マクロは保存されない。xlsmにする必要がある。

拡張子(*.*)説明
*.xlsx通常のexcel book
*.xlsmマクロ入りexcel book

たまーに出てきてた、よく分からんダイアログの意味が、少し分かった

20170329-03.png

debug.Printは、イミディエイトウィンドウに表示する。

Msgboxを使ったけど、ちゃんとPrint関数もある(Pは大文字だった!いちいち大文字書かせる。)。
イミディエイトは、「ただちに」とか、そんな感じの英語の形容詞だった気がする。

Sub test()
dim a
a= "aaaaa"
debug.Print a
End Sub

20170329-05.png

文字列の連結

「文字列の連結には、+よりも&の方が便利ですよ」との御触れがありますな。

Sub test()
Dim a
Dim b

a = "aaaaa "
b = "bbbbb"

Debug.Print a & b
End Sub

衝撃!\nじゃない改行

「文字列に、\nを入れたら、改行」というのが先入観だったと気付かされた。

Sub test()
Dim a
Dim b

a = "aaaaa "
b = "bbbbb"

Debug.Print a & vbCrLf & b
End Sub

結果は、改行されて表示されるという…

VBAのシンタックスハイライトにも、Markdown hereが対応している。

今まで、Markdown hereを使って、シンタックスハイライトをしてきたけど、マークダウンでpythonコードを書くときは、下のような感じで書いてきた。

```py
print a
```

VBAの場合は、
```vb
Msgbox(“Hello World!”)
```
といった具合に出せた。

dim hensu as 型

pythonでは意識した事が無い型

自分が使い分けているのは、

  • string (文字列 例:”abc”, “%05.f”%1 など。文字を表示したりするとき要る。諸般の事情(連番!)で、ここに、数値を代入することもある。)
  • int (整数 例:1,3,100, 100001など。「小数点が付いてない数字で、計算に支障がある。」程度の認識。)
  • float (浮動小数点 例:…「小数点付きの数字」程度の認識。)

正直なtころ、intと、それ以外の数字しか分かっていない。
あとは、doubleだのなんだのがあるらしいが、floatとの違いは、よっぽどのことがあったら、本、ネットを読みながら考える。

桁落ちメモリ量とか考えたくないなら、計算するときは、なるべく長いbitのfloatを選べばいいと思っている。

…今回も、ここの表にあるようなことは無視。覚えきれない。

配列型

一つの変数に、たくさんのデータムを入れてプロットしたりしたい。
一連のデータを、まとめて処理したい時に配列を使いたい。
dim A(8)と宣言したら、a(0)~a(8)までの9個設定できる。

Sub testArray()
dim A(8)
A(1)=2
A(2)=3
Msgbox(A(1))
End Sub

VBAで、ToStringは使えない。

文字列の所に、数値を代入したいシーンが絶対出てくる。
連番画像は、0埋め(zero fill)すべきでしょう!

数字→文字列だけではダメ。
文字列の、型というか、フォーマットというか、書式を設定できないとだめ。
もっと具体的に言うと、0埋め100を、6桁表示なら、000100とか。

CStrではフォーマット表示できない(と思う)。

だから、そっち系の方法を探っていたら、ToStringを使うのが確実なやり方か?と思ったが、このやり方は、VB.netっていうのでしかできない。「オブジェクトが必要です」とか、エラーが出る。

Format関数っていうのがあるらしい。

Sub Zerofil()
Dim a
Dim b

a = 10
b = Format(a, "000")

Debug.Print b

End Sub

今後の課題

まだ、Excel独自の機能を使っていない。
Excelのブックを操作する方法も分かっていない。
後は、

  • forループ
  • 連番排出方法 pythonでいうrange関数
    辺りが分かれば、十分。
posted by yuchan at 07:00 | Comment(324) | VBA