FrontPage 新規 編集 検索 一覧 ヘルプ

VBS

VBS(Visual Basic Script)メモの目次

VBSとは?

Visual Basic Scriptは、MicrosoftのVisual Basicシリーズの1つで、HTML(IE)、ASP、WSHなど色々な環境で動作するスクリプト処理を可能にしています。VBやVBAなどと基本的な構文が同じですので、VBやVBAを使っている人には簡単に理解することができます。WinのIE5.0以上がインストールされていれば、VBS5.0以上のバージョンがすでに組み込まれているはずですので、インストールの必要はありません。最新版を使用したいときは、Windows Scriptからダウンロードしてセットアップしましょう。

自分の使ってるVBScriptのバージョンは?

拡張子.vbs の適当なファイルを作成して、以下をコピーしてダブルクリックしてください。

 Option Explicit
 ' getver.vbs - VBScriptのバージョン取得
 
 MsgBox ScriptEngineMajorVersion & "." & ScriptEngineMinorVersion

各環境での記述方法など

上の例では、直接 VBS ファイルにアクセスしていますが、HTMLやASPファイルでの記述方法も書いておきます。

HTMLファイル(IEで表示の場合)

<SCRIPT>タグ内に記述します。

 <HTML>
 <HEAD>
 <TITLE>VBScriptのバージョン表示</TITLE>
 <HEAD>
 <BODY>
 スクリプトのバージョンは、
 <SCRIPT language="VBScript">
 document.write ScriptEngineMajorVersion & "." & ScriptEngineMinorVersion
 </SCRIPT>
 です。
 </BODY>
 </HTML>

ASP(PWS/IISサーバ経由)

<% ... %> で挟まれた部分がサーバーサイドスクリプトとして認識実行されます。<%= ... %> とイコールを付けるとその値をその場所に代入します。アクセスはPWS/IIS経由ですので単純にダブルクリックしてもだめです。http://localhost/.../.../getver.asp のようにアクセスします。

 <%@ LANGUAGE="VBScript" %>
 <HTML>
 <HEAD>
 <TITLE>VBScriptのバージョン表示</TITLE>
 </HEAD>
 <BODY>
 スクリプトのバージョンは、
 <%= ScriptEngineMajorVersion & "." & ScriptEngineMinorVersion %>
 です。
 </BODY>
 </HTML>
 </HEAD>

データベースへの接続

一番手軽なのは、UDLを使う方法だ。UDLについては別のページに記載します。

 Option Explicit
 ' 簡単なADODB接続&レコードセット取得
 Dim objRec
 Set objRec = CreateObject("ADODB.RecordSet")
 objRec.Open "SELECT * FROM 仕入先", "File Name=Sample.udl"
 
 '... 処理 ...
 
 objRec.Close
 Set objRec = Nothing

というようにレコードセットを取得しデータベース処理を行います。上記は Sample.udl で指定されたデータベースから仕入先テーブルのすべてをレコードセットとして取得します。

タイプライブラリについて

忘れてた。タイプライブラリのこと書かないと、上のプログラム生VBSで実行してもエラーになっちゃうですます。はい。

adOpenStatic, adLockReadOnly, adCmdTableDirect とかっていうのはADO用の定数で、ADOのタイプライブラリを読み込むと使えるようになるです。adovbs.inc というのをHDD内から検索してみてください。そしてテキストなので開いてみましょう。非常に沢山の定数が定義されてますねぇ・・・。

生VBS(.vbs)では、インクルードできないので、必要な定数定義をプログラム内にコピーするか、定数を数字で直接書きます。もしくは、.wsf ファイルにしてタイプライブラリを参照します。

 <job id="IncludeTest">
    <reference object="ADODB.Recordset" />
    <script language="VBScript">
 
        ここにVBScriptを記述します。
 
    </script>
 </job>

上記例では、ADOタイプライブラリを参照します。

またASPの場合は、METADATAでTypelibの宣言を行います。タイプライブラリは共通で利用するものなので通常global.asaで宣言しますが、.asp内で個別に宣言しても利用できます。

ライブラリID

 <!-- METADATA TYPE="TypeLib" UUID="00000205-0000-0010-8000-00AA006D2EA4"-->

か、ファイル名

 <!-- METADATA TYPE="TypeLib" FILE="C:\Program Files\Common Files\System\ado\msado15.dll"-->

や、

 <!-- METADATA TYPE="TypeLib" FILE="C:\Program Files\Common Files\System\ado\msado25.tlb"-->

などと指定します。上記は全てADO2.5タイプライブラリを利用します。

エラー処理と解除

通常VBSで実行時エラーが発生すると、エラーダイアログが表示されプログラムの実行が中断されますが、

 On Error Resume Next

を指定すると、以降エラーが出ても止まらずに処理を続けます。この時、Errオブジェクトには、適切なエラー値がセットされますので、それを参照、取得するようにします。例えば、このようにします。

 If Err Then
     MsgBox  Err.Description, vbCritical, "エラーNo." & Err
     WScript.Quit
 End If

ところで、このOn Error Resume Nextを一度設定してしまうと、以降実行時エラーが発生しても中断せずに処理を行ってしまいます。これを解除するには、

 On Error Goto 0

と指定します。下記サンプルは、エラー(ゼロで除算)を2回しています。1度目のエラー処理で独自にエラーの説明ダイアログを出しています。2度目はエラー処理をしないで、実行時エラーのダイアログが表示されます。

 Option Explicit
 ' error.vbs - エラー処理
 On Error Resume Next
 
 Dim Kotae, Shiki
 
 Shiki = "5 / 0"
 Kotae = Eval(Shiki)
 
 If Err Then
     MsgBox  Err.Description, vbCritical, "エラーNo." & Err
     ' WScript.Quit
 Else
     MsgBox Shiki & " = " & Kotae & " です",, "計算結果"
 End If
 
 On Error Goto 0
 Kotae = Eval(Shiki)    ' 実行時エラー

おすすめのエディタ、デバッグ環境

VBSなどHTMLスクリプトのデバッグをサポートしているエディタでオススメは、MS Officeに付属しているスクリプトエディタです。htmlのタグエディタの機能を合わせ持っているので、タグ入力は非常に楽です。

オフィスアプリからしか呼び出せないと思われがちですが、OfficeのディレクトリにちゃんとExeファイルがあり、単体で動作します。Windows98ではパスを変更していなければC:\Program Files\Microsoft Office\Office10\MSE7.EXE にセットアップされます。ない場合、MSE7.exe を検索してください。

インストールされてない場合は、インストールの必要があります。Officeアプリから、[ツール]->[マクロ]->Script Editor を選択すると、インストールするか聞いてきますので、そのままインストールしましょう。

.vbs をデバッグしたい場合は、スクリプトを<script>タグで挟んでからデバッグ実行します。基本的にこのデバッグは、HTMLスクリプトのデバッグなので、ブラウザ上で実行できるような形にしてあげる必要があるからです。

 <script language="VBScript">
 ....
 .... ここにVBSを記述します。
 ....
 </script>

オフィスを持っていない場合は、Microsoft Script Debugger というソフトがMicrosoftから無償で提供されています。http://www.microsoft.com/japan/msdn/scriptingからダウンロードできます。

ファイル選択ダイアログを使いたい

このダイアログを利用するにはVisualBasicのライセンスが必要です。参考: http://tuka.s12.xrea.com/index.xcg?page=BBS%2D%BB%A8%C3%CC%2F33

コモンダイアログコントロールを使います。

 Option Explicit
 
 Dim objDlg
 Set objDlg = WScript.CreateObject("MSComDlg.CommonDialog")
 
 With objDlg
     .Filter = "All Files (*.*)|*.*"
     .MaxFileSize = 256
     .CancelError = false
     .ShowOpen
     MsgBox .Filename
 End With
 
 Set objDlg = Nothing

保存用なら、ShowOpen ではなく、ShowSaveを使います。

フォルダ選択ダイアログ

ShellオブジェクトのBrowseForFolderメソッドを使う方法です。このメソッドは選択されたフォルダをFolderオブジェクトとして返します。以下は選択されたフォルダを単純に表示するサンプルです。

 Option Explicit
 ' selfolder.vbs - フォルダ選択ダイアログサンプル
 Const BIF_RETURNONLYFSDIRS   = &H1
 Const BIF_DONTGOBELOWDOMAIN  = &H2
 Const BIF_STATUSTEXT         = &H4
 Const BIF_RETURNFSANCESTORS  = &H8
 Const BIF_EDITBOX            = &H10
 Const BIF_VALIDATE           = &H20
 Const BIF_BROWSEFORCOMPUTER  = &H1000
 Const BIF_BROWSEFORPRINTER   = &H2000
 Const BIF_BROWSEINCLUDEFILES = &H4000
 
 Dim objSA, objFol
 Set objSA = WScript.CreateObject("Shell.Application")
 Set objFol = objSA.BrowseForFolder(0, "フォルダを選択するのだ!", BIF_EDITBOX)
 WScript.Echo objFol.Items.Item.Path
 Set objSA = Nothing

詳しい情報は、MSDNに掲載されています。

プログラムの強制終了

プログラムの途中で強制的に終了したいことがあります。例えば、エラー処理の後にすぐに終了したい場合などです。

 WScript.Quit

と記述します。

月末の日付を求める

マニュアルに詳しく記載されていますが、該当月の翌月の初日の前日 が月末となります。初日の前日は、1-1=0 です。

 Option Explicit
 ' LastDay.vbs - 今月末を求める
 
 Dim LastDay
 LastDay = DateSerial(Year(Date), Month(Date)+1, 0)
 
 MsgBox LastDay

VBSのユーザインターフェース

VBSは色々な場面で利用できますが、このページに載せているVBSはフォーム等のユーザインターフェースがありません。なぜならVBS自体はユーザインターフェースの機能を殆ど持たないからです。普通の命令で利用できるのは、ダイアログ(MsgBox)やインプットボックス(InputBox)だけです。

フォームなどのユーザインターフェースを利用するには、ASPやIE(HTML)を使うことになります。各技術ごとの制限などは以下です。

拡張子ブラウザ制限など
ASP.aspなんでも可IIS/PWS経由でアクセスしなければならない
HTML.htm .htmlIEのみFileSystemObjectなどセキュリティ上好ましくない機能は利用できない
WSH.wsf .vbs-GUIを持たない
HTA.htaIEのみセキュリティ上好ましくない機能も利用できる:-)

このうちHTAは非常に便利でスピードこそ劣りますが、実行形式(.exe)ファイルのように殆ど制限のない単体のアプリケーションを作成することができます。.exe のインタプリタ版といったところでしょうか。

スペシャルフォルダー

OSのバージョンや個人の設定に依存してしまうものとして、スペシャルフォルダーがあります。マイドキュメントやデスクトップなどがそれにあたりますが、これらのスペシャルフォルダーを動的に取得し使用することで、環境に左右されにくいスクリプトを書くことができます。たとえば、デスクトップにショートカットを作成するようなスクリプトなどに利用します。

 Option Explicit
 
 Dim props(15)
 props(0) = "AllUsersDesktop"
 props(1) = "AllUsersStartMenu"
 props(2) = "AllUsersPrograms"
 props(3) = "AllUsersStartup"
 props(4) = "Desktop"
 props(5) = "Favorites"
 props(6) = "Fonts"
 props(7) = "MyDocuments"
 props(8) = "NetHood"
 props(9) = "PrintHood"
 props(10) = "Programs"
 props(11) = "Recent"
 props(12) = "SendTo"
 props(13) = "StartMenu"
 props(14) = "Startup"
 props(15) = "Templates"
 
 Dim objWS
 Set objWS = CreateObject("WScript.Shell")
 
 Dim prop
 For Each prop In props
     MsgBox prop & vbCr & objWS.SpecialFolders(prop)
 Next
 
 Set objWS = Nothing

上記サンプルは、スペシャルフォルダーを1つずつメッセージボックスに表示していきます。

WshSpecialFolders オブジェクト

配列のSort(並べ替え)

悲しいことにVBScriptにはソートする関数が用意されていません。しかしながら世には優れたコンポーネントが沢山ありますので、そのようなコンポーネントを利用すれば実装は簡単です。しかしながら、レジストリを汚したくないとか、インストールが煩わしいとか、クライアントのマシンにインストールできないとか理由は色々あると思いますが、単純なソートの為にに態々コンポーネントを利用したくないこともあります。

そんな場合は、ソートの関数を自作しましょう。クイックソートはアルゴリズムが単純でしかも高速です。スクリプトレベルで実装しても高速で実用的だと思います。

クイックソートのアルゴリズムの簡単な概念は次のようになります。

 Option Explicit
 ' qsort.vbs - 配列のクイックソート
 
 ' 配列エントリのサンプル
 Dim entry
 entry = Array(53, 32, 98, 83, 38, 27, 10, 92, 33, 45)
 'entry = Array("こ","ん","に","ち","わ","せ","か","い","!")
 
 ' ソート前後の配列内容を表示するテスト
 dispArray entry
 qsort entry
 dispArray entry
  
 ' クイックソートのインターフェース
 Sub qsort(array)
     quicksort array, 0, UBound(array)
 End Sub
 
 ' クイックソート本体(再帰)
 Sub quicksort(array, first, last)
     Dim point, f, l, tmp
     point = array(first)
     f = first: l = last
     Do
         While array(f) < point: f = f + 1: Wend
         While array(l) > point: l = l - 1: Wend
         If f >= l Then Exit Do
         tmp = array(f): array(f) = array(l): array(l) = tmp
         f = f + 1: l = l - 1
     Loop
     If first < f - 1 Then quicksort array, first, f - 1
     If l + 1 < last  Then quicksort array, l + 1, last
 End Sub
 
 ' 配列内容を表示する
 Sub dispArray(datas)
     Dim data, str
 
     For Each data In datas
         str = str & data & vbCr
     Next
     MsgBox str
 End Sub

関数のリファレンスを使う!!

関数のリファレンスを使ったちょっと高度なテクニックです。マニュアルを見るとGetRef()は、関数をDHTMLのイベントと接続し、イベントが発生すると指定した関数が実行される例が載っていました。

果たしてイベントにしか利用できないのか?と思い実験してみたところ、変数にも格納できることがわかりました。

 Option Explicit
 ' GetRef.vbs - GetRef()のテスト 
 Dim objRef
 Set objRef = GetRef("Hello")
 
 objRef("Hoge")
 
 Sub Hello(str)
     MsgBox "Hello " & str & "!"
 End Sub

とこのように変数に関数へのリファレンスを格納して、呼び出すことができます。さらに発展させて、ハッシュに関数へのリファレンスを格納することもできました。

 Option Explicit
 ' hashref - 関数リファレンスをハッシュへ格納するテスト
 ' Windows98SE, VBScript5.6 で動作確認
 Dim objDic
 Set objDic = CreateObject("Scripting.Dictionary")
 
 ' 関数へのリファレンスのハッシュ
 objDic.Add "名前を聞く", GetRef("inputName")
 objDic.Add "名前を表示", GetRef("showName")
 
 ' 関数呼び出しテスト
 Dim strName
 strName = objDic("名前を聞く")()
 objDic("名前を表示")(strName)
 
 Set objDic = Nothing
 
 Function inputName
     inputName = InputBox("あなたの名前は?")
 End Function
 
 Sub showName(name)
     MsgBox "あなたの名前は" & name & "です。"
 End Sub

とこのようになります。引数の無いプロシージャの場合は、objDic("名前を聞く")()のように空の()を使用します。

配列を動的に変更しながらデータを格納する

配列を動的に変更するメリットは、

などがあります。

VBSctiptでは、配列を動的に変更するのにReDimというステートメントを使います。「最低10個の配列は必ず必要」とか決まっているなら、単純に ReDim hoge(9) などとやってしまえばよいですが、決まっていない場合は、一度空の配列を作成してからReDimします。

また実際の処理では、なんらかのデータを読み込みながら配列に格納したり、規則的な計算で演算結果を配列に格納したりする場合など、ループを使うことが多いと思います。そういった場合、UBound(hoge)で配列インデックスの最大値を求めてから、ループごとに+1することで次に作成するインデックスを取得できます。

動的に作成した配列は、Eraseを使うとメモリを解放することができます。使わなくなった配列は小まめにメモリ解放してあげましょう。

下記サンプルは、hoge.vbs の内容を配列に一行づず格納し、結果を一行ずつ配列から読み取り表示します。

 Option Explicit
 ' 配列を動的に変更しながらデータを格納する
 Const FileName = "hoge.vbs"
 
 Dim objFS, objTS
 Set objFS = CreateObject("Scripting.FileSystemObject")
 Set objTS = objFS.OpenTextFile(FileName)
 
 ' 配列を動的に変更しながらデータを格納する
 Dim strLines, n
 strLines = Array
 
 Do Until objTS.atEndOfStream
     n = UBound(strLines) + 1
     ReDim Preserve strLines(n)
     strLines(n) = objTS.ReadLine
 Loop
 
 Set objFS = Nothing
 
 ' 配列の内容を順番に表示する
 Dim strLine
 For Each strLine In strLines
     WScript.Echo strLine
 Next
 
 Erase strLines

ドラッグ&ドロップアプリケーション

VBS(WSH)ではドラッグ アンド ドロップがサポートされていますが、ドロップできるファイル数に制限があるので結構ショボイです。マニュアルによると、

スクリプトにドラッグできるファイルの数は、システムで許容されるコマンド ラインの長さの上限によって決まります。ドラッグしたファイル名をすべて合わせた文字数がコマンドラインの長さ制限を超えていると、ドラッグ アンド ドロップ操作が失敗します。

だそうです。試しにデフォルトの設定で10ファイルくらいドラッグ&ドロップしたらエラーがでました。ありゃりゃ。:-( これを踏まえてドロップするファイルは、是非、浅い階層で短いフォルダ名に入れておきましょう!・・・オイオイ。

まあでも、そのことに目を瞑れば取得も簡単で結構便利です。

サンプルは、ドロップしたファイルのリードオンリー属性を反転します。おー、このソフト結構便利かも。:-P

 Option Explicit
 ' revro.vbs - ドロップしたファイルのリードオンリー属性を反転する
 Dim objArgs, strPath
 Set objArgs = WScript.Arguments
 
 Dim objFS, objFile
 Set objFS = CreateObject("Scripting.FileSystemObject")
 
 For Each strPath In objArgs
   Set objFile = objFS.GetFile(strPath)
   objFile.Attributes = objFile.Attributes Xor 1
 Next
 
 Set objFS = Nothing

VBSのソースコードをエンコードしたい

Microsoftから無償でダウンロードできるScript Encoderを使います。以下からダウンロードできます。

http://www.microsoft.com/downloads/details.aspx?displaylang=ja&familyid=2976EE94-BEC5-4314-84FD-8D7EC891C1C5

使い方はScript Encoderのマニュアルに書かれていますが、以前VBScriptのエンコードでちょっとハマッたので、それだけ紹介しておきます。

生VBSファイル(拡張子.vbs)をエンコードするには、アウトプットファイル名の拡張子を.vbeにします。

 screnc hoge.vbs hoge.vbe

生成されたhoge.vbeファイルはそのままhoge.vbsと同様に動作します。

数字を3桁ごとにカンマ区切りしたい

文字列中から数字を探して、3桁ごとにカンマ区切りする方法です。

与えられた文字列を逆さまにしてから3桁数値ごとにマッチさせます。その際、肯定先読み(?=\d)を使用して4桁目が存在する場合のみマッチさせます。これがないと、3桁や6桁の数値の先頭にカンマが入ってしまいます。

置換の終わった文字列は再度逆さまにして元に戻します。

 Option Explicit
 ' 3figure.vbs - 数字を3桁ごとにカンマ区切り
 
 Dim objRE, Num
 Num = "この車は2150000円しました。1000台限りの限定発売でした。"
 
 Set objRE = New RegExp
 
 objRE.Pattern = "(\d\d\d)(?=\d)"
 objRE.Global = True
 Num = StrReverse(objRE.Replace(StrReverse(Num), "$1,"))
 Set objRE = Nothing
 
 WScript.Echo Num

また、単純に数値だけであれば、FormatNumber関数を使うと簡単です。

 Num = 1000000
 WScript.Echo FormatNumber(Num, False, False, False, True)

文字列をバイト単位で扱う関数

文字列をバイト単位で扱う関数です。マニュアルの片隅にちょこっとだけ載っています。なぜこんな小さく載せているのかちょっと疑問です。VBAのマニュアルでは目次になっているのにねぇ・・・。

例えば、Lenは文字数ですが、LenBはByte数になります。

 Option Explicit
 'bytefunc.vbs
 Dim str
 str = "深夜でございます"
 
 WScript.Echo "文字数は" & Len(str) & "文字です"
 WScript.Echo "Byte数は" & LenB(str) & "Byteです"
 WScript.Echo Left(str, 2) & " - " & Mid(str, 3, 4) & " - " & Right(str, 2)
 WScript.Echo LeftB(str, 2) & " - " & MidB(str, 3, 4) & " - " & RightB(str, 2)
 WScript.Echo Asc("漢")
 WScript.Echo AscB("漢") & " - " & AscB(RightB("漢", 1))
 WScript.Echo "Chr(-30017)は" & Chr(-30017) & "です"
 WScript.Echo "ChrB(34) & ChrB(111)は" & ChrB(34) & ChrB(111) & " です"

バイナリデータの読み書き

{{include ADO,バイナリデータの読み書き}}

イベントを処理する

VBSでイベントを使うには、WScript.CreateObject の第2引数にプリフィックスを指定します。プリフィックス_イベント名のような関数を定義すると、イベントが起こるとその関数が呼び出されます。

CreateObjectは3種類あり間違いやすいので注意が必要です。

  1. CreateObject
  2. WScript.CreateObject
  3. Server.CreateObject

このうちイベントに使うのは、WScriptオブジェクトのCreateObjectです。WScript.CreateObjectはWSHでしか利用できませんが、イベントと接続できます。Server.CreateObjectはASPのサーバスクリプト内で利用します。ただのCreateObjectは、普通にオブジェクトのインスタンスを作成したり、リモートのインスタンスを作成したりできます。

サンプルは、ADODB.Connection のイベントであるConnectCompleteとDisconnectを使っています。非同期接続を行い5秒後に接続を切ります。接続されるとCon_ConnectComplete が処理され、切断するとCon_Disconnect が処理されます。

 Option Explicit
 ' adoev.vbs - ADOイベントをVBScriptで使ってみるテスト
 Dim objCon
 Set objCon = WScript.CreateObject("ADODB.Connection", "Con_")
 objCon.Open "File Name=nw.udl" , , , 16
 
 WScript.Sleep 5000
 
 objCon.Close
 Set objCon = Nothing
 
 Sub Con_ConnectComplete(ByVal pError, adStatus, ByVal pConnection)
     WScript.Echo "接続しちゃった!"
 End Sub
 
 Sub Con_Disconnect(adStatus, ByVal pConnection)
     WScript.Echo "切っちゃった!"
 End Sub

巨大な数値を扱う

世に言うBigIntです。実は仕事で必要となり本日急遽作成したものです。スクリプトでなくても良かったのですが、書いてみたら意外と早かったのでスクリプトのまま納める予定です。

さておき、このプログラムは正の2値の足し算ルーチンのみです。引数は当然ながら、文字列な数値となります。アルゴリズムは単純に1桁ずつ筆算するような感じです。

 Option Explicit
 ' bigint.vbs - 巨大な数値を扱う
 Dim A, B
 A = "900750974388398729199701419182087930200787329829"
 B = "4127897100837491024712900874190749187491438878923"
 
 WScript.Echo BigInt_Add(A, B)
 
 Function BigInt_Add(X, Y)
     Dim aZ, i, iZ, iK, l, lX, lY
     lX = Len(X)
     lY = Len(Y)
     If lX > lY Then
         Y = String(lX - lY, "0") & Y
         l = lX
     Else 
         X = String(lY - lX, "0") & X
         l = lY
     End If
 
     aZ = Array
     ReDim Preserve aZ(l)
 
     iK = 0
     For i = l To 1 Step - 1
         iZ = CInt(Mid(X, i, 1)) + CInt(Mid(Y, i, 1)) + iK
         If iZ >= 10 Then
             iZ = iZ - 10
             iK = 1
         Else
             iK = 0
         End If
         aZ(i) = iZ
     Next
     If iK Then
         aZ(0) = 1
     End If
     BigInt_Add = Join(aZ, "")
     Erase aZ
 End Function

上記サンプルでは省きましたが、BigIntな数値文字列でも、IsNumeric()で検査できるので、関数内か関数呼び出し前に簡単にチェックすることが可能です。例えば、

 If Not (IsNumeric(X) And IsNumeric(Y)) Then
     WScript.Echo "引数は数値として評価できません"
     WScript.Quit
 End If

のようにチェックします。

カレントディレクトリを取得したい

GetFolder関数でカレント(".")を指定することで、カレントフォルダを取得できます。

 Option Explicit
 ' cd.vbs - カレントディレクトリの取得
 Dim objFol
 Set objFol = CreateObject("Scripting.FileSystemObject").GetFolder(".")
 WScript.Echo objFol.Path
 Set objFol = Nothing

カレントディレクトリの取得は何かと便利です。例えば、プログラム中で使用する外部ファイルを相対パスで指定することが可能です。下記サンプルは、カレントディレクトリのUDLファイルを指定するADOの接続文字列を生成します。このようにしておけば、.udlファイルと.vbs を違う場所に移動しても、プログラム中のパスを書き換えることなく利用できます。

 Option Explicit
 ' cd2.vbs - カレントディレクトリの取得
 Const UDL = "nw.udl"
 
 Dim objFS, objFol, strConn
 Set objFS  = CreateObject("Scripting.FileSystemObject")
 Set objFol = objFS.GetFolder(".")
 strConn = "File Name=" & objFS.BuildPath(objFol.Path, UDL)
 Set objFol = Nothing
 Set objFS  = Nothing
 
 WScript.Echo strConn

こっちの方がオシャレかな?WScript.ScriptFullName で実行ファイルのフルパスを取得し、GetParentFolderName でその親パス(つまりカレントディレクトリ)を取得します。

 Option Explicit
 ' cd3.vbs - カレントディレクトリの取得
 Dim objFS
 Set objFS = CreateObject("Scripting.FileSystemObject")
 WScript.Echo objFS.GetParentFolderName(WScript.ScriptFullName)
 Set objFS = Nothing

カレントドライブを取得したい

ついでにカレントドライブの取得も。上のコードとそっくり・・・:-)

 Option Explicit
 ' curdrv.vbs - カレントドライブの取得
 Dim objFS
 Set objFS = CreateObject("Scripting.FileSystemObject")
 WScript.Echo objFS.GetDriveName(WScript.ScriptFullName)
 Set objFS = Nothing

CD-ROMがセットされているかどうかチェックする

作成したプログラムをCD-Rに焼いて配布するとか言った場合、エンドユーザーの環境によってCDドライブの場所は違います。あるユーザーはDドライブだったり、あるユーザーはEドライブだったりします。そういう場合を考慮して、配布するCD-ROMのボリューム名で検索するようにします。指定したボリュームが見つからない場合(=CD-ROMがセットされていない)は処理を終了するようにします。

 Option Explicit
 ' cdready.vbs - CD-ROMがセットされているかどうかチェックする
 Const CDROM       = 4
 Const VOLUME_NAME = "CDTITLE"
 
 Dim objFS, objDrv, strDrv
 Set objFS = CreateObject("Scripting.FileSystemObject")
 For Each objDrv In objFS.Drives
     With objDrv
         If .DriveType = CDROM And .VolumeName = VOLUME_NAME Then
             strDrv = .Path
             Exit For
         End If
     End With
 Next
 Set objFS = Nothing
 
 If IsEmpty(strDrv) Then
     MsgBox "CDをセットしてください!", vbCritical
     WScript.Quit
 End If
 
 ' ここからCDを使った処理を書く
 WScript.Echo strDrv & "ドライブにセットされてるよ!"

指定ディレクトリ以下の全てのファイルに対して処理する

Perl版しか書いてなかったんですねぇ。本日ASP開発で必要になったので作りました。再帰を使った単純な方法です。サンプルは、hoge以下の全てのファイル名を表示します。

 Option Explicit
 ' filefind.vbs - 再帰ファイルサーチ
 
 Const FIND_DIR = "hoge"
 
 Dim strFileList
 
 Dim objFS, objFolder
 Set objFS = CreateObject("Scripting.FileSystemObject")
 Set objFolder = objFS.GetFolder(FIND_DIR)
 FileFind objFolder
 Set objFolder = Nothing
 Set objFS = Nothing
  
 WScript.Echo strFileList
 WScript.Quit
 
 Sub FileFind(objFolder)
     Dim objFile, objSubFolder
 
     For Each objFile In objFolder.Files
         strFileList = strFileList & objFile.Name & vbCrLf
     Next
     For Each objSubFolder In objFolder.SubFolders
         FileFind objSubFolder
     Next
 End Sub

おまけアルゴリズム

ユークリッドの互除法

最大公約数を求めるアルゴリズムとして有名なユークリッドの互除法のプログラムです。

 Option Explicit
 ' ユークリッドの互除法(再帰版)
 Dim m, n
 m = 96
 n = 128
 
 MsgBox m & "と" & n & "の最大公約数は" & GCD(m, n) & "です"
 
 Function GCD(A, B)
     If A Mod B Then
         GCD = GCD(B, A Mod B)
     Else
         GCD = B
     End If
 End Function

再帰を使った方法が有名で見た目も非常に美しいですが、ループで処理したほうが実行速度は速いです。(こちらも意外と美しい:-P)

 Function GCD(A, B)
     Dim C
     While B
         C = A Mod B: A = B: B = C
     Wend
     GCD = A
 End Function

掲示板でのVBS関連話題

Yesterday Today Total