VB6系全般 †
基本的な言語仕様 †
仕様 | デフォルト | オプション指定 | 備考 |
文字列の比較 | バイナリ比較 (大文字小文字を区別) | Option Compare [Binaly|Text|Database] ※VBSでは使用不可 | DatabaseはAccessVBAのみ |
配列の添数 | 0~ | Option Base [0|1] ※VBSでは使用不可 | 「0~」の場合、Dim a(2)という配列はa(0)~a(2)までの3要素になることに注意 |
変数の宣言 | 不要 | Option Explicit | オプション指定すると、変数の宣言を強制できる |
オブジェクトのバインド †
- アーリーバインド(事前バインド)
COMコンポーネントをプログラムの実行前に参照設定しておく手法。VBScriptでは使用できない。
オブジェクト変数の宣言時に型を指定する。
1
2
3
4
| | Dim objFSO As New FileSystemObject
Set objFSO = Nothing
|
または、
1
2
3
4
5
| | Dim objFSO As FileSystemObject
Set objFSO = New FileSystemObject
Set objFSO = Nothing
|
長所:プログラムの実行速度が早い。
短所:COMコンポーネントの仕様変更により正常に動作しなくなる可能性がある。
- レイトバインド(実行時バインド)
COMコンポーネントをプログラムの実行時に取得する手法。
オブジェクト変数はObject型で宣言し、CreateObject関数を使用する。
1
2
3
4
5
| | Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFSO = Nothing
|
長所:COMコンポーネントの仕様変更に柔軟に対応できる。
短所:プログラムの実行速度が遅い。
疑似continue †
- ループ終端の直前にラベルを置いてGoToする。
- Forループに対しては、Doループをネスト
1
2
3
4
5
6
7
| | For k = 1 To 10
Do
:
Exit Do :
Loop Until 1
Next
|
- Doループに対しては、Forループをネスト
1
2
3
4
5
6
7
| | Do While True
For Ctn = 1 To 1
:
Exit For :
Next
Loop
|
関数ポインタ †
AddressOf演算子を用いることで、プロシージャのポインタを取得できる。Sub と Function のどちらにも有効。
外部DLLの読み込み †
Declare構文を使う。
- Win32APIを使うとき(例:Sleep関数)
1
| | Private Declare Sub Sleep Lib "KERNEL32.dll" (ByVal dwMilliseconds As Long)
|
プロパティのByRef引数への引き渡し †
VB6では、ByRef引数へプロパティを直接引き渡しても、プロパティの値は変更されない。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| | :
SomeObject.SomeProperty = "abc"
Call Test(SomeObject.SomeProperty)
:
Function Test(ByRef wk As String)
wk = "xyz"
End Function
|
DOSコマンドの実行 †
WScript.ShellオブジェクトのRunメソッドを用いる。
ただし、ひとつのDOS窓上で複数コマンドを実行することはできない。
1
2
3
4
5
| | CreateObject("WScript.Shell").Run "cmd /c ipconfig", 0, true
CreateObject("WScript.Shell").Run "cmd /k ipconfig", 1, true
|
条件評価を途中で中断しない †
Ifステートメントで複数条件をAndやOrで連結している場合、途中で条件式全体の真偽が確定したとしても、全ての条件判定を行うことに注意する。
下記のコードは、メッセージボックスが2回表示されることになる。
1
2
3
4
5
6
7
| | If False And MsgBox("test1") Then
End If
If True Or MsgBox("test2") Then
End If
|
SMTPによるメール送信 †
CDO.Messageというオブジェクトを使用するとWSHからメール送信を行うことができる。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| | Dim objMail
Dim strSchemas
set objMail = WScript.CreateObject("CDO.Message")
strSchemas = "http://schemas.microsoft.com/cdo/configuration/"
objMail.Configuration.Fields.Item(strSchemas & "sendusing") = 2 objMail.Configuration.Fields.Item(strSchemas & "smtpserver") = "smtp-server" objMail.Configuration.Fields.Item(strSchemas & "smtpserverport") = 25 objMail.Configuration.Fields.Item(strSchemas & "smtpconnectiontimeout" ) = 30 objMail.Configuration.Fields.Update
objMail.From = "送信元 <aaa@hoge.co.jp>"
objMail.To = "送信先1 <bbb@hoge.co.jp>; 送信先2 <ccc@hoge.co.jp>"
objMail.Cc = "送信先3 <ddd@hoge.co.jp>"
objMail.Bcc = "送信先4 <eee@hoge.co.jp>"
objMail.Subject = "タイトル:VBSによるメール送信テスト"
objMail.TextBody = _
"本文1" & vbCrLf & _
"本文2" & vbCrLf & _
"本文3" & vbCrLf
objMail.Send
set objMail = nothing
|
VBA †
全般 †
隠し関数 †
ヘルプに載っていないらしい関数。
- ObjPtr関数
オブジェクトのポインタ取得
- StrPtr関数
文字列の先頭ポインタ取得
※うまくいかない?
- VarPtr関数
変数のポインタ取得
外部オブジェクトの参照 †
FileSystemObject などは、VBEの「参照」で追加にチェックを入れておけば、
1
2
| | Dim objFSO As New Scripting.FileSystemObject
Dim objFolder As New Scripting.Folder
|
のように直接変数宣言が可能となる。CreateObject不要。→解放はCreateしてないんだからいらない?
配列の初期化はできない †
VB6では以下のような配列の初期化はできない。
1
| | Dim intNum() As Integer = {1, 2, 3, 4}
|
マクロを追加していないのにセキュリティ警告が表示される †
マクロを追加していない、もしくは全て削除したのにファイルを開くときにセキュリティ警告が表示されてしまう場合がある。
VBEで1行でもマクロコードを書いている場合はセキュリティ警告が出てしまう。
例えば、シートのコード欄に
が残っている可能性がある。
自動的に「Option Explicit」を挿入する設定になっている場合は、この状態になりやすいので注意。
Excel †
セルを選択する際の注意点 †
Range.Selectメソッド、またはRange.Activateメソッドを使ってセルを選択する場合、
対象のシートが選択されていないと実行時エラーとなり、メソッドが失敗する。
先に Worksheet.select メソッドで対象のシートを選択する処理を入れておくと回避できる。
シートの最下端の行番号/最左端の列番号 †
1
2
| | [Worksheetオブジェクト].Cells.Rows.Count [Worksheetオブジェクト].Cells.Cols.Count
|
使用されているセルのうち最終の行番号/列番号 †
1
2
3
4
5
| | [Worksheetオブジェクト].Cells([Worksheetオブジェクト].Rows.Count, col).End(xlUp).Row
[Worksheetオブジェクト].Cells(row, [Worksheetオブジェクト].Columns.Count).End(xlToLeft).Column
|
別のブックへのハイパーリンク †
- マクロでの設定
1
2
3
4
5
6
7
| | Hyperlinks.Add(
リンクするセル位置, アドレス, サブアドレス, ツールチップ文字列,
セルに表示する文字列
)
|
ハイパーリンクでジャンプしたときにジャンプ先のセルを画面左上に表示する †
Workbook の SheetFollowHyperlinkイベントをハンドルする。
1
2
3
4
| | Private Sub Workbook_SheetFollowHyperlink(ByVal Sh As Object, ByVal Target As Hyperlink)
Call Application.Goto(Selection, True) ActiveWindow. ScrollColumn = 1 End Sub
|
マクロで罫線を引く †
- 基本
1
2
3
4
5
| | with [Rangeオブジェクト].Borders(??) .LineStyle = xlContinuous .Weight = xlThin .ColorIndex = xlAutomatic End With
|
- 上下左右縦横の罫線を引く場合
1
| | [Rangeオブジェクト].Borders.LineStyle = xlContinuous
|
とすることで、以下のコードと同様の指定となる
1
2
3
4
5
6
7
8
| | With [Rangeオブジェクト]
.Borders(xlEdgeTop).LineStyle = xlContinuous
.Borders(xlEdgeBottom).LineStyle = xlContinuous
.Borders(xlEdgeRight).LineStyle = xlContinuous
.Borders(xlEdgeLeft).LineStyle = xlContinuous
.Borders(xlInsideVertical).LineStyle = xlContinuous
.Borders(xlInsideHorizontal).LineStyle = xlContinuous
End With
|
アプリケーション機能の制御 †
- エラーチェック機能のON/OFF
Application.ErrorCheckingOptionsオブジェクトの各プロパティをON/OFF。
※最初にそのユーザの設定値を取得しておいて、終了時に元に戻すのが無難。
- セルのエラー値
CVErr関数に取得したいエラーのID値を指定し、戻り値をセルのValueに入れることで
Excel標準のセルエラーを使用できる。
- 画面描画更新のON/OFF
Application.ScreenUpdating プロパティ
自作マクロをワークシート関数として使用する †
マクロの標準モジュール内にFunctionを定義すると、ワークシート関数として使用できる。
アドインマクロを自作メニューとして追加する †
メニューに追加されるオリジナルマクロを作る際は、メインの処理を 'Module' に追加しておく。
※'Module' に追加するモジュールでは、Thisworksheet オブジェクトではなく Activesheet を使用すること。
また、以下のコードを 'ThisWorkBook' に追加する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| | Private Sub Workbook_AddinInstall()
Set NewM = Application.CommandBars("Worksheet Menu Bar").Controls.Add(Type:=msoControlPopup)
NewM.Caption = "メニュー名"
Set NewC = NewM.Controls.Add
With NewC
.Caption = "表示するコマンド名"
.OnAction = "呼ばれるモジュール名"
.BeginGroup = False
.FaceId = 38 .TooltipText = "説明チップ"
End With
End Sub
|
1
2
3
| | Private Sub Workbook_AddinUninstall()
Application.CommandBars("Worksheet Menu Bar").Controls(MENU_MYMACRO).Delete
End Sub
|
アドインとして保存して出来上がり。
※メニューにFaceID(ツールバー上のアイコン)が同じである別のマクロをインストールすると、上書きされてしまう。
セルの接頭辞(先頭のシングルクォート) †
接頭辞とは、強制的に文字列と解釈させるためにセルの先頭に付けられた「'」のこと。
Range.ValueやRange.Textでは取得不可。Range.PrefixCharacterで取得可能。
セルの内容の取得 †
Rangeオブジェクトのプロパティによって取得できる値が異なる。
プロパティ | 取得できる値 |
Range.Value | 通常の値。デフォルトプロパティ |
Range.Value2 | シリアル値。日付型や通貨型の場合、Valueとは異なる値となる。 |
Range.Text | セルに実際に表示されている文字列。書式設定に依存する。 |
Range.Formula | セルに入力された数式(イコールを含む)。数式が入力されていない場合はValueと同様の値。 |
Visio †
イベント †
ExcelVBAのイベントのように簡単には実装できない。(外部アドインからも処理を可能とするため?)
詳しくは、開発者用ヘルプで「AddAdvise」や「イベント コード」を検索すること。
以下、ページを挿入したときのイベント「PageAdded」を実装するためのサンプル。
- クラスモジュールを追加する。オブジェクト名は「clsEventSink」とする。
- 追加したクラスモジュールに以下のコードを実装する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| | Option Explicit
Implements Visio.IVisEventProc
Private Const visEvtAdd% = &H8000
Private Function IVisEventProc_VisEventProc( _
ByVal nEventCode As Integer, _
ByVal pSourceObj As Object, _
ByVal nEventID As Long, _
ByVal nEventSeqNum As Long, _
ByVal pSubjectObj As Object, _
ByVal vMoreInfo As Variant) As Variant
Dim strMessage As String
Select Case nEventCode
Case (visEvtPage + visEvtAdd)
strMessage = "PageAdded (" & "&H" & Hex(nEventCode) & ")"
Case Else
strMessage = "Other (" & "&H" & Hex(nEventCode) & ")"
End Select
End Function
|
- 標準モジュールを追加する。オブジェクト名は任意で。
- 追加した標準モジュールに以下のコードを実装する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| | Option Explicit
Private mEventSink As clsEventSink
Dim vsoDocumentEvents As Visio.EventList
Dim vsoPageAddedEvent As Visio.Event
Private Const visEvtAdd% = &H8000
Public Sub CreateEventObjects()
Set mEventSink = New clsEventSink
Set vsoDocumentEvents = ActiveDocument.EventList
Set vsoPageAddedEvent = vsoDocumentEvents.AddAdvise( _
visEvtAdd + visEvtPage, mEventSink, "", "Page added...")
End Sub
Public Sub DeleteEventObjects()
vsoPageAddedEvent.Delete
Set vsoPageAddedEvent = Nothing
End Sub
|
- CreateEventObjectsマクロを実行すればイベントをハンドルできる状態になる。
※この作業を自動化できないか。
PageAdded以外のイベントを実装するには、(*1)~(*4)の処理に任意のイベント用の処理を追記する必要がある。
VBScript †
WSHエンジン †
VBScriptを実行するホストは、2種類ある。
それぞれで、WScript.Echo メソッドの処理が異なる。
既定のホストを変更することも可能。
クリップボード †
IE7がインストールされている状態でクリップボードを操作する場合、「インターネットオプション」-「セキュリティ」-「インターネット」を選択して「レベルのカスタマイズ」-「スクリプトによる貼り付け処理の許可」を有効にしておく必要がある。
正規表現 †
RegExpオブジェクトを用いることで正規表現が使用可能。
特に、VBSはLike演算子を使用できないので、正規表現を替わりに使用することになる。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| | Set objRE = CreateObject("VBScript.RegExp")
objRE.Pattern = "^test.*test$"
if objRE.Test("test_abcde_test") then
else
end if
Set objRE = Nothing
|
コモンダイアログ †
- ファイル選択ダイアログ
1
2
3
4
5
6
7
8
9
| | Set objDlg = WScript.CreateObject("MSComDlg.CommonDialog")
With objDlg
.Filter = "All Files (*.*)|*.*"
.MaxFileSize = 256
.CancelError = false
.ShowOpen strFileName = .Filename
End With
|
※VBがインストールされていないと使えない?
スクリプトの疑似EXEファイル化 †
Windowsに標準でインストールされている「IExpress.exe」を用いることで、スクリプトを疑似的にEXEファイルとして扱うことができる。
IExpressは、もともと自己解凍形式の圧縮ファイルを作成するツールである。自己解凍形式の圧縮ファイルをインストーラ目的で使用するために、「解凍時に自動的に実行するファイル」を設定できるため、これを利用する。
スクリプトファイルを圧縮対象のファイルに含め、「解凍時に自動的に実行するファイル」に指定することで、BAT,VBS,JS等のファイルが自動実行される。
※注意
- VBSやJS等のファイルは、解凍時に自動的に実行するファイル」として直接指定するとエラーになってしまうため、スクリプトを起動するバッチファイルを書いておき、それを指定する。
- あくまで疑似的なEXE化なので、コマンドライン引数を利用するスクリプトには使用できない。
スクリプトの終了 †