VBAのCallByName

MOSの試験対策を考えていると、MOSの試験問題の傾向だけではなく、採点基準もどのようになっているのか知りたくなります。

MOSの試験の採点はコンピュータによる自動採点で、人間の採点とは違い、こう考えたからこうなるのだろうなという予想をして、ちょっとした違いを吸収して採点しているというわけではなく、完全に正確に答えになっているかを審査されていると思います。

WordやExcelの機能には自動で採点できるものとそうではないものがあるので、自動で採点できないものは出題されないような気もします。

また、自動採点は1問1問ごとに別々の採点のアルゴリズムで採点しているようになっているのかも知れませんが、コンピュータである以上、一定のアルゴリズムで採点していると予測されます。

そのために、セルの内容でも、セルの背景色でも、シート名でも、シートの見出しの色でもひとつの法則でチェックできるといった仕組みがなされているのではないかなと思いました。

そこでVBAでそのようなバラバラのチェックポイントを同じアルゴリズムでチェックできる方法を調べていたところCallByNameというものを見つけました。

プロパティをチェックするときの課題

普通、今のブックの1枚目のシートのセルA1の入力値を調べる時はThisWorkBook.Sheets(1).Range(“A1”).Valueです。

もしも違うセルの入力値を調べたい場合は”A1″を引数にしてセルの位置を指定するようなFunctionを作成すれば良いのです。

Function セルチェック(ByVal セル位置 As String)
  セルチェック=ThisWorkBook.Sheets(1).Range(セル位置).Value
End Function

しかし、この方法だと、セルの値しかチェックできません。セル幅をチェックするためには上のFunctionの他に以下のようなFunctionを用意する必要があります。

Function セル幅(ByVal セル位置 As String)
  セル幅=ThisWorkBook.Sheets(1).Range(セル位置).ColumnWidth
End Function

これでは、チェックする種類すべてでFunctionを設定しなければなりません。

そこで、CallByNameが使えないかと考えました。

CallByNameの動き

今回求めていることを実現するCallByNameは以下のような書式です。

CallByName(チェックするオブジェクト名,プロパティ名,VbGet)

これをFunctionに落とし込むと、次のようになります。

Function チェック(ByVal ブック As String, _
  ByVal シート As String, _
  ByVal セル位置 As String, _
  ByVal プロパティ As String)
  チェック=CallByName( _
    Workbooks(ブック).WorkSheets(シート).Range(セル位置),プロパティ名,VbGet)
End Function

それをメインプロシージャで呼び出して正解の値と比較すれば正解かどうかがわかります。

売上ブックのコメントシートのセルA1の計算の結果が「2021年」かどうか調べるためには次のようにすればよいです。

Sub 採点
  成否=(チェック("売上","今年度","A1","Value")="2021年")
End Sub

セルの値とセルの背景色

この方法であればうまくいくと思ったのですが、CallByNameの第一引数では、オブジェクトを指定することになります。

セルの値や列の幅であれば、セルがオブジェクトです。

しかし、セルの背景色やフォントの書式だと、セルのオブジェクトの下にInteriorやFontといったプロパティが指定されるので、CallByNameで背景色をチェックする場合、以下のようになります。

CallByName(ThisWorkBook.WorkSheets(1).Range(セル位置).Interior,"BgColor",VbGet)

第一引数にInteriorが指定されてしまうので同じVBAの文では文字の色であるFontを指定できません。

CallByNameは読み出すだけではない

ここからは実際にはうまくいっていないのですがおそらくこんなやり方があるのではないかという予想です。

上記の例ではプロパティの値を読み出すということを紹介してきましたが、CallByNameでは、プロパティを設定したり、 コピーやクリアなどの動作をメソッドとして実行したりすることができます。VbGetでは値を読み込むという意味なのですが、VbLetにすればプロパティを設定するという意味になり、VbMethodにすればメソッドを実行するという意味になります。 VbLetの場合は第4引数以降に設定値を指定することができます。

その中にもう一つ、オブジェクトを指定するという意味のVbSetがあります。ただその使用例が少なく、どう使ったらいいのかわからないところで止まっています。

VbSetでオブジェクトを一旦作成し、それを使ってオブジェクトを指定してCallByNameすればうまくいくのではないかなと思っています。その仕組みをVBAではない方法でMOSの採点プログラムでは採用しているのではないかなと思っています。

まとめ

実際にはMOSの採点プログラムは公開されているものではないので実際に一文ごとに採点するアルゴリズムが設定されているのかもしれませんし、私の予想通り一つのアルゴリズムで判定しているのかもしれません。

一つ言えることはVBAで何ができるかがわかることで、MOSの採点基準を理解することができ、どんな答え方をしたら一番安全なのかということが予測できるということです。

それはMOSの攻略法でも裏技でもなく、パソコンとは本来こういうふうに動くものという理解をすることで、それを本当に理解している人はWordでもExcelでも手足のように使えるようになると思っています。

VBAの理解がMOS試験の点数に繋がるというは、実は逆のことも言えて、MOSをきちんと理解すればパソコンがどういうものか分かるようになってVBAで何かを作るときでも元々作れないものを作ろうと思ったりExcelの基本機能でできるものをわざわざVBAで作成したりするといった事が少なくなるとも思っています。

コメント

タイトルとURLをコピーしました