■閉鎖した昔のブログの記事復活
[2025/05/11] VB.NET:ADO.NET を使用した SQL-Server へのアクセス・クラス (No.388)
[2025/05/10] VB:NET:ArrayList と Hashtable の合体クラス (No.387)
[2025/05/10] 「更新プログラムをインストールしてシャットダウン」Windows7 更新プログラムのインストール中で終わらない (No.386)
[2025/05/10] FL-netのアクセスライブラリ「Binarix FL-net Library for Windows」の利用について (No.385)
[2025/05/10] 三菱「GT SoftGOT1000」用のアクセスDLL「GDevlib_GT16.dll」の利用について (No.384)
[2025/05/10] VB:NET:ArrayList と Hashtable の合体クラス (No.387)
[2025/05/10] 「更新プログラムをインストールしてシャットダウン」Windows7 更新プログラムのインストール中で終わらない (No.386)
[2025/05/10] FL-netのアクセスライブラリ「Binarix FL-net Library for Windows」の利用について (No.385)
[2025/05/10] 三菱「GT SoftGOT1000」用のアクセスDLL「GDevlib_GT16.dll」の利用について (No.384)
-
ADO.NET を使用した SQL-Server へのアクセス・クラスの簡単なものを作成してみました。
このクラスを元にして拡張したものを仕事でも使っています。
このクラス「clsSqlServer」には以下のメソッド・プロパティが備わっています。
メソッド・プロパティ 概要 New
コンストラクタ(引数にデータベース接続文字列を渡す) BeginTransaction
トランザクション開始 Commit
トランザクションコミット Rollback
トランザクションロールバック CloseConnection
コネクションの解除 OpenDataReader
SELECT文SQLの実行とDataReaderへの読込 CloseDataReader
DataReaderのクローズ ExeSQL
DML-SQL文の実行 CnvReaderToHashtable
DataReaderの結果ItemsをHashtableに変換
今回のクラスのテストプログラムを以下に載せますが、SQLサーバへの接続文字列は以下の様にしています。
キーワード 概要(設定値) Persist Security Info
ID やパスワードなどのセキュリティ関連情報の破棄指定(False) Integrated Security
現在のWindowsアカウントでの認証(SSPI) Database
データベース名(取敢えず「TEST」) Data Source
SQL Serverのインスタンスの名前
(Microsoft SQL Server Management Studio Express:.\SQLEXPRESS)
このテストは、システム日付をSELECTで実行し、SqlDataReaderに取得しています。SqlDataReaderから日付を取り出して その後、クラスのクローズを行っています。
■「clsSqlServer」の使用テストソース1
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click 'SQL-Server接続クラス生成 Dim DBConnection As String = "Persist Security Info=false;" & _ "Integrated Security=SSPI;Database=TEST;Data Source=.\SQLEXPRESS;" Dim CSQL = New clsSqlServer(DBConnection) 'TESTデータ取得クラス生成 Dim SQL As String = "SELECT GETDATE() AS SYSDATE" Dim Reader As System.Data.SqlClient.SqlDataReader = Nothing If CSQL.OpenDataReader(SQL, Reader) = True Then '読込 While Reader.Read() = True '読込が行われた場合,データをHashtableに格納 Dim ht As Hashtable = CSQL.CnvReaderToHashtable(Reader) MsgBox(ht("SYSDATE") & " : " & Reader.Item("SYSDATE")) End While End If 'クローズ CSQL.CloseConnection() End Sub
以下に、clsSqlServerの全体のソースを載せます。バグがあるかもしれませんが悪しからず。
■「clsSqlServer」のソース
Imports System.Data.SqlClient ''' ====================================================================== '''
''' SQLServer処理用クラス ''' ''' ====================================================================== Class clsSqlServer 'コネクションを共有変数で持つ Private _Conn As SqlConnection = Nothing 'トランザクションを共有変数で持つ Private _Trans As SqlTransaction = Nothing '接続文字列 Private _DBConnection As String '最後の実行SQL文および、エラーメッセージ Private _LastSQL As String = "" Private _LastErr As String = "" ' -------------------------------------------------------------------- ' プロパティ ' -------------------------------------------------------------------- ''' ------------------------------------------------------------------- '''最終実行SQL文 ''' ------------------------------------------------------------------- Public ReadOnly Property LastSQL() As String Get Return Me._LastSQL End Get End Property ''' ------------------------------------------------------------------- '''最終エラーメッセージ ''' ------------------------------------------------------------------- Public ReadOnly Property LastErr() As String Get Return Me._LastErr End Get End Property ''' ------------------------------------------------------------------- '''コンストラクタ '''データベース接続文字列 ''' ------------------------------------------------------------------- Public Sub New(ByVal DBConnection As String) 'データベース接続文字列の退避 Me._DBConnection = DBConnection End Sub ''' ------------------------------------------------------------------- '''''' トランザクション開始 ''' '''処理結果(true:OK, false:NG) ''' ------------------------------------------------------------------- Public Function BeginTransaction() As Boolean Try _Trans = _Conn.BeginTransaction(IsolationLevel.ReadCommitted) Return True Catch ex As Exception Me._LastErr = ex.ToString() _Trans = Nothing Return False End Try End Function ''' ------------------------------------------------------------------- '''''' トランザクションコミット ''' ''' ------------------------------------------------------------------- Public Sub Commit() Try If (_Trans IsNot Nothing) Then _Trans.Commit() _Trans = Nothing End If Catch ex As Exception Me._LastErr = ex.ToString() _Trans = Nothing End Try End Sub ''' ------------------------------------------------------------------- '''''' ロールバック ''' ''' ------------------------------------------------------------------- Public Sub Rollback() Try If (_Trans IsNot Nothing) Then _Trans.Rollback() _Trans = Nothing End If Catch ex As Exception Me._LastErr = ex.ToString() _Trans = Nothing End Try End Sub ''' ------------------------------------------------------------------- '''''' コネクションの解除 ''' ''' ------------------------------------------------------------------- Public Sub CloseConnection() Try If (_Conn IsNot Nothing) Then _Conn.Close() _Conn = Nothing End If Catch ex As Exception Me._LastErr = ex.ToString() _Conn = Nothing End Try End Sub ''' ------------------------------------------------------------------- '''''' SELECT文SQLの実行とDataReaderへの読込 ''' '''SELECT文SQL '''DataReaderへの参照 '''1行のみの読込指定(true:1行のみ, false:複数行) '''''' ------------------------------------------------------------------- Public Function OpenDataReader(ByVal strSQL As String, ByRef Reader As SqlDataReader, _ Optional ByVal fSingleRow As Boolean = False) As Boolean Dim functionReturnValue As Boolean = False Try '戻り値初期化 functionReturnValue = False 'DB接続処理 If _Conn Is Nothing Then '未接続の場合に接続する _Conn = New SqlConnection(Me._DBConnection) _Conn.Open() End If 'トランザクションの指定がされていればコマンドオブジェクトに関連付け Dim pCmd As SqlCommand = Nothing If (_Trans IsNot Nothing) Then pCmd = New SqlCommand(strSQL, _Conn, _Trans) Else pCmd = New SqlCommand(strSQL, _Conn) End If _LastSQL = strSQL 'SQL文の退避 '---読込オブジェクトに接続--- '強制的に1行のみ読込?? If fSingleRow = True Then Reader = pCmd.ExecuteReader(CommandBehavior.SingleRow) '行数の有無をチェック If Reader.HasRows Then If Reader.Read() Then '戻り値初期化 functionReturnValue = True End If End If Else '複数行の読込の場合はRead()関数はコールしない(この関数の外側でRead()すること) Reader = pCmd.ExecuteReader() '行数の有無をチェック If Reader.HasRows Then '戻り値初期化 functionReturnValue = True End If End If Catch ex As Exception 'エラーの退避 _LastErr = ex.Message '戻り値エラー functionReturnValue = False End Try Return functionReturnValue End Function ''' ------------------------------------------------------------------- ''' ''' DataReaderのクローズ ''' '''DataReaderへの参照 ''' ------------------------------------------------------------------- Public Sub CloseDataReader(ByRef Reader As SqlDataReader) Try If (Reader IsNot Nothing) Then Reader.Close() Reader = Nothing End If Catch Reader = Nothing End Try End Sub ''' ------------------------------------------------------------------- '''''' DML-SQL文の実行 ''' '''DML-SQL文 '''影響を受けた行数(-1:エラー戻り) ''' ------------------------------------------------------------------- Public Function ExeSQL(ByVal strSQL As String) As Integer Dim functionReturnValue As Integer = 0 Try '戻り値初期化 functionReturnValue = 0 'DB接続処理 If _Conn Is Nothing Then _Conn = New SqlConnection(Me._DBConnection) _Conn.Open() End If 'コマンドオブジェクト処理 Dim pCmd As New SqlCommand(strSQL, _Conn) 'SQL文の退避 _LastSQL = strSQL 'トランザクションの指定がされていればコマンドオブジェクトに関連付け If (_Trans IsNot Nothing) Then pCmd.Transaction = _Trans End If 'SQL実行 functionReturnValue = pCmd.ExecuteNonQuery() '戻り値は処理件数 'オブジェクトの廃棄 pCmd = Nothing Catch ex As Exception 'エラーの退避 _LastErr = ex.Message 'エラーNo取得 functionReturnValue = -1 End Try Return functionReturnValue End Function ''' ------------------------------------------------------------------- '''''' DataReaderの結果ItemsをHashtableに変換 ''' '''DataReader '''Hashtable ''' ------------------------------------------------------------------- Public Function CnvReaderToHashtable(ByVal Reader As SqlDataReader) As Hashtable 'HashTableの生成 Dim ht As New Hashtable() If Reader Is Nothing Then '引数チェックでNULLの場合 Return ht End If If Reader.IsClosed Then 'クローズされている場合 Return ht End If Try 'カラム名 Dim columnName As String = "" 'フィールド数の処理 For i As Integer = 0 To Reader.FieldCount - 1 'カラム名 columnName = Reader.GetName(i) 'HashTableへのReaderの内容Objectを追加 ht.Add(columnName, Reader.GetValue(i)) Next Catch Return ht End Try Return ht End Function End Class
=====
2015/03/18:の時の情報
PR -
VB.NETには「コレクション」としてのArrayList、Hashtable、SortedListなどの、各種のデータを配列の様に扱えるクラスが標準で備わっています。
クラス キー 指標 概要 ArrayList
× ○ 指標のみ扱いができる。(通常の配列の様である) Hashtable
○ × キーのみ扱いができる。 SortedList
○ ○ ArrayListとHashtableを合体した感じであるが、指標の扱いはキーでソートされた結果である。
クラス全体のソースは最後に載せますが、このクラスの使い方を先ずは見てください。
あるフォームにボタンを配置し、そのクリックでテストを行っています。
clsArrayHashに追加されるデータは文字列を使った簡単なもので、データの順次取得に、ForEachと指標を使った2つの方法を示しています。
■「clsArrayHash」の使用テストソース1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'ArrayHashクラスの生成 Dim clsList As New clsArrayHash '仮のデータを3件追加 clsList.Add("key1", "key1-contents") clsList.Add("key2", "key2-contents") clsList.Add("key3", "key3-contents") 'ArrayHashクラスから順次データを取得 Dim strSum As String = "" For Each str As String In clsList strSum &= str & " : " Next MsgBox(strSum) 'ArrayHashクラスから指標を用いて順次データを取得 strSum = "" For i = 0 To clsList.Count - 1 strSum &= clsList(i) & " : " Next MsgBox(strSum) 'ArrayHashクラスクリア clsList.Clear() clsList = Nothing End Sub
次に、更にフォームにボタンを配置し、そのクリックでテストを行っています。
clsArrayHashに追加されるデータはテスト的なクラスを使った簡単なもので、データの順次取得に、ForEachと指標を使った2つの方法を示しています。
■「clsArrayHash」の使用テストソース2
'テストクラス Private Class clsSub Public strData1 As String Public strData2 As String 'コンストラクタ Sub New(ByVal strData1 As String, ByVal strData2 As String) Me.strData1 = strData1 Me.strData2 = strData2 End Sub End Class Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click 'ArrayHashクラスの生成 Dim clsList As New clsArrayHash '仮のデータを3件追加 clsList.Add("key1", New clsSub("key1-Data1", "key1-Data2")) clsList.Add("key2", New clsSub("key2-Data1", "key2-Data2")) clsList.Add("key3", New clsSub("key3-Data1", "key3-Data2")) 'ArrayHashクラスから順次データを取得 Dim strSum As String = "" For Each cls As clsSub In clsList strSum &= cls.strData1 & "," & cls.strData2 & " : " Next MsgBox(strSum) 'ArrayHashクラスから指標を用いて順次データを取得 strSum = "" For i = 0 To clsList.Count - 1 Dim cls As clsSub = clsList(i) strSum &= cls.strData1 & "," & cls.strData2 & " : " Next MsgBox(strSum) 'ArrayHashクラスクリア clsList.Clear() clsList = Nothing End Sub
以下に、clsArrayHashの全体のソースを載せます。バグがあるかもしれませんが悪しからず。 ■「clsArrayHash」のソース
'''------------------------------------------------------------------------ '''
=====''' ArrayListとHashtableの合体クラス ''' ''''''------------------------------------------------------------------------ Public Class clsArrayHash Implements IEnumerable Private arrayList As ArrayList Private hashTable As Hashtable '''------------------------------------------------------------------------ ''' ''' コンストラクタ ''' '''------------------------------------------------------------------------ Sub New() Me.arrayList = New ArrayList Me.hashTable = New Hashtable End Sub '''------------------------------------------------------------------------ '''''' 指定したキーおよび値を持つ要素を ArrayHashに追加します。 ''' '''追加する要素のキー。 '''追加する要素の値。 '''value が追加された位置の ArrayHash インデックス。 '''------------------------------------------------------------------------ Public Function Add(ByVal key As String, ByVal value As Object) As Integer 'ArrayListへの追加位置 Dim listPos As Integer = -1 'ハッシュテーブルのキーの存在チェック If Me.hashTable.ContainsKey(key) = False Then 'ArrayListへの追加 listPos = Me.arrayList.Add(value) 'ハッシュテーブルへArrayListのIndexを追加 hashTable.Add(key, listPos) End If 'ArrayListへの追加位置を返す Return listPos End Function '''------------------------------------------------------------------------ '''''' 指定したキーに関連付けられている値を取得または設定します。 ''' '''値を取得または設定する対象のキー。 '''設定値 '''指定したキーに関連付けられている値。指定したキーが見つからない場合、Nothingが返ります。 '''------------------------------------------------------------------------ Default Public Property Item(ByVal key As String) As Object Get 'ハッシュテーブルのキーの存在チェック If Me.hashTable.ContainsKey(key) = True Then '存在した場合、ArrayListのIndex取得 Dim i As Integer = Me.hashTable(key) Return Me.arrayList(i) Else '存在しない場合、Nothingを返す Return Nothing End If End Get Set(ByVal value As Object) 'ハッシュテーブルのキーの存在チェック If Me.hashTable.ContainsKey(key) = True Then '存在した場合、ArrayListのIndex取得 Dim i As Integer = Me.hashTable(key) 'ArrayListへオブジェクトの設定 Me.arrayList(i) = value End If End Set End Property '''------------------------------------------------------------------------ '''''' 指定したインデックスにある要素を取得または設定します。 ''' '''取得または設定する要素の、0 から始まるインデックス番号。 '''設定する要素。 '''指定したインデックスにある要素。 '''------------------------------------------------------------------------ Default Public Property Item(ByVal idx As Integer) As Object Get If 0 <= idx And idx <= Me.arrayList.Count - 1 Then '指標の範囲が正常の場合、ArrayListの内容を返す Return Me.arrayList(idx) Else '指標の範囲がエラーの場合、Nothingを返す Return Nothing End If End Get Set(ByVal value As Object) If 0 <= idx And idx <= Me.arrayList.Count - 1 Then '指標の範囲が正常の場合、ArrayListへオブジェクトの設定 Me.arrayList(idx) = value End If End Set End Property '''------------------------------------------------------------------------ '''''' ArrayHash に実際に格納されている要素の数を取得します。 ''' '''ArrayHash に実際に格納されている要素の数 '''------------------------------------------------------------------------ Public ReadOnly Property Count() As Integer Get Return Me.arrayList.Count End Get End Property '''------------------------------------------------------------------------ '''''' ArrayHash からすべての要素を削除します。 ''' '''------------------------------------------------------------------------ Public Sub Clear() Me.arrayList.Clear() Me.hashTable.Clear() End Sub '''------------------------------------------------------------------------ '''''' ArrayHash に特定のキーが格納されているかどうかを判断します。 ''' '''ArrayHash 内で検索されるキー。 '''指定したキーを持つ要素が ArrayHash に格納されている場合は true。それ以外の場合は false。 '''------------------------------------------------------------------------ Public Function ContainsKey(ByVal key As String) As Boolean '内部のハッシュテーブルを利用 Return Me.hashTable.ContainsKey(key) End Function '''------------------------------------------------------------------------ '''''' IEnumerable.GetEnumerator()の実装 ''' ''''''------------------------------------------------------------------------ Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator 'arrayList型のGetEnumerator()を流用する Return Me.arrayList.GetEnumerator() End Function End Class
2015/03/16:の時の情報
-
昨日、PCをシャットダウン使用とした時に、「更新プログラムのインストール中(13個中8個目)」で更新処理が終わらなくなりました。
2時間以上「インストール中...」の表示で止まったままで、たまにHDDランプが点滅する感じでした。
この状況、Googleで検索すると結構いろんな方が遭遇した様で、解決方法は自己責任で強制終了しか無いようでした。
仕方ないので、HDDランプが点滅していない時を見計らって電源ボタンの長押しで電源をOFFし、 その後、しばらく待って電源を再起動を行いました。
「Windows更新プログラムの構成中」が表示されて無事に起動。
コンピュータの再構成などが行われて、ほどなくWindowsが立ち上がりログインの画面となりました。
更新プログラムの途中で強制終了していますので、残りの更新プログラムのインストールをする必要があります。
[スタート]ボタンをクリックし、[すべてのプログラム]-[Windows Update]をクリックします。
[Windows Update]画面が表示されるので、[更新プログラムのインストール]をクリックし
残りの更新プログラムを処理させます。残りは4個の更新プログラムでしたので、すぐに終わりました。
その後、PCの再起動を行い、問題無く動作しました。
今回、何も無く再起動できましたが、やはりハードディスクのバックアップは必要だと思います。
=====
2014/12/11:の時の情報
-
シーケンサとの通信を行う「FL-net」を使用する機会が数ヶ月前にありました。
この「FL-net」を使うことで、シーケンサとのプロトコルを意識せずメモリの読み書きで通信ができるものです。
私は知らなかったのですが、シーケンサ(PLC)とパソコン等とを接続し、その間でのデータの授受を行うために「FL-net」はよく用いられているそうです。
「FL-net」の特徴を以下に記します。
■パソコン側のインターフェイスはEthernetがそのまま利用できる。
■FL-netのネットワーク上には、最大254台の機器(ノード)を接続可能。
■各ノードはマスターレス方式で管理され、トークンバス方式でデータを交換する。
■全てのノードが共通認識しているメモリブロックであるコモンメモリが在る。
■コモンメモリは、ビット単位での扱いに適した「領域1(8192ビット分)」と、 ワード単位(16ビット単位)での扱いに適した「領域2(8192ワード分)」の2ブロックがある。
■コモンメモリの自分のノードのデータ領域の公開と、他のノードのデータ領域の参照が可能。
定期的に他のノードのデータを参照することで、それに対応する処理を行ったり、 自分のノードに他のノードへ伝えることを書き込んだりできることになります。
この「FL-net」を.NETから扱えるようにしたライブラリが「Binarix」から発売されています。 「Binarix FL-net Library for Windows」という製品で開発ライセンスフリーで動作させるパソコンには USBキーを装着することになります。(このUSBキーは60,000円)
http://www.binarix.co.jp/ja/products/flnet/
以下にコモンメモリの領域2を読み書きする簡単なテストプログラムを示します。
「Binarix」のサンプルプログラムで行っているように、FL-netをオープンした後でFL-netの 状態変化イベントでFL-netへの参加を検知する様にしています。
この組み方でほぼ動作すると思うのですが、実際にこの様にして数本のプログラムを組み1個のPC上で 同時に走らせた時に問題が発生しました。
実際のプログラムは5本同時に走らせたのですが、各プログラムでオープンした後で、 必ずしも全てのプログラムでオープン後の参加イベントが返ってくるわけではありませんでした。
「Binarix」の方に伺ったところ、イベントで見るのではなく、自ノードの状態を監視するのみでOKとのことでした。
結局ステータスイベントを使わずにオープン後のDo...WhileループをGetNodeInfo関数で監視すればよいことになります。
■「FL-net Library」の使用テストソース
Module Test '----- 'FL-net用の変数 '----- Private WithEvents m_flnet As FLnet 'FL-netコントロール Private m_blnParticipation As Boolean = False '参加フラグ Private m_flRet As FLResult 'FL-net関数戻り値 Private m_intAddr As Integer Private m_intData As Integer Private m_ushortArr(10) As UShort '''
■「FL-net参加を待つ」部分を改良したソース(抜粋)''' FL-netテスト用メインSub ''' Sub Main() 'FL-netインスタンス m_flnet = New Binarix.FALink.FLnet() 'FL-netオープン m_flRet = m_flnet.Open() If m_flRet = FLResult.OK Then MsgBox("Fl-net Open Error") Exit sub End If 'FL-net参加を待つ Do If m_blnParticipation = True Then Exit Do Threading.Thread.Sleep(100) While m_intAddr = 100 '1ワードの領域2のコモンメモリの読込(Address:100) m_flRet = m_flnet.ReadC2(m_intAddr, m_intData) If Not (m_flRet = FLResult.OK) Then MsgBox("Fl-net Open Error") End If '1ワードの領域2のコモンメモリの書込(Address:200) m_intAddr = 200 m_flRet = m_flnet.WriteC2(m_intAddr, m_intData) m_intAddr = 100 '10ワードの連続領域2のコモンメモリの読込(Address:100) m_flRet = m_flnet.ReadC2(m_intAddr, m_ushortArr) If Not (m_flRet = FLResult.OK) Then MsgBox("Fl-net Open Error") End If '10ワードの連続領域2のコモンメモリの書込(Address:200) m_intAddr = 200 m_flRet = m_flnet.WriteC2(m_intAddr, m_ushortArr) 'FL-netクローズ Dim result As FLResult = flnet1.Close() 'Display Close Result If result = FLResult.OK Then MsgBox("Close OK") Else MsgBox("Close Error:" & result.ToString()) End If End Sub '''''' FL-net状態変更通知イベントハンドラ ''' Private Sub flnet_StatusChanged(ByVal sender As System.Object, ByVal e As Binarix.FALink.FLStatusEventArgs) Handles m_flnet.StatusChanged 'GetNodeInfoメソッドを使用して自ノードの状態を調べます。 Dim nodeInfo As New FLNodeInfo If flnet1.GetNodeInfo(nodeInfo) = FLResult.OK Then Dim part As String If (nodeInfo.NodeStatus And FLNodeStatus.Participation) = FLNodeStatus.Participation Then '参加フラグON m_blnParticipation = True End If End If End Sub End Module
... ... '''
=====''' FL-netテスト用メインSub ''' Sub Main() 'FL-netインスタンス m_flnet = New Binarix.FALink.FLnet() 'FL-netオープン m_flRet = m_flnet.Open() If m_flRet = FLResult.OK Then MsgBox("Fl-net Open Error") Exit sub End If 'FL-net参加を待つ Do If m_flnet.GetNodeInfo(nodeInfo) = FLResult.OK Then Exit Do Threading.Thread.Sleep(100) While m_intAddr = 100 '1ワードの領域2のコモンメモリの読込(Address:100) m_flRet = m_flnet.ReadC2(m_intAddr, m_intData) If Not (m_flRet = FLResult.OK) Then MsgBox("Fl-net Open Error") End If ... ...
2014/10/06:の時の情報
-
最近の仕事で、三菱のシーケンサソフトである「GT SoftGOT1000」との通信を行うものがあり、 そのアクセス用のDLLとしての「GDevlib_GT16.dll」を使用しました。
「GT SoftGOT1000」と通信を行うために、「GT SoftGOT1000」がインストールされているパソコンに さらに今回開発のプログラムと同一ディレクトリに「GDevlib_GT16.dll」を設置しました。
「GDevlib_GT16.dll」を使うにあたって、三菱さんからはサンプルプログラムが提供されていますが VC++のソースしか無かったので、今回VB.NET用に書き換えました。
VB.NET用のソースは以下にありますので、よろしければお使い下さい。 但し、間違い等があるかもしれませんので、責任は負いかねますのでご了承下さい。
(「GDevlib_GT16.dll」利用するためのクラスとして「CDev.vb」の1個のファイルにしてあります。)
尚、「GDevlib_GT16.dll」を使っての開発は、三菱さんに伺ったところ「VisualStudios2012上での開発については、保証外となります」 とのことですので、VisualStudio2008で開発を行いました。
■「CDev.vb」クラスの使い方
大体以下の様な感じで使えますが、ErrLogはこの関数外で宣言したエラー出力用の関数です。
'[GT SoftGOT1000]内部デバイス操作クラス Private Device As GDev Private Sub TestSub() ' [GT SoftGOT1000]内部デバイス操作クラス作成 Device = New GDev() '----- '開始処理 '----- If Device.IsOpen() = False Then 'SoftGOT1000内部デバイス・オープン If Device.Open(1) = False Then 'オープンエラー ErrLog("GT SoftGOT1000 が開始されていません。 ") Exit Sub End If End If '===== 'SGT1000.exeの実行中確認 '===== Dim ArrProcess As Process() ArrProcess = Process.GetProcessesByName("SGT1000") If ArrProcess.Length <= 0 Then ErrLog("SoftGOT1000が動作していません。") Exit Sub End If '----- '読出 '----- 'デバイスNO Dim DevNum As UInt32 = 82 'デバイスNO:82から8個のWORD領域 '内部デバイス入力データ領域 Dim ArrDev(8 * 2 + 1) As UShort '8ワードの領域 Dim blnRet As Boolean blnRet = Device.Read(GDev.DeviceName.GD, DevNum, ArrDev) If blnRet = False Then ErrLog("読出エラー(" & DevNum.ToString & ")") Exit Sub End If '----- '書込 '----- 'デバイスNO Dim DevNumO As UInt32 = 400 'デバイスNO:400から8個のWORD領域 '内部デバイス出力データ領域 Dim ArrDevO(8 * 2 + 1) As UShort '8ワードの領域 blnRet = Device.Write(GDev.DeviceName.GD, DevNumO, ArrDevO) If blnRet = False Then ErrLog("書込エラー") Exit Sub End If 'SoftGOT1000内部デバイス・クローズ If Device.IsOpen() Then Device.Close() End If End Sub
■「CDev.vb」クラスのソース
Imports System Imports System.Text Imports System.Runtime.InteropServices Class GDev Private m_hMapFile As IntPtr Private m_ulMapPointer As UInt32 Private m_sGotNo As Int16 <DllImport("GDevlib_GT16.dll")> _ Private Shared Function GDev_OpenMapping(ByRef phMapFile As IntPtr, ByVal sGotNo As Int16) As UInt32 End Function <DllImport("GDevlib_GT16.dll")> _ Private Shared Sub GDev_CloseUnMapping(ByVal hMapFile As IntPtr, ByVal ulMapPointer As UInt32) End Sub <DllImport("GDevlib_GT16.dll")> _ Private Shared Function GDev_Read(ByVal ulMapPointer As UInt32, ByVal sDevNameID As Int16, ByVal lDevNum As Int32, ByRef pusDataTable As UInt16, ByVal lDataSize As Int32) As Int32 End Function <DllImport("GDevlib_GT16.dll")> _ Private Shared Function GDev_Write(ByVal ulMapPointer As UInt32, ByVal sDevNameID As Int16, ByVal lDevNum As Int32, ByRef pusDataTable As UInt16, ByVal lDataSize As Int32) As Int32 End Function Public Enum DeviceName GB GD GS End Enum Protected Overrides Sub Finalize() Try Close() Finally MyBase.Finalize() End Try End Sub ''' ----------------------------------------------------------------------- '''
=====''' オープン処理 ''' '''GOT-NO '''処理結果(True:OK, False:NG) '''''' ----------------------------------------------------------------------- Public Function Open(ByVal sGotNo As Int16) As Boolean If m_hMapFile = IntPtr.Zero Then Dim hMapFile As IntPtr m_ulMapPointer = GDev_OpenMapping(hMapFile, sGotNo) If m_ulMapPointer <> 0 Then m_hMapFile = hMapFile m_sGotNo = sGotNo Return True End If End If Return False End Function ''' ----------------------------------------------------------------------- ''' ''' オープン済チェック ''' '''チェック結果(True:OK, False:NG) '''''' ----------------------------------------------------------------------- Public Function IsOpen() As Boolean Return (m_hMapFile <> IntPtr.Zero) End Function ''' ----------------------------------------------------------------------- ''' ''' クローズ処理 ''' '''''' ----------------------------------------------------------------------- Public Sub Close() If m_hMapFile <> IntPtr.Zero Then GDev_CloseUnMapping(m_hMapFile, m_ulMapPointer) m_hMapFile = IntPtr.Zero m_sGotNo = 0 End If End Sub ''' ----------------------------------------------------------------------- ''' ''' デバイス名からID変換 ''' '''デバイス名 '''ID '''''' ----------------------------------------------------------------------- Private Function GetDevNameID(ByVal eDevName As DeviceName) As Int16 Select Case eDevName Case DeviceName.GB Return 0 Case DeviceName.GD Return 1 Case DeviceName.GS Return 2 End Select Return -1 End Function Private Function GetFlag(ByVal sVal As UInt16, ByVal iBit As Integer) As Boolean Dim iMask As Integer = 1 << iBit Return ((sVal And iMask) <> 0) End Function Private Function SetFlag(ByVal sVal As UInt16, ByVal iBit As Integer, ByVal bFlag As Boolean) As UInt16 Dim iMask As Integer = (1 << iBit) If bFlag Then Return CType(sVal Or iMask, UInt16) Else Return CType(sVal And Not iMask, UInt16) End If End Function ''' ----------------------------------------------------------------------- ''' ''' 単独データ読出し ''' '''デバイス名 '''デバイスNO '''返すデータ '''読出結果(True:OK, False:NG) '''''' ----------------------------------------------------------------------- Public Function Read(ByVal eDevName As DeviceName, ByVal lDevNum As Int32, ByRef DataVal As UInt16) As Boolean If m_hMapFile <> IntPtr.Zero Then Dim usValue As UInt16 = 0 Dim sDevNameID As Int16 = GetDevNameID(eDevName) If GDev_Read(m_ulMapPointer, sDevNameID, lDevNum, usValue, 1) = 0 Then If eDevName = DeviceName.GB Then If GetFlag(usValue, lDevNum Mod 16) Then DataVal = 1 Else DataVal = 0 End If Else DataVal = usValue End If Return True End If End If Return False End Function ''' ----------------------------------------------------------------------- ''' ''' 連続データ読出し ''' '''デバイス名 '''デバイスNO '''データ配列 '''読出結果(True:OK, False:NG) '''ビットデータは想定していない ''' ----------------------------------------------------------------------- Public Function Read(ByVal eDevName As DeviceName, ByVal lDevNum As Int32, ByRef DataTable() As UInt16) As Boolean If m_hMapFile <> IntPtr.Zero Then Dim sDevNameID As Int16 = GetDevNameID(eDevName) If GDev_Read(m_ulMapPointer, sDevNameID, lDevNum, DataTable(0), DataTable.Length) = 0 Then Return True End If End If Return False End Function ''' ----------------------------------------------------------------------- '''''' 単独データ書込み ''' '''デバイス名 '''デバイスNO '''データ値 '''''' 書込結果(True:OK, False:NG) ''' ----------------------------------------------------------------------- Public Function Write(ByVal eDevName As DeviceName, ByVal lDevNum As Int32, ByVal usValue As UInt16) As Boolean If m_hMapFile <> IntPtr.Zero Then Dim sDevNameID As Int16 = GetDevNameID(eDevName) If eDevName = DeviceName.GB Then Dim usTmpValue As UInt16 = 0 If GDev_Read(m_ulMapPointer, sDevNameID, lDevNum, usTmpValue, 1) = 0 Then usValue = SetFlag(usTmpValue, lDevNum Mod 16, (usValue <> 0)) End If End If If GDev_Write(m_ulMapPointer, sDevNameID, lDevNum, usValue, 1) = 0 Then Return True End If End If Return False End Function ''' ----------------------------------------------------------------------- '''''' 連続データ書込み ''' '''デバイス名 '''デバイスNO '''データ配列 '''書込結果(True:OK, False:NG) '''ビットデータは想定していない ''' ----------------------------------------------------------------------- Public Function Write(ByVal eDevName As DeviceName, ByVal lDevNum As Int32, ByRef DataTable() As UInt16) As Boolean If m_hMapFile <> IntPtr.Zero Then Dim sDevNameID As Int16 = GetDevNameID(eDevName) If GDev_Write(m_ulMapPointer, sDevNameID, lDevNum, DataTable(0), DataTable.Length) = 0 Then Return True End If End If Return False End Function Public Overrides Function ToString() As String Return String.Format("GT SoftGOT1000") End Function End Class
2014/09/03:の時の情報