Hey, Scripting Guy!発言には注意しましょう

Microsoft Scripting Guy

アメリカ南北戦争中 (正確にはスポットシルバニアの戦いに際し) に、北軍のジョン・セジウィック将軍は、部下たちが南軍の狙撃兵たちによる不規則かつ無作為な発砲におじけづいているのを見て落胆していました。言い伝えによれば、セジウィックは部下たちにこう言いました。「そんな風に逃げ回るな。恥を知れ。南軍はこの距離では象でも撃てまい。」その直後に、セジウィックは戦死した最高位の北軍将校となりました。セジウィックにとっては不幸なことに、南軍の狙撃兵は象を撃つことはできなかったかもしれませんが、将軍を撃つことはできたのです。

もちろん、言うまでもなくこの話の教訓は明らかです。きっとこういうことだと思われるでしょう。「だれかが撃っているときには頭を下げろ」、良い教訓だと思われますか。残念ながら、私たちはそのように考えませんでした。代わりに、私たちは次の教訓を学びました。「発言には注意しましょう。いつの日か、それが跳ね返ってきて自分を撃つかもしれないからです。」ジョン・セジウィックにとってこの言葉は真実でした。そしてこれは他の大勢の人々にとっても同様に真実です。たとえば、長い間 IBM の社長であったトーマス・ワトソンを、アメリカの史上最も偉大な企業家の 1 人として覚えている人はいないでしょう。代わりに、「私が思うに、全世界には 5 台のコンピュータが売れるだけの市場があるだろう」という言葉を語った人としてワトソンは歴史に名を残しました。

興味深いことに、ワトソンがこの言葉を実際に語ったという証拠はありません。単にその事柄に関するだれか他の人の考えを述べたにすぎないのかもしれません。しかし気にする人はほとんどいないでしょう。結局のところ、IBM の社長がコンピュータにとっての市場などはないと語ったかもしれないという考えそのものが、ささいなことに思える事実を無視できないということをたいへんよく表しているのではないでしょうか。

ちなみに、ワトソンは「成功したいなら、普通の倍失敗しなさい。」とは語りました。このアドバイスに Scripting Guy は心から同感します。

まあ、少なくとも、普通の倍失敗するという部分に。

またこのような格言もあります。「VBScript でスクリプトを書いているライターは、.NET Framework ではスクリプトが書けない。」明らかに Microsoft® .NET Framework ではスクリプト ライターはスクリプトを書けないということは、「南軍はこの距離では象でも撃てまい。」または「私が思うに、全世界には 5 台のコンピュータが売れるだけの市場があるだろう。」という言葉ほど印象的ではありません。しかし、そのような発言は一様にまったく的外れです。.NET Framework は C# および Visual Basic® を使用する開発者を念頭に置いて設計されているのは事実です。また VBScript ではネイティブ .NET Framework クラスをインスタンス化できません。しかしこのことは .NET Framework ではすべてのライターがスクリプトを書けないということでは決してありません。

そうです。.NET Framework クラスの大部分が VBScript では使用できないままになっていることは否定できません。しかし、COM を呼び出すことができるラッパーが付いている .NET クラスはかなり多くあります。これが意味するところは単純で、COM インターフェイスを含むこれらのクラスを、VBScript のようなスクリプト言語で使用できるということです。信じられないと思いますか。図 1 に示されるレジストリの HKEY_CLASSES_ROOT の部分を見てください。System で始まるクラスはすべて見ることができるはずです。

図 1 レジストリのシステム クラス

図 1** レジストリのシステム クラス **(画像を拡大するには、ここをクリックします)

これらの大部分は .NET Framework クラスです。またこれらのほとんどが VBScript を介してインスタンス化できます。

言ったとおりでしょう。

もちろん、深夜番組で広告される商品を購入したことのある人ならだれでも証言できるように、何かができる**からといってそれをしなければならないということにはなりません (たいていそれらの商品には店でおおっぴらに購入できない何らかの理由があります)。確かに、スクリプト内で System.ContextMarshalException クラスのインスタンスを作成できますが、なぜそうするのか、それをどう使用するのかということはわたしたちにはわかりません。

しかしこれはすべての .NET Framework クラスに当てはまるわけではありません。たとえば、スクリプトの世界における最大の悩みの種は項目を分類する簡単な方法がないという事実です。リストをアルファベット順に置くには非接続のレコードセットを使用するか、または暗号のようなソート関数をすべて自分で作成する必要があります。次に示すようなバブル ソート コードです (胃が弱い方は飛ばして次の段落に進む方がよいかもしれません)。

For i = (UBound(arrNames) - 1) to 0 Step -1
    For j= 0 to i
        If UCase(arrNames(j)) > 
          UCase(arrNames(j+1)) Then
            strHolder = arrNames(j+1)
            arrNames(j+1) = arrNames(j)
            arrNames(j) = strHolder
        End If
    Next
Next

落ち込まないでください。コードを書きはしましたが、私たちもすべての意味が完全にわかっているわけではありません。

このような状況で .NET Framework をどのように利用できるでしょうか。その質問に答えるために、非常に単純でわかりやすい短いスクリプトを見てみましょう。

Set DataList = CreateObject _
      ("System.Collections.ArrayList")

DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()

For Each strItem in DataList
    Wscript.Echo strItem
Next

ご覧のように、ここでは NET Framework クラスの System.Collections.ArrayList のインスタンスを作成しています。次に、Add メソッドを使用してリストに 5 つの項目を追加します。すべてうまくいっていますが、1 つだけ問題があります。これらの項目はいわゆる無作為な形式 (B、C、E、D、A) で追加しましたが、アルファベット順 (A、B、C、D、E) で表示する必要があります。バブル ソート コードを使うときがきましたね。

いいえ、違います (たいへん無愛想で申し訳ありませんが、間違いは間違いです)。バブル ソート コードを持ち出す必要はありません。配列リストの Sort メソッドを呼び出すだけでよいのです。

DataList.Sort()

これだけです。そのコード 1 行だけで、配列リストのすべての項目を並べ替えることができます。

証明しましょうか。手厳しい方々ですね。いいでしょう。皆さんが疑い深いことは予期していました。なぜスクリプトが、リスト内のすべての項目をループする For Each ループを含み、画面上にそれぞれの値をエコーするのか、これがその理由です。

For Each strItem in DataList
    Wscript.Echo strItem
Next

さて、皆さんが取り組むことができる質問をご紹介します。このスクリプトを実行すると、どのような結果を得ることができますか。

良い読みです。

A
B
C
D
E

すばらしいでしょう。

うーん、完全には満足していない方もおられるようですね。確かにこれでうまくいっていますが、本当に表示したいことは、それらの値をエコー バックして降順に並べ替えることでした。つまり A から Z へのリストではなく Z から A へのリストを表示したかったわけです。そうなっていないならどうすればよいでしょうか。。。

問題はありません。お答えしましょう。

Set DataList = CreateObject _
      ("System.Collections.ArrayList")

DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()
DataList.Reverse()

For Each strItem in DataList
    Wscript.Echo strItem
Next

そのとおりです。非常に長いスクリプトになりましたね。しかし、ここで重要な追加があります。追加した 1 行のコードをご覧ください。それは Sort メソッドの直後の 1 行です。

DataList.Reverse()

わかりましたか。リストを昇順に並べ替えた後に、驚くべきことに配列内の各項目をすべて逆の順番にする Reverse メソッドを呼び出しました。これにより何が得られるでしょうか。次のような出力が得られます。

E
D
C
B
A

感動せずにはいられないでしょう。

でもちょっと待ってください。ここからこれまでより、さらに良くなるのです。VBScript 配列から項目の削除を試みたことはありますか。もしなくても泣かないでください。これからあなたにそうしていただくわけではありません。代わりに、.NET Framework 配列リストから項目を削除することがどのくらい簡単なのかをお伝えします。D の文字は好きではないですよね。削除しましょう。これが配列リストを作成し、並べ替えて、D のエントリを削除するスクリプトです。

Set DataList = CreateObject _
  ("System.Collections.ArrayList")

DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()
DataList.Remove("D")

For Each strItem in DataList
    Wscript.Echo strItem
Next

もう一度 Sort メソッドの直後の短いコード行を見てください。

DataList.Remove("D")

ここでは、Remove メソッドを使用して D に等しい項目を削除しています。次にスクリプトを実行した結果を示します。

A
B
C
E

さようなら D。

そしてこの一番良い部分を見逃さないでください。配列のサイズ変更や再ディメンションを行うことなく項目を削除できるのです。かっこいいでしょ。もちろん、私たちもサイズ変更や再ディメンションなどを行わずに配列に項目を追加できました。スクリプト作成がより簡単になったと思われませんか。

信じられないかもしれませんが、これでもまだ .NET Framework 配列リストを使用して行うことのできるほんの少しの部分を取り上げたとさえ言えないのです (詳細については .NET Framework SDK 配列リスト (英語) を参照してください)。

この配列リストはスクリプト ライターにとって有益でしょうか。こう考えてみましょう。.NET Framework 配列リストを見た今となっては、少なくともここで使用したような単純な項目には、もはや組み込まれている VBScript 配列を使用したいとは思われないことでしょう。

正直なところ、私たち Scripting Guy はスクリプト ライターが使用できるのはどのクラスか (および使用できないのはどのクラスか) ということに関してまだ .NET Framework を徹底的に調査してはいません。これについては現在取り組んでいるところです。とりあえず、.NET Framework SDK (英語) を自由に参照してください。この SDK ページを参照すると、ほとんどの場合、スクリプト ライターが使用できる新しくて興味深い事柄を発見できます。

たとえばどんなことがあるでしょうか。乱数を生成する方法についてはどうでしょうか。VBScript 乱数生成スクリプトを使用して 1 から 100 の乱数を生成したいですか。問題ありません。これとよく似たコードを使用するだけです。

Randomize
Wscript.Echo Int((100 - 1 + 1) * Rnd + 1)

数式を覚えましたか。覚えていなくても心配する必要はありません。.NET Framework System.Random クラスを使用する方がより簡単でより直感的であることがわかっていただけるでしょう。

Set objRandom = CreateObject("System.Random")
Wscript.Echo objRandom.Next_2(1,100)

おそらく説明なしでこれは理解できるでしょう。いずれにせよ、短いスクリプトを紹介します。なぜなら TechNet Magazine ではコラムニストは毎月何かしらのスクリプトを書かなければならないからです (なぜですかと突っ込まないでください。私たちではなく TechNet Magazine のポリシーだからです)。

ご覧のとおり、System.Random クラスのインスタンスを作成し、次に Next_2 メソッドを呼び出し、2 つのパラメータにメソッドを渡します。

  • 1、今回の範囲内の最初の数 (1 から 100 までの間で乱数を生成するということを思い出してください)。
  • 100、今回の範囲内の最大数。

これで作業は完了です。

最後にもう 1 つだけ質問に答える時間がありそうです。緑色のシャツの人、どうぞ。スクリプト ライターは .NET Framework でスクリプトが書けないと言った人は本当にいるのですか。さて、正直なところ、まず、おーっと、時間がなくなったようです。来月またお会いしましょう。

良い時、良い時

間もなく 2 月です。それが意味することは 1 つだけです。バレンタインデーではありません。大統領の誕生日でもありません。え、グラウンドホッグ・デーですか。いいえ、2 月が近づくにつれ世界で最も重要な (といってもこの世界だけでの話ですが) 国際スクリプト競技会 2007 Winter Scripting Games も近づくのです。今年の競技会はこれまでで最も大きく最も良いものになると断言できます。今回は 4 つの部門があります。

  • VBScript 初心者
  • VBScript 上級者
  • Windows PowerShell™ 初心者
  • Windows PowerShell™ 上級者

詳細については 2007 Winter Scripting Games のホーム ページ (英語) を参照してください。

はい、何でしょう。そうそう、ありがとうございました。そして、そうそう、グラウンドホッグ・デーおめでとう。

Windows PowerShell を今すぐダウンロードしてください

Windows PowerShell 1.0 はダウンロード可能になりました。そして無料です。この機会を逃さないでください。ソフトウェアのダウンロード (英語) からダウンロードしてご使用ください。

Microsoft Scripting Guyマイクロソフトの仕事をしています、というよりもマイクロソフトにより雇われています。野球をプレイしたり監督したり観戦したり (または他のさまざまな活動を) しているのでない限り、彼らは TechNet Script Center を運営しています。詳細については、http://www.microsoft.com/japan/technet/scriptcenter/default.mspx を参照してください。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.