2010年1月23日
いざ、方針が決まったらプログラムを書き始める。
とりあえず、有効数字2桁が問題なくできれば3桁は桁数を1つ増やすだけなので、
簡単にできそうだと判断して、2桁のプログラムからスタート。
名前は何でもいいのだが、「significantFigure2」にしてみた。
significant figureは有効数字という意味。2桁なので「2」。
まぁ、そういう単純な発想です。
Sub significantFigure2() '変数の定義 Dim myRange As Range Dim myCellValue As String '式として変換する為の変数 Set myRange = Application.Selection For Each c In myRange.Cells '個々のセルを抽出 myCellValue = c.Value c.Value = "=ROUND(" & myCellValue & ",1-INT(LOG10(" & myCellValue & ")))" Next End Sub |
「=」などの演算子の前後のスペースや、大文字小文字の区別については、自分で定義するもの以外は、
入力補助で勝手にやってくれる。有難い。
Subはサブルーチンであることの宣言。 ここから、End Subまでがサブルーチンになる。
マクロの実行は、開発タブのマクロのボタンを押して「significantFigure2」を選んで「実行」。
そこで呼び出すときの名前を定義している。
さらにその後ろの()は、このサブルーチンに引数を渡すときに使うのだが、
今は引数がないので空白のまま。
空白なら書かなければいいじゃないか、と言われそうだが、そういうお約束なので、とりあえず書いておく
(書かなかった場合は入力補助で勝手に追加される)。
その下、「'」に関してだが、同一行で「'」
より後ろの部分はコメントとして扱われる。
つまり、実際に実行するときは完全に無視される領域になる。
無視されるんだから書かなくてもいいのだが、後々、自分で見たときに分かり易くするために色々と書く人が多い。
まぁ、そういうもの。
で、Dimからが本編。
VBAではDimを使って変数を予め宣言する必要がある。つまり、「私はこういう名前の変数を使うんだ!」と
最初に書く必要がある、という事。
ちょっと話はそれるが、私が触れてきたプログラミング言語はBASICとperlだ。
この2つは基本的には(あくまでも「基本的には」。perlではした方がいいとされている)変数の宣言は要らない。
ある所でいきなり変数を使っても良かったのだ。
しかし、Appleが無償の開発環境を提供してくれたので、Objective-Cなる言語に触ったのだが、それでは変数の宣言が必要だった。
しかも、変数の型(後述)も宣言しなくてはいけない・・・。これは私にとってかなり苦痛。
色々と大事な事だというのは分かっているが、いまだにこれは慣れない。
閑話休題。
Dimで宣言しているのは、myRangeとmyCellValue。
まぁ名前なんてなんでもいいのだが、極端に適当な名前を付けると、あとから分からなくなるので
何となく分かる名前を付けるのが一般的かと。
名前の後ろにAsがあり、その後に来るのが変数の型。つまり、この変数には何が入るのかって事。
Rangeは実際には型ではなくてオブジェクトと呼ばれるものになるので、Office2007では無くても動くっぽい。
で、myCellValueのStringというのが文字列という意味。
何を入れるかは後々決めるとして、とりあえずmyCellValueには文字列が入るという事を宣言しておく。
使いそうな変数の宣言が終わったら実際の処理に手をつける(実際に書くときは、随時変数の宣言を書き足していく。
変数が登場する直前に宣言してもいいのだが、後で探すのが面倒になるので、最初にまとめて宣言してしまう)。
想定しているのは、セルを選択してマクロを動かすという物なので、起動する時にはExcelで選択しているセルの場所を
マクロ側が受け取る必要がある。それが、
Set myRange = Application.Selection
myRangeがオブジェクトなので、Setをつける必要があるのだが、致し方ない。
Application(今はExcel)でSelection(つまり、選択)しているものをmyRangeに代入しなさい、という意味。
よくある事なのだが、「=」は数学のイコールではなく、右辺のものを左辺に代入するという意味。だから、
a = a + 1
なんていうのもよく見かける。これはaという変数に1を加えなさいという命令。
慣れてくると、あぁ、そんなもんかと思えるようになるかと。
For Each c In myRange.Cells 〜 Next
ForとNextがセットになっているのはBASICあたりを触った事のある方ならお馴染みかと。
今回の場合はFor Eachだが、まぁ同じ事。ForとNextはセットになっている。
意味としてはほぼ英語そのままなのだが、
「myRange内のCellをcとして、それぞれのcについてNextまでの処理を繰り返しなさい」
という事。
1つのセルが選択されて、cに代入されて、Nextまでの処理が実行されてから、再びFor Eachまで戻り、
別のセルが選択されて・・・・という処理が、全てのセルで行われるまで繰り返される。
どの順番で選択されるのかはあまり気にしなくて良さそうだが、どうやら左上から右下の方向のようだ。
myRangeは選択された物でしかないので、数字なのか何なのか分からないのでCellを明示してあげる必要がある。
それだけではFor 〜 Nextの間で使いにくいのでcとしましょう、という感じ。
ちなみに、For EachとNextの間の記述には、行の最初にタブを入れいているが、
これはどこからどこまでがFor〜Nextの間かを分かり易くするためのもの。
他にももう1つ役割があるのだが、それは後で分かる。
myCellValue = c.Value
というのは、上でも出てきた代入式。別に必要ないと言えば必要ないのだが、色々な事情で付けている。
c.Formulaというのは、cは上で書いたようにmyRange内のセルの事、それのValue(値)という事。
つまり、セルに入力されている値をmyCellValueに代入しろという事です。
変数の名前がそのままズバリだというのが分かりますでしょ?
で、最後に
c.Value = "=ROUND(" & myCellValue & ",1-INT(LOG10(" & myCellValue & ")))"
として、そのセルの値として「=ROUND(・・・・)」というのを入力してあげるというもの。
「"」で囲まれた部分はそのまま入力される。
「&」は文字列を連結する記号、
myCellValueのように「"」
で囲まれていない変数は変数の中身が入力される。
とまぁ、ここまでで、どうにか有効数字2桁にするスクリプトが完成したわけだ。
たったこれだけのスクリプトでも、これだけ色んな事を考えている(?)のだ。
しかし、闘いはまだ終わらない。
すべての仕様を満たしているかの確認が終わっていないからだ。
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14]