【Dev】.NET VB覚書@ことはじめ

開発ざれごと

HDDを掃除していたら出てきやがったメモです。以前に学習用にメモったやつです。ちょい古いけど。

VB .NET初歩覚え書き

.NET Framework上の言語は、(基本的に)全機能が利用できる。
VB.NETも例外無く、C#などと同等の機能を保有している。
CLI(.NET中核)へ渡すMSIL(中間コード)を作っているにすぎない。
VisualStudio Express VB/C#/WebDevが無償公開されている。
実コーディングについては、ここが詳しい。
http://www.atmarkit.co.jp/fdotnet/vb6tonet2/index/index.html

VB6/VBAとの相違点
l    戻り値を利用するかしないかにかかわらず、引数を囲む“ ("と“) "が必要
l    .NET Framework クラスライブラリを利用することもできます
l    オブジェクト指向のサポート、コードの継承、オーバーロード、オーバーライド、コンストラクタ/デストラクタ
l    VB6コードを変換するアップグレードウィザードがある
l    従来よりも厳密なタイプチェック
l    例外処理が利用できる
l    マルチスレッドのアプリケーションや Windows サービスソフトの開発
l    オブジェクトが破棄されるタイミング、共通言語ランタイムでは、メモリが必要だと判断したとき
l    同じ DLL の異なるバージョンを管理することができる。レジストリ非依存
l    Option Explicit (変数宣言の強制)
l    変数のスコープ範囲は、ブロック内だけとなる
l    全ての変数がオブジェクト扱い、型無指定は、Object型へ
l    Currencyは廃止、Decimal型へ
l    数値型の表現範囲が、大きくなった。Short(16it)→Short(32bit)
l    デフォルトプロパティが無くなった。必ずプロパティを指定する必要がある。ただし、エディタが補完する
l    配列の始まりは、必ず0となる
l    固定長文字列型は無くなった
l    vb*のVB定数は廃止、.NETのものに変更
l    On?GoTo/GoSub、GoSub/Return、VarPtr、ObjPtr、StrPtr、LSet によるユーザー定義型変数の代入、DefBool、DefByte、DefInt、DefStr などは廃止される
l    VariantがObjectに、NullがNothingに
|    関数引数は、無指定時、値渡しbyValとなる。VB6は、byRef

●VB.NETでのGC/メモリ開放のタイミングは知りようがない
VB6とは違いnothingを入れても処理されない。
手動で開放する場合は、system.gc.collect()で処理可能

●オブジェクトの参照型と値型
ObjectとString型は常に参照型として扱われる
Structureは値型となる

●条件付ビルド
#If Debug Then
    Trace.WriteLine("Debug Build")
#Else
    Trace.WriteLine("Release Build")
#End If
#Constディレクティブ
定数には、#constか、プロパティのカスタム定数で定義できる

●強制的にGCしてみる
System.GC.Collect()

●参照カウント
型を明示化した場合、参照カウントは 1 になる。
型を明示化しない場合、参照カウントは 2 になる。←注意

●参照カウントを調べる方法
Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(sourceSheet)
MessageBox.Show("参照カウントの残り == " & iRemainCount.ToString())

●文字列比較の速さ
1.s1.Equals(s2)
2.String.Equals(s1, s2)
3.s1 == s2
内部的には、3は2、2は1を呼び出している。そのため、1が最も速い

●正規表現
VB netでも、Perlと同じような正規表現機能が利用できるようである。
*(?:)や(?<=)など、文内コメント、後方参照なども
Dim m As Match = Regex.Match("A.BC DEF", "(?<moji>[^ ]+)(?<space>[ ]*)")
(?<moji> ) というのがグループ化構成体で、括弧の中身をグループとして扱えるようになる

●正規表現 置換replace
Dim myString As String = RegEx.Replace( "a true taste of the temperature", "t.*?e", "a" )

using System.Text.RegularExpressions;
namespace RegularExpressions
{
    class RegularExpressions
    {
        [STAThread]
        static void Main(string[] args)
        {
            // 正規表現パターン
            string pattern = @"b(dim)s+(?<identifier>w+)s+(as)s+(?<type>[w.]+)b";
            // 検索された文字列に対して置き換えるパターン
            string replacement = "${type} ${identifier};";
            // Regexクラスのインスタンスを作成 (検索の際、大文字小文字を無視)
            Regex r = new Regex( pattern, RegexOptions.IgnoreCase );
            // 置き換えて結果を表示
            Console.WriteLine( r.Replace( "Dim i As Integer", replacement ) );
            Console.WriteLine( r.Replace( "Dim s As String", replacement ) );
            Console.WriteLine( r.Replace( "Dim ui As System.UInt32", replacement ) );
        }
    }
}

●デリゲートによる文字列置換
Sub Page_Load(sender as Object, e as EventArgs)
    Dim myDelegate As New MatchEvaluator( AddressOf MatchHandler )
    Dim sb As New System.Text.Stringbuilder()
    Dim bodyOfText As String = _
        "~~~ This %%% is ### a chunk of text."
    Dim pattern As String = "(w)(w+)?"
    Dim re As New Regex( _
        pattern, RegexOptions.Multiline Or _
        RegexOptions.IgnoreCase _
    )
    Dim newString As String = re.Replace(bodyOfText, myDelegate)
    Response.Write( bodyOfText & "<hr>" & newString )
End Sub

Private Function MatchHandler( ByVal m As Match ) As String
    Return m.Groups(1).Value.ToUpper() & m.Groups(2).Value
End Function

●Nullable型 nothingを扱う事をできるようにする
Dim i As Nullable(Of Integer) = Nothing
●ジェネリック
コンパイル中の型チェックを行う
例)
ArrayList list = new ArrayList();
List<string> list = new List<string>();
●分離クラス
Form1.Designer.vb/Form1.vbなど
クラス定義が分離されている。2005移行
●REGION "?"
畳みこむエディタにて利用
●コンストラクタはsub new()
●自分は、me
●NULL&空文字チェック
String.IsNullOrEmptyメソッド(String)
●Nothingチェック
checkString IsNot Nothing

●VB6のDebug.Printと同じ事を行うには?
System.Diagnostics.DebugクラスのWriteメソッド
System.Diagnostics.Debug.Indent()
System.Diagnostics.Debug.Unindent()
Trace.Write

●良くも悪くも例外が出まくる。→ちゃんと書く

●Excelオブジェクトを利用するには、
[プロジェクト][参照の追加][COM]にて、Microsoft Excel *.* Object Libraryを選択する。
完全名はこちら
Dim xlapp As Microsoft.Office.Interop.Excel.Application
面倒なら、Imports Microsoft.Office.Interopと先頭に書く

●excel::rangeオブジェクト メモ
.Value/.Address/.Row/.Column/ セル幅の指定 .RowHeight/.ColumnWidth
Resize()/Offset()
Width/height 半角一文字分サイズ取得
aa.Count         '選択範囲の個数
aa.Row           '先頭行の番号
aa.Rows.Count    '行数
aa.Column        '先頭列の番号
aa.Columns.Count '列数

●Excelの画面制御方法
再描画が抑えられるため高速に処理できます。
Application.ScreenUpdating = False
ActiveSheet.DisplayPageBreaks = False

●CSVの読込み
Using parser As New TextFieldParser(stCurrentDir & sCsvFile, System.Text.Encoding.GetEncoding("SHIFT_JIS"))
    parser.TextFieldType = FieldType.Delimited
    parser.HasFieldsEnclosedInQuotes = True
    parser.SetDelimiters(",")
    While Not parser.EndOfData
        'Trace.Write(parser.LineNumber & ">>>")
        Dim fields As String() = parser.ReadFields()
        'For Each field As String In fields
        'Trace.Write(field & "|")
        'Next
        'Trace.WriteLine("")
        _hData(fields(0)) = fields(1)
    End While
End Using

●ハッシュテーブルの列挙
For Each de As DictionaryEntry In ht
      Console.WriteLine("{0} : {1}", de.Key, de.Value)
    Next

●フォルダ (ディレクトリ) が存在しているかどうか確認
If System.IO.Directory.Exists("C:Hoge") = True Then
●ファイル が存在しているかどうか確認
If System.IO.File.Exists("C:Hoge") = True Then

●絶対パスか相対パスかを判断
If System.IO.Path.IsPathRooted("….Hoge.txt") = True Then

●親ディレクトリ名 (フォルダ名) を取得
Dim stParentName As String = System.IO.Path.GetDirectoryName("C:HogeFoo.txt")

●ファイルパスからファイル名を取得
Dim stFileName As String = System.IO.Path.GetFileName("C:Hoge.txt")

●連結したファイルパスを取得
Dim stFilePath As String = System.IO.Path.Combine("C:HogeFoo", "Bar.txt")

●フォルダの属性を取得
Dim uAttribute As System.IO.FileAttributes = System.IO.File.GetAttributes("C:Hoge")

●コメント・名前の削除(Excel)
Me.rangeTarget.ClearComments()
Dim objName As Name

For Each objName In ActiveWorkbook.Names
    objName.Delete()
Next objName

●インラインマシン語
Dynamically Writing and Executing Native Assembly in C#
.NET ver 2.0 ではインラインマシン語が使える

●デリゲート
デリゲートとは、他のオブジェクトのメソッドを間接的に呼び出すためのオブジェクト
Delegate Sub MyDelegate(ByVal x As String)

Dim MyDelegate As MyDelegate
MyDelegate.Invoke(Me.Name)

●名前でメソッドの呼び出し
dim objCls as new myClass
sRet = CallByName( objCls, "testFunc", CallType.Method, "3", "5")

●EVAL
Dim exp As String = "(1+6)*5/(7-4)"

Dim ve As Microsoft.JScript.Vsa.VsaEngine = _
    Microsoft.JScript.Vsa.VsaEngine.CreateEngine()
Dim result As Double = _
    CDbl(Microsoft.JScript.Eval.JScriptEvaluate(exp, ve))

'結果を表示
Console.WriteLine(result)

ごり初心者書式メモ
CaseSelect文
                Select Case st.Name
                    Case "項目1"
                        rangeName.Value = "123456789"
                    Case "項目2"
                        rangeName.Value = "987654321"
                 End Select
構造体
    Structure Datas
        Dim name As String
        Dim value As Decimal
    End Structure

ハッシュテーブル作成
    Dim _hData As Hashtable
        _hData = New Hashtable

¥パス指定(1個だけでいいらしい)
        sCsvFile = "c:test.csv"

ForEach文
        For Each st In xlApp.Names
        Next

●リソースの取得
'文字列リソースを取り出す
Dim str As String = My.Resources.Message
'画像リソースを取り出す
Dim bmp As Bitmap = My.Resources.Banner
'アイコンリソースを取り出す
Dim ico As
Icon = My.Resources.Icon1
'オーディオリソースを取り出す
Dim strm As System.IO.Stream = My.Resources.Voice1
'テキストファイルリソースを取り出す
Dim txt As String = My.Resources.TextFile1
'バイナリファイルリソースを取り出す
Dim bs As Byte() = My.Resources.BinaryFile

●DataSet
Dim OleConn As OleDb.OleDbConnection = New OleDb.OleDbConnection
Dim OleDA As OleDb.OleDbDataAdapter
Dim dtSet As DataSet = New DataSet("アドレステーブル")
OleConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source=C:WorkTest.mdb;Persist Security Info=False"
OleDA = New OleDb.OleDbDataAdapter("SELECT * FROM ADDRESS_TBL", OleConn)
OleDA.Fill(dtSet, "アドレステーブル")
DataGrid1.DataSource = dtSet.Tables(0)

●Datasetへのインデックス
DataView、UniqueKey、ForeignKey を追加することで DataTable のインデックス数が増えると、パフォーマンスの差ははるかに大きい
ds.Tables(0).Columns("ID").Unique = True

●インストールされているプリンタ
System.Drawing.Printing.PrinterSettings.InstalledPrinters.Count

●.NET で現在実行中のメソッド名を取得
System.Reflection.MethodBase.GetCurrentMethod().Name

●ミリ秒の取得
System.Environment.TickCount
※コールバック
System.Threading.Timer
System.Timers.Timer
System.Windows.Forms.Timer … 55ミリ秒の精度
※現在時間の場合は、DateTimeで。

●エラー時デバッグ情報
System.Diagnostics.Debug.Assert()
System.Diagnostics.Debug.Fail()
System.Diagnostics.Trace.Assert()

●Caseの部分は結構色々書ける
複数項目の場合(1 or 2 or 4)は
Case 1,2,4
範囲指定の場合(10以上15以下)は
Case 10 To 15
またそのあわせ技
Case 1,2,4, 10 To 15
比較演算子も使えたり(100以上)は
Case Is >= 100

●Office 2003から名前空間が変更になっているらしい
BuiltinDocumentPropertiesなど

●ZIPファイルを扱う
SharpZipLibというオープンソースがある。GPLで、クロースソースでも可となっている。
その他は、J#ライブラリを使う手もあるらしい。

●メソッド又はプロパティが存在するか?
IsNothing(sender.GetType.GetMethod("Focus"))
IsNothing(sender.GetType.GetProperty("BackColor"))
IsNothing(sender.GetType.GetMember("Enabled"))

●タスクコメントの書き方
TODO 標準 未実装のため、新たにコードを追加する必要がある個所。
HACK 標準 実装済みだが、コードをさらに改善する必要がある個所。
UNDONE 標準 未完成のため、さらにコードを編集する必要がある個所。

●ファイルを開くダイアログの表示
Dim ofd As New OpenFileDialog()
ofd.FileName = "default.html"
ofd.InitialDirectory = "C:"
ofd.Filter = _
    "HTMLファイル(*.html;*.htm)|*.html;*.htm|すべてのファイル(*.*)|*.*"
ofd.FilterIndex = 2
ofd.Title = "開くファイルを選択してください"
ofd.RestoreDirectory = True
ofd.CheckFileExists = True
ofd.CheckPathExists = True
ofd.ShowDialog() = DialogResult.OK

●例外が発生するとめっさ重い
ので、無理でも発生しないようにする

●死ぬほど速く大量のセルに値を書き込む
dim array(,)
range.value = array
※2次元配列である必要がある

●ContextSwitchDeadlock が検出されました。
COMをしばらく放置していると(60秒)、例外が発生する。
これはVBから発生しているものだが、オプションにて回避できる。
ソリューションプロパティからアンマネージコードデバッグをONにする。

●VB Report Excelプレビューのみ
        Me.vbRepoCtrl.FileName = "c:test.xls"
        Me.vbRepoCtrl.Start.File()
        'Me.vbRepoCtrl.Start.Create(VBReport.XlsReportCtrl.xlVersion.ver2002)
        Me.vbRepoCtrl.Page.Begin("Sheet1", "1")
        Me.vbRepoCtrl.Page.End()
        Me.vbRepoCtrl.Option.ViewZoom = VBReport.XlsReportCtrl.xlViewZoom.xzWidthFit
        Me.vbRepoCtrl.Out.PreView(0, 0, 1024, 768)

●遅延バインディング
VB.NETで遅延バインディング(実行時にオブジェクトのクラスを決めること)
を使うと、極端に遅くなる。VB.NETでは、遅延バインディングを禁止するために
「Option Strict」という設定があるので、これをOnにするのが好ましい。
デフォルトはOffであり、Offの状態だと相当遅くなる。

開発ざれごと

Posted by nabe