VBScriptでプログラミングの基礎を学ぼう13【オブジェクト変数】

VBScript入門
スポンサーリンク

久しぶりにVBScript入門記事を更新します。

今回はVBScriptにおける「オブジェクト変数」について紹介します。

プログラミング初心者の場合、この「オブジェクト変数」もなかなか理解しづらい概念ですが、非常に便利な仕組みなので是非習得してください。

オブジェクト変数とは

過去の記事で「変数」を紹介しています。
また別の記事では「配列」を紹介しました。

変数は“ある値を一時的に格納する入れ物”であり、配列は“複数の値を一塊のグループとして格納出来る重箱の様な入れ物”といった説明をしました。

今回の「オブジェクト変数」も変数と付くからには、最初に宣言をして、何かを代入して使うことに代わりは無いのですが、その変数という入れ物に入れるものは値ではなく「オブジェクト」です。

通常の変数と何が違うのかを次で説明していきます。

「変数」と「オブジェクト変数」の違い

前述した通り、通常の「変数」は数値や文字列などの何らかの値を格納します。
その値をプログラム内で出し入れして使用します。

「オブジェクト変数」とは、言葉の通り「オブジェクト」を格納します。
正確には”オブジェクトのアドレス位置“を格納するのですが、今回はそこまで理解を深める必要は無いので、単純にオブジェクトを格納すると理解してください。
では、そのオブジェクトとは何でしょうか?

ものすごく砕けた例えで言えば、”プログラムから呼び出せる部品“です。
似たような概念で言えば、VBScriptの組み込み関数である「Msgbox」はメッセージボックスを表示する部品ですし「IsDate」は引数の文字列が日付として扱えるかをチェックする部品です。

ただ、これらの組み込み関数は、呼び出したら処理を実行するだけで、この関数自体では値を保持できません。
オブジェクト変数は値を保持します。
また、通常の変数は値を保持するだけですが、オブジェクト変数は関数のように処理を実行します。
通常の変数の様に値が保持できて関数の様に処理ができる部品です。

う~ん、この説明だけでは正直良くわかりません。
具体的な例をあげると、VBScriptやVBAでよく使われるオブジェクトに「FileSystemObject」というオブジェクトがあります。

VBScriptの標準の機能としては、外部ファイルのコピーや移動、削除といった操作や、特定のフォルダのなかのファイル名の一覧を取得するといった処理はできません。
そもそもVBScript自体はそれほど多くの機能を持っていません。
VBScript自体では持っていない機能であっても、Windowsや外部プログラムが汎用的に提供している機能をプログラムから呼び出して操作することができます。
前述したFileSystemObjectもWindowsが提供する汎用的な機能の一つです。

Microsoftの「FileSystemObject」のリファレンスのリンクを参照してください。

FileSystemObject オブジェクト Microsoft Office VBA リファレンス

こちらを見て頂くとわかりますが、FileSystemObjectの配下に様々な「メソッド」や「プロパティ」が存在します。

メソッドはオブジェクトに対する「操作」。
プロパティはそのオブジェクト「固有のデータ」。
プロパティに値を入れてオブジェクトの設定する。

オブジェクト変数の使い方

VBScriptにおけるオブジェクト変数は、通常の変数と同様に、プログラム内で宣言します。
宣言した後、対象の変数に対してオブジェクトを代入します。
上記リンク先のMicrosoftのリファレンス記事内のサンプルコードでは以下の処理です。

Set fs = CreateObject(“Scripting.FileSystemObject”)

「fs」という変数に対して、CreateObjectでFileSystemObjectのインスタンスを生成し、setを付与して代入しています。

※「インスタンス」という言葉を使いましたが、これは「呼び出したオブジェクトをオブジェクト変数化して操作可能な状態にしたもの」と理解してもらえれば結構です。
※「set」については以前の記事で簡単に説明しています。

【VBScript】レコードセットを関数の戻り値に指定する方法
VBScriptでバッチを作っていて、たまにRecordsetを関数の戻り値に設定したい場合があり、いつもやり方を忘れる...

ここで変数「fs」は通常の変数からオブジェクト変数に変わりました。

オブジェクト変数化したことで、この変数名の後ろにドットを付けて、動作をメソッドで指定することで、様々な処理が行える様になります。

Microsoftのサンプルコードでは以下の様にメソッドを指定しています。

Set a = fs.CreateTextFile(“テキストファイルのフルパス”,上書き可否)

この「CreateTextFile」というメソッドは名前の通りテキストファイルを作成します。
このCreateTextFileは戻り値として、「TextStream」オブジェクトを返すため、変数「a」にsetを付与して代入して、変数aをオブジェクト変数化しています。
※FileSystemObjectやTextStreamなどのオブジェクトは利用する機会も多いので、後述のサンプルコードでも詳しく言及します。

今回の「FileSystemObject」の様に、プログラム内から「CreateObject」で様々なオブジェクトを呼び出してオブジェクト変数化することで、VBScriptからExcelを操作したり、Windowsのコマンドを実行したり、データベースと接続してレコードセットを操作したりできます。

よく利用するオブジェクトとそのサンプルコード

次に、VBScriptでプログラムを作成する際に、私がよく利用するオブジェクトとそのサンプルコードを紹介します。
また、サンプルコード内のコメントにてオブジェクト変数に関する解説も記述してあります為、ご確認ください。

ADODB関連オブジェクト

VBScriptでデータベースに接続して処理を自動化する場合には、ADO関連のオブジェクトを利用します。

Option Explicit

'スクリプトレベル変数(共通変数)を定義します。'***********************************
Dim srvName, dbName, loginName, loginPass	'データベースの接続情報関連変数'

	'データベース接続情報'
	srvName = "サーバのIPアドレス又はホスト名"
	dbName = "データベース名"
	loginName = "DBユーザー名"
	loginPass = "DBユーザーパスワード"
'****************************************************************************'

Call Main()

Sub Main()

	Dim objCon		'Connectionオブジェクト用変数
	Dim objRS		'Recordsetオブジェクト用変数
	Dim query		'SQL文字列格納用変数

		'インスタンスを生成
		'解説:
		' CreateObjectでADODB.Connectionを呼び出して、変数objConにsetを付けて
		' 代入し、ADODB.Connectionオブジェクトとして使用出来る状態にします。
		Set objCon = CreateObject("ADODB.Connection")

		'データベースと接続
		'解説:
		' ADODB.ConnectionオブジェクトのOpenメソッドに、データベース接続文字列を
		' 引数として渡して実行します。
		objCon.Open "Driver={SQL Server};" & _
			" server=" & srvName & "; database=" & dbName & "; uid=" & loginName & "; pwd=" & loginPass & ";"
        
		'SQL文字列を指定
		'解説:
		' 変数queryはただの文字列としてSQL文を格納する為、setの付与は不要です。
		query = "SELECT * FROM 対象テーブル名 WHERE データ取得条件"
		
		'SQLを実行
		'解説:
		' ConnectionオブジェクトのExecuteメソッドの戻り値はRecordsetオブジェクト。
		' 変数 objRS にオブジェクトを代入する為、set を付与しています。
		Set objRS = objCon.Execute(query)

		'取得したレコードの最初の行の指定したカラム名の値をMsgboxに表示
		'解説:
		' Recordsetオブジェクトのvalueプロパティから値を取得しています。
		msgbox objRS.Value("指定したカラム名")

		'取得したレコードのレコード件数をMsgboxに表示
		'解説:
		' RecordsetオブジェクトのRecordCountプロパティから値を取得しています。
		msgbox objRS.RecordCount

		'データベース接続及びレコードセット接続を切断
		'解説:
		' RecordsetオブジェクトとConnectionオブジェクトのCloseメソッドを実行して、
		' 明示的にオブジェクト変数を閉じます。
		objRs.Close
		objCon.Close

		'使用したオブジェクト変数を破棄
		'解説:
		' オブジェクト変数である、objCon及びobjRSの使用が終了した為、メモリ上から
		' 当変数を完全に解放(削除)します。
		Set objRS = Nothing
		Set objCon = Nothing

	End Sub

VBScriptでデータベースと接続して処理を行うときはADOと呼ばれるデータベースへの操作を共通化した仕組みを使います。
上記コード内のConnectionオブジェクトはデータベースとの接続処理を担い、トランザクションを管理するメソッドも持っています。
上記コードではRecordsetオブジェクトは、Createobjectで明示的な生成はしていませんが、ConnectionオブジェクトのExecuteメソッドではSQLを実行できますが、その戻り値はRecordsetオブジェクトで返してくるため、戻り値をsetで変数に代入してRecordsetオブジェクト化しています。

FileSystemObjectオブジェクト

業務を自動化するうえで、自端末やファイルサーバのファイルやフォルダに対して各種操作や情報の取得などを行える「FileSystemObject」は必ずおさえておきたい機能の一つです。

Dim objFS			'FileSystemObject格納用
Dim objFile			'TextStream格納用

	'インスタンスを生成
	'解説:
	' CreateObjectでScripting.FileSystemObjectを呼び出して、変数objFSにsetを付けて
	' 代入し、FileSystemObjectオブジェクトとして使用出来る状態にします。
	Set objFS = CreateObject("Scripting.FileSystemObject")

	'指定したドライブの存在チェック
	'解説:
	' FileSystemObjectオブジェクトのDriveExistsメソッドに引数を渡して実行し、
	' 戻り値を真偽値で返します。
	If objFS.DriveExists("C") Then
	    msgbox "指定したドライブは存在します。"
	Else
	    msgbox "指定したドライブは存在しません。"
	End If

	'指定したファイルのコピー
	'解説:
	' FileSystemObjectオブジェクトのCopyFileメソッドに引数を渡して実行します。
	objFS.CopyFile "C:\コピー元ファイル.txt","C:\test\"

	'指定したテキストファイルの読み込み
	'解説:
	' FileSystemObjectオブジェクトのOpenTextFileメソッドに引数を渡して実行し、
	' 当メソッドはTextStreamオブジェクトが戻される為、その戻り値を変数objFileに
	' setを付与して代入します。
	Set objFile  = objFS.OpenTextFile("C:\読込対象ファイル.txt", 1)

	'読み込んだテキストファイルの1行目を表示
	'解説:
	' TextStreamオブジェクトのReadLineメソッドでは読み込んだテキストファイルの
	' 1行目(テキストの始めから最初の改行まで)を文字列で返します。
	msgbox objFile.ReadLine

	'開いているテキストファイルを閉じる。
	'解説:
	' TextStreamオブジェクトでテキストファイルは物理的に開いたままの状態になっており、
	' 対象のテキストファイルを他のプロセスが編集や削除等を出来ない状態な為、
	' 当プログラム内でのテキストファイルの使用が終わったら、TextStreamオブジェクトの
	' Closeメソッドを実行して、テキストファイルを閉じます。
	objFile.Close

	'使用したオブジェクト変数を破棄
	'解説:
	' オブジェクト変数である、objFile及びobjFSの使用が終了した為、メモリ上から
	' 当変数を完全に解放(削除)します。
	Set objFile = Nothing
	Set objFS = Nothing

FileSystemObjectオブジェクトのOpenTextFileメソッドでは、指定したテキストファイルを開き、戻り値としてTextStreamオブジェクトを返します。
この戻り値のTextStreamオブジェクトを変数にsetで代入するとこで、その変数はTextStreamオブジェクト化し、そのオブジェクト変数のメソッドを指定することで、開いているテキストファイルに対して値を書き込んだり、読み込むことができます。

WshShellオブジェクト

シェル」とは、名前の通り「貝」の様にOSの核であるカーネルを覆っており、カーネルに対するユーザーの操作を受け付けて、処理結果を返すといったインターフェースの様なものです。

もっと砕けた言い方で言えば、WindowsOSの場合は、Windowsのスタートメニュー内の「コマンドプロンプト」を用いた各操作などがそれにあたります。

取り敢えず、「WshShellオブジェクト」とは、VBScriptからWindowsのコマンドプロンプトを呼び出してコマンドを実行したり、レジストリと呼ばれるWindows自体の設定を書き換えたり、環境変数などのWindows固有の変数にアクセスするといったことが行えるオブジェクトです。

前述しましたが、VBScript自体が標準で持っている機能自体はそれほど多くはないです。
その為、Windows自体を直接操作できるコマンドプロンプトでコマンドを実行しないと実現できない処理もあります。

そんなときに今回のWshShellオブジェクトを呼び出します。

Dim objShell		'WshShellオブジェクト格納用

    'インスタンスを生成
    '解説:
    ' CreateObjectでWScript.Shellを呼び出して、変数objShellにsetを付けて
    ' 代入し、WshShellオブジェクトとして使用出来る状態にします。
    Set objShell = CreateObject("WScript.Shell")

    'カレントディレクトリ(自身が存在するフォルダ)を取得
    '解説:
    ' WshShellオブジェクトのCurrentDirectoryプロパティは、このvbsファイルが
    ' 存在するフォルダのパスを保持しています。
    msgbox "現在のフォルダは " & objShell.CurrentDirectory

    'Windowsコマンドを実行1
    '解説:
    ' WshShellオブジェクトのRunメソッドは、引数で渡された文字列を
    ' コマンドプロンプトで実行します。
    ' Runメソッドの引数 第1:実行するコマンド 第2:ウィンドウスタイル 第3:同期実行有無
    ' 当コードではメモ帳を起動します。尚、引数2と3は省略可能です。
    ' ※%windir%はWindows自体が使用している変数で通常はC\:Windowsを表します。

    msgbox "同期処理でメモ帳を起動し、メモ帳が閉じられたらメッセージを表示します。"
    objShell.Run "%windir%\system32\notepad.exe",,True
    msgbox "メモ帳が閉じられました。"

    msgbox "非同期処理でメモ帳を起動します。※メモ帳を起動した直後に次の処理に移ります。"
    objShell.Run "%windir%\system32\notepad.exe"

    'Windowsコマンドを実行1
    '解説:
    ' WshShellオブジェクトのRunメソッドは、引数で渡された文字列を
    ' コマンドプロンプトで実行します。
    ' Runメソッドの引数 第1:実行するコマンド 第2:ウィンドウスタイル 第3:同期実行有無
    ' 当コードではNET USE コマンドを実行及び切断します。
    ' 引数2でウィンドウスタイルを「0:非表示」に指定し、引数3で処理完了まで待つ同期実行を指定。
    msgbox "NET USEを実行します。"
    objShell.Run "net use 接続先ホスト名orIP 接続先パスワード /user:接続先ユーザー名",0,true
    msgbox "NET USEを切断します。"
    objShell.Run "net use 接続先ホスト名orIP /DELETE",0,true

    '使用したオブジェクト変数を破棄
    '解説:
    ' オブジェクト変数である、objShellの使用が終了した為、メモリ上から
    ' 当変数を完全に解放(削除)します。
    Set objShell = Nothing

WshShellオブジェクトのRunメソッドでは、Windowsのコマンドを実行できますが、引数でコマンドの実行を待って次の処理に移るか、コマンドを実行してそのコマンドの完了を待たずに次の処理に移るかを指定できます。この処理の完了を待って次の処理に移ることを「同期的実行」と読んだりしますが、RunメソッドでWindowsコマンドを実行する場合に、この同期的実行の実施有無を使い分けることは非常に重要です。
上記サンプルコードの「NET USE」を非同期的に実行する場合は、NET USEで共有フォルダとの認証、接続処理を開始し、その処理が終わらないうちに次の処理で共有フォルダへアクセスしてしまい、エラーになります。
また、同じく上記サンプルコードのメモ帳を起動するようなケースですと、もし同期的に実行した場合は、起動されたメモ帳を閉じないと次の処理には進まず、VBScriptの処理は延々とメモ帳が閉じられるのを待ち続けることになります

最後に

今回のVBScript入門記事は、一気に難易度が上がってしまった感はありますが、「オブジェクト変数」に対して可能な限り噛み砕いて説明したつもりです。

ネットで見つけたサンプルコードをコピペして実行してもそれなりに動くと思いますが、しっかりプログラミングの基本を理解してプログラムを作ることで、もっとプログラミングは便利になります。
是非活用してください。

今回も読んで頂きありがとうございました。
それでは、ごきげんよう。

↓次回の記事はこちら

VBScriptでプログラミングの基礎を学ぼう14【エラー処理】
今回はVBScriptにおける「エラー処理」について説明していきます。 エラー処理とは プログラミングでは、様々...

↓前回の記事はこちら

VBScriptでプログラミングの基礎を学ぼう12【入門記事総集編】
久々の更新です。今回はこれまで更新してきたVBScriptでのプログラミング入門記事の内容を復習しつつ、VBScript...

Windows10で文字化けする場合

Windows10でテキストファイルを作成した場合の規定の文字コードがVBScriptに対応していないことが原因です。
詳しい原因の解説と、その対応方法を記事にしてあるので参照してください。

【VBScript】Windows10でmsgboxが文字化けする原因と対策
今回は「Windows 10」環境でVBScriptのプログラムを作るとmsgboxが文字化けする現象に関して、その原因...