本文中の記述例およびサンプルは、すべてVB6またはVBA5(Excel97)で書いてある。
記述例およびサンプルに含まれるファイルの全部、または一部を使用したことによる損害等について、一切の責任を負いません。
使用するテキストボックスは予めMultiLineプロパティをtrueにしておく。必要に応じてScrollBarsプロパティも設定する。テキストボックス内の文字列を任意の位置で改行させたければvbCrLfを連結すれば良い。SelTextプロパティを設定すれば自動的に表示位置もスクロールされて書き込んだところが表示されるようになる。
txtOut.SelText = "Allergy testing" & vbCrLf
もちろん&演算子を用いて通常の文字列と同じように連結しても良い。その場合は以下のようになる。テキストボックスへの文字列の追加が済んだら、SelStartプロパティを設定して追加した最後尾(最新)の文字列を画面に表示させる。このとき最後尾の文字列が画面に表示されていなければ、テキストボックス内の文字列が自動的にスクロールされ、設定したSelStart辺りの文字列が表示されるようになる。
txtOut.Text = txtOut.Text & "Allergy testing" & vbCrLf txtOut.SelStart = Len(txtOut)
ただし、こちらは毎回表示位置を再設定しているため、テキストが増えてくると非常に遅くなる。SelTextのほうは高速だが、ユーザがカーソルを移動しないことが前提である。
[VB]コマンドラインの取得
VBでコマンドラインを取得するにはCommand関数を使用する。Command関数はCプログラマにはおなじみのargc、argvと異なり、プログラムを起動したコマンド名は含まれず、全てのパラメータを含む単一の文字列として返す。
取得したコマンドラインをスペースで区切るにはSplit関数を利用すると良い。
' コマンドラインを取得しスペースで分割します Function getArgument() As String() Dim strArg() As String Dim i As Long strArg = Split(Command()) ' スペースで分割 Debug.Print "UBound(strArg) = " & UBound(strArg) For i = 0 To UBound(strArg) Debug.Print strArg(i) Next i getArgument = strArg End Function
コマンドラインを取得するサンプル
[VB]コンソールアプリケーションの起動と完了待ち
VBから他アプリケーションを起動するにはShell関数を使う方法とAPIのCreateProcessを使う方法がある。私は主に後者を用いる。
起動したアプリケーションの完了を待つにはそのプロセスのハンドルを取得し、APIのWaitForSingleObjectで待機する。取得したハンドルは必要がなくなったら解放する。
<Shell関数を使う方法>
Dim pid As Long Dim ph As Long Dim ecode As Long pid = Shell("aaa.exe work.txt", vbNormalFocus) ' aaa.exe実行 work.txtは引数 ph = OpenProcess(SYNCHRONIZE Or PROCESS_QUERY_INFORMATION, True, pid) WaitForSingleObject ph, 100000 ' aaa.exeが終了するまで待つ GetExitCodeProcess ph, ecode ' 終了コード取得 CloseHandle ph ' プロセスハンドルを閉じる
<CreateProcessを使う方法>
Dim pInfo As PROCESS_INFORMATION Dim sInfo As STARTUPINFO Dim lngRet As Long Dim ecode As Long sInfo.cb = LenB(sInfo) lngRet = CreateProcess(vbNullString, _ "aaa.exe work.txt", _ ByVal 0&, _ ByVal 0&, _ 1&, _ NORMAL_PRIORITY_CLASS, _ ByVal 0&, _ vbNullString, _ sInfo, _ pInfo) WaitForSingleObject pInfo.hProcess, 100000 ' aaa.exeが終了するまで待つ GetExitCodeProcess pInfo.hProcess, ecode ' 終了コード取得 CloseHandle pInfo.hThread ' スレッドハンドルを閉じる CloseHandle pInfo.hProcess ' プロセスハンドルを閉じる
何れの方法も出力のリダイレクトができないようです。リダイレクトを必要とする場合は、予めバッチファイルを作成し、そのバッチファイルを実行すると良い。またShell関数またはCreateProcessを呼び出した後は、DoEvents等でCPUを解放すると良いようだ。
APIのOpenProcessの第一引数はNT系でのみ有効である。APIのGetExitCodeProcessにより、起動したアプリケーションの終了コードを取得し、処理を分岐させることが可能である。
コンソールアプリケーションの起動と完了待ちのサンプル
[VB]Excelの起動
VBで作成するアプリケーションからExcelを起動することがでる。もちろんExcelがインストールされている必要がある。Excelは巨大なActiveXオブジェクトなので、前述の通常のアプリケーションの起動方法とは異なるアプローチを用いる。こちらはオートシェイプのサンプルを見て欲しい。
Dim objAppXL As Excel.Application Set objAppXL = CreateObject("Excel.Application") ' Excel objAppXL.Caption = "サンプル" objAppXL.Visible = True ' 表示
このプログラムの動作にはExcelのタイプライプラリもインポートする必要があるのでお忘れなく。Excelのオブジェクトを作成することができれば、後はVBAと同じ感覚で操作することができる。
[VB]円形のスクリーンを描画する
リージョンかあ...大変だったなぁ。リージョンを使うとVisual Basicでも多様なグラフィック処理が可能になる。
正方形のリージョンを丸く刳り抜き、型枠を作成して上から被せる事により、円形のスクリーンを描くことが可能になる。この処理の肝はAPIのCombineRgnと、ピクチャーボックスのFillStyleプロパティを動的に変更することにある。画面更新の度にスクリーンを消去するが、AutoRedrawプロパティをTrueに設定しておく事でウィンドウのちらつきは最小限に抑えることができる。
GetClipBox pctScreen.hdc, mRect ' スクリーンのサイズを取得 ' 円形のリージョンを作成 hRgn2 = CreateEllipticRgn(mRect.Left - 1, mRect.Top - 1, mRect.Right + 2, mRect.Bottom + 2) mhRgn1 = CreateRectRgnIndirect(mRect) ' 正方形のリージョンを作成(スクリーンのサイズ) CombineRgn mhRgn1, mhRgn1, hRgn2, RGN_XOR ' 真中を丸くくりぬいたリージョンを作成 DeleteObject hRgn2 ' 不要なリージョンは解放
pctScreen.FillStyle = vbFSSolid ' 塗り潰し PaintRgn pctScreen.hdc, mhRgn1 ' 型枠の描画 pctScreen.FillStyle = vbFSTransparent ' 透明
円形スクリーンを描画するサンプル
[VB]App.Path
当然ご存知とは思うが念のため。App.Pathは実行ファイルのあるディレクトリのパスが入っている。例えば、
strFullPath = App.Path & "\test.txt"と書くと、実行ファイルと同一のディレクトリにある「test.txt」のパスを生成できる。
bytSjis = InputB(lngReadSize, #1) ' SJISのテキスト読み込み strUni = StrConv(bytSjis, vbUnicode) ' SJISからUNICODEへまず、InputBで必要なサイズ分ファイルから読み込む。InputBが返すのはバイトデータであるので、Visual Basicでテキストとして表示するためにはStrConvでUNICODEに変換する必要がある。例えば、これを100ms周期のファイルの差分読み込みに使用すると、Line Inputではすぐに動かなくなる処理が、ほとんどCPU時間を消費せずに可能になる。
高速なファイル読み込みのサンプル
[VB,VBA]オートシェイプを描画する
VBアプリケーションからExcelのオートシェイプを描画することができる。これはそれほど難しくないのだが、オートシェイプの操作方法を書いた資料がほとんど見当たらず、少しずつコードを書いては動かして調べた。
VBAはもちろんのこと、COMを使用してVBからもオートシェイプを操作することができる。VBでは「参照設定」でMicrosoft Excel x.x Object LibraryとMicrosoft Office x.x Object Libraryを参照するのを忘れてはならない。x.xの部分はバージョンによって異なる。
With ActiveSheet.Shapes.AddShape(msoShapeFlowchartProcess, _ 20, 20, 100, 20).TextFrame .Characters.Text = "Allegy" ' オートシェイプの中に文字 .Characters.Font.Size = 10 ' フォントサイズを10ポイントに .HorizontalAlignment = xlHAlignCenter ' 中央揃え .VerticalAlignment = xlVAlignCenter ' 中央揃え End With
Excelを起動し、オートシェイプを描画するサンプル
[VBA]標準メニューに項目を追加する
Excel97からメニューの扱いが変わり多少苦労した。ここではブックのオープン時に、標準メニューに項目を追加する方法を紹介する。まずVisualBasicEditorを開き、ThisWorkbookのWorkbook_Openに以下のようなコードを記述する。
Private Sub Workbook_Open() With Application.CommandBars("Worksheet Menu Bar") ' メニューに項目を追加 With .Controls.Add(Type:=msoControlPopup, Temporary:=True) .Caption = "サンプル(&S)" ' サブメニューAAAを追加 .Controls.Add Type:=msoControlButton With .Controls(1) .Caption = "AAA(&A)" .OnAction = "mnuAaa" ' AAA選択時に実行されるSubプロシージャ名 End With ' サブメニューBBBを追加 .Controls.Add Type:=msoControlButton With .Controls(2) .Caption = "BBB(&B)" .OnAction = "mnuBbb" ' BBB選択時に実行されるSubプロシージャ名 End With End With End With End Sub
OnActionプロパティにより、メニュー選択時のSubプロシージャと結び付ける。結びつけるSubプロシージャは標準モジュール内に記述する。
Sub mnuAaa() MsgBox "AAA" End Sub Sub mnuBbb() MsgBox "BBB" End Sub
このExcelファイルを保存して終了し、再び開くと標準メニューの最後に「サンプル」と言う名前のメニュー項目が追加されているはずである。
.Controls.AddするときにTemporary:=Trueを指定しているため、このExcelファイルを開いていないときはメニュー項目に「サンプル」は現れない。XLStartフォルダにこのExcelファイルを入れることで、Excelの起動時に常に「サンプル」メニューを表示することができる。
標準メニューに項目を追加するサンプル(Excelファイル)
[VBA]画面更新を抑止して高速化
Excelの機能を利用して膨大な数のグラフィックを描くと非常に時間がかかる。そんな時ScreenUpdatingプロパティを変更して画面更新を抑止すると、かなり時間の節約になる。グラフィックの描画が終わったときはScreenUpdatingプロパティを元に戻す必要があるさもないと永久に画面の更新はされない。
Application.ScreenUpdating = False
Range("A6").Formula = "=SUM(A1:A5)"
さらにセルアドレスも併用すると、ループ処理などで利用できるようになる。AddressプロパティはExcelではおなじみの"A1"とか"B3"等の文字列を返します。
Cells(6, 3).Formula = "=SUM(" & Cells(1, 3).Address(False, False) & ":" & Cells(5, 3).Address(False, False) & ")"
数式を設定するサンプル(Excelファイル)
[VBA]ソートを行う
ソートは任意のRangeに対してSortメソッドを使用する。キーは複数設定可能で、また昇順及び降順の何れも実行可能だ。
Range("A1:B10").Sort Key1:=Columns("A")
ソートを行うサンプル(Excelファイル)
[VBA]検索を行う
検索は任意のRangeに対してFindメソッドを使用する。セルが検索された場合、そのセルが返されるのでRangeオブジェクトにSetする。セルが検索されなかった場合、Nothingが返される。
Dim objRange As Range Set objRange = Columns("A").Find("DEF")
検索を行うサンプル(Excelファイル)
[VBA]ThisWorkbook.Path
VBのApp.PathみたいなものがVBAにもある。ThisWorkbook.Pathがそれである。ちなみにApplication.Pathは、excel.exeがあるディレクトリを知ることができる。
Copyright(C) 2001-2003 Allergy Design Office All rights reserved.
[Home]