-
今回はフォームの位置を画面上のどの位置に表示するかを行う処理になります。
フォーム位置設定の関数内では、Screen.PrimaryScreen.WorkingArea プロパティによりディスプレイの大きさを取得し 計算に使っています。この関数では Screen.PrimaryScreen を使っているので、ディスプレイが一台のみと想定しています。
尚、Screen.PrimaryScreen.WorkingArea プロパティにより、ディスプレイの作業領域が取得できますが、 作業領域とは、ディスプレイのデスクトップ領域からタスクバー、 ドッキングされたウィンドウ、およびドッキングされたツール バーを除いた部分のことをいいます。フォームの位置設定を行う関数と実行例
Public Class frmPosition 'フォーム位置宣言 Enum enmWindowPos Center = 0 '中央 TopLeft '左上 TopRight '右上 BottomLeft '左下 BottomRight '右下 End Enum ''' <summary> ''' フォームの位置設定 ''' </summary> ''' <param name="frmDes">対象のフォーム</param> ''' <param name="pos">位置</param> Private Sub SetWindowPosition(ByVal frmDes As Form, ByVal pos As enmWindowPos) With Screen.PrimaryScreen.WorkingArea Select Case pos Case enmWindowPos.Center '中央 frmDes.Left = (.Width / 2) - (frmDes.Width / 2) + .Left frmDes.Top = (.Height / 2) - (frmDes.Height / 2) + .Top Case enmWindowPos.TopLeft '左上 frmDes.Left = 0 frmDes.Top = 0 Case enmWindowPos.TopRight '右上 frmDes.Left = .Width - frmDes.Width frmDes.Top = 0 Case enmWindowPos.BottomLeft '左下 frmDes.Left = 0 frmDes.Top = .Height - frmDes.Height Case enmWindowPos.BottomRight '左下 frmDes.Left = .Width - frmDes.Width frmDes.Top = .Height - frmDes.Height End Select End With End Sub ''' <summary> ''' ボタンクリックイベント ''' </summary> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'チェックするラジオボタン Dim arrRdo As RadioButton() = {Me.rdoTopLeft, Me.rdoTopRight, Me.rdoCenter, Me.rdoBottomLeft, Me.rdoBottomRight} For Each rdo As RadioButton In arrRdo If rdo.Checked = True Then 'Tagより位置設定指示を取得 Dim enmPos As enmWindowPos = CType(rdo.Tag, enmWindowPos) 'ウインドウ設定 Call Me.SetWindowPosition(Me, enmPos) Exit For End If Next End Sub ''' <summary> ''' フォームロードイベント ''' </summary> Private Sub frmPosition_Load(sender As Object, e As EventArgs) Handles Me.Load 'ラジオボタンのTagにウインドウ位置Enum設定 Me.rdoTopLeft.Tag = enmWindowPos.TopLeft Me.rdoTopRight.Tag = enmWindowPos.TopRight Me.rdoCenter.Tag = enmWindowPos.Center Me.rdoBottomLeft.Tag = enmWindowPos.BottomLeft Me.rdoBottomRight.Tag = enmWindowPos.BottomRight End Sub End Classこのプログラムは、各ラジオボタンをチェックし、「フォーム位置設定」ボタンを押下することで、 自分自身のフォームの位置が移動します。
関連する記事
⇒フォームの位置設定を行う処理 :[Screen.PrimaryScreen.WorkingArea]
⇒フォームクラスにプロパティ宣言し外からアクセスする方法
⇒親フォームのコントロールを子フォームからアクセスする方法
⇒フォームが閉じるのをキャンセルする方法:[FormClosingEventArgs,Cancel]
⇒フォームの表示をモジュールのMain関数から行う(エントリポイントの変更)
⇒フォームがKeyDownなどのキーイベントを受取り、ファンクションキー処理をする
⇒最初のフォームActivatedイベントでの処理(1回のみしか処理しない様にする)
⇒初回のフォームActivatedイベント発生させるフォーム継承について
PR -
INIファイルは簡単にプログラムの動作パラメータなどを保存しておくには便利な機能です。 この機能をXMLファイルで出来る様にクラスを作成してみました。
INIファイルへの書込み、読み込みの様な関数を持ったクラスになります。 以下にそのクラスのソースを示します。XMLファイルをINIファイルの様に読み書きクラス
Imports System.Xml Imports System.Text Public Class ClsXmlIni Private XmlDoc As XmlDocument Private XmlFileName As String '''''' コンストラクタ ''' ''' <param name="strXmlFilePath">XMLファイル</param> Public Sub New(ByVal strXmlFilePath As String) Try '初期XMLファイル読込 Me.XmlFileName = strXmlFilePath Me.XmlDoc = New XmlDocument If System.IO.File.Exists(strXmlFilePath) = False Then 'XML宣言を設定する Dim xmlDecl As System.Xml.XmlDeclaration = XmlDoc.CreateXmlDeclaration("1.0", "Shift-JIS", Nothing) '作成したXML宣言をDOMドキュメントに追加します XmlDoc.AppendChild(xmlDecl) Else 'ファイルが存在した場合 XmlDoc.Load(strXmlFilePath) 'XMLファイルをロード End If Catch ex As Exception Throw ex End Try End Sub '''''' プロファイル文字列の取得 ''' ''' <param name="strAppName">アプリケーション文字列</param> ''' <param name="strKeyName">キー文字列</param> ''' <param name="strDefault">デフォルト文字列</param> ''' <returns>プロファイル文字列</returns> Public Function GetProfileString(ByVal strAppName As String, _ ByVal strKeyName As String, _ ByVal strDefault As String) As String '戻り値初期化 GetProfileString = strDefault Try '引数チェック If strAppName = "" Or strKeyName = "" Then Exit Function 'INIノードチェック Dim xeleIni As XmlElement = Me.XmlDoc.SelectSingleNode("INI") If Not xeleIni Is Nothing Then 'APPチェック Dim xeleApp As XmlElement = xeleIni.SelectSingleNode(strAppName) If Not xeleApp Is Nothing Then 'KEYチェック Dim xeleKey As XmlElement = xeleApp.SelectSingleNode(strKeyName) If Not xeleKey Is Nothing Then GetProfileString = xeleKey.InnerText End If End If End If Catch ex As Exception Throw ex End Try End Function '''''' プロファイル文字列設定 ''' ''' <param name="strAppName">アプリケーション文字列</param> ''' <param name="strKeyName">キー文字列</param> ''' <param name="strSet">設定文字列</param> ''' <returns>True:正常, False:エラー</returns> Public Function WriteProfileString(ByVal strAppName As String, _ ByVal strKeyName As String, _ ByVal strSet As String) As Boolean '戻り値初期化 WriteProfileString = False Try '引数チェック If strAppName = "" Or strKeyName = "" Then Exit Function 'INIノードチェック Dim xeleIni As XmlElement = Me.XmlDoc.SelectSingleNode("INI") If xeleIni Is Nothing Then xeleIni = Me.XmlDoc.CreateElement("INI") 'INI要素を作成 Call Me.XmlDoc.AppendChild(xeleIni) 'ドキュメントに追加 End If 'APPチェック Dim xeleApp As XmlElement = xeleIni.SelectSingleNode(strAppName) If xeleApp Is Nothing Then xeleApp = Me.XmlDoc.CreateElement(strAppName) 'APP要素を作成 Call xeleIni.AppendChild(xeleApp) 'INI要素に追加 End If 'KEYチェック Dim xeleKey As XmlElement = xeleApp.SelectSingleNode(strKeyName) If xeleKey Is Nothing Then xeleKey = Me.XmlDoc.CreateElement(strKeyName) 'KEY要素を作成 Dim xValKey As XmlText = Me.XmlDoc.CreateTextNode(strSet) '設定値を作成 Call xeleKey.AppendChild(xValKey) 'KEY要素に値を追加 Call xeleApp.AppendChild(xeleKey) 'APP要素に追加 Else 'KEYが存在 xeleKey.InnerText = strSet End If 'XMLファイルの上書き Me.XmlDoc.Save(Me.XmlFileName) Return True Catch ex As Exception Return False End Try End Function End Classこのクラスを利用する例を以下に記します。 フォーム(frmXmlIni)の上にボタンを貼り付け、このボタン処理内で、 最初にXMLファイルへの書込を行い、その後でそのXMLファイルからの読込を行っています。 その後さらに、書込と読込を行っています。
Public Class frmXmlIni Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Try 'XMLファイルのテスト Dim strPath As String = System.IO.Path.GetDirectoryName(Application.ExecutablePath) Dim Ini As New ClsXmlIni(strPath & "\TEST.XML") '書込テスト Ini.WriteProfileString("SECTION1", "DATA1", "aaa") Ini.WriteProfileString("SECTION1", "DATA2", "bbb") Ini.WriteProfileString("SECTION2", "DATA1", "AAA") '読込テスト Dim strDsp As String = "" strDsp &= "SECTION1:DATA1=" & Ini.GetProfileString("SECTION1", "DATA1", "***") & vbCrLf strDsp &= "SECTION1:DATA1=" & Ini.GetProfileString("SECTION1", "DATA2", "") & vbCrLf strDsp &= "SECTION1:DATA1=" & Ini.GetProfileString("SECTION2", "DATA1", "@@@") & vbCrLf MsgBox(strDsp) '書込テスト Ini.WriteProfileString("SECTION1", "DATA1", "111") Ini.WriteProfileString("SECTION1", "DATA2", "222") Ini.WriteProfileString("SECTION2", "DATA1", "333") '読込テスト strDsp = "" strDsp &= "SECTION1:DATA1=" & Ini.GetProfileString("SECTION1", "DATA1", "") & vbCrLf strDsp &= "SECTION1:DATA1=" & Ini.GetProfileString("SECTION1", "DATA2", "") & vbCrLf strDsp &= "SECTION1:DATA1=" & Ini.GetProfileString("SECTION2", "DATA1", "") & vbCrLf MsgBox(strDsp) Catch ex As Exception MsgBox(ex.Message) End Try End Sub End Classこの処理の後のXMLファイルの内容は以下の様になります。
<?xml version="1.0" encoding="Shift-JIS"?> <INI> <SECTION1> <DATA1>111</DATA1> <DATA2>222</DATA2> </SECTION1> <SECTION2> <DATA1>333</DATA1> </SECTION2> </INI>
-
INIファイルというと今更感がありますが、 簡単にプログラムの動作パラメータなどを保存しておくには便利な機能です。 私もプログラムの変更なしに、外からタイミングの時間の値を後から少し変えたい場合によく使います。
INIファイルの構造は以下の様になります。[SECTION1] KEY1=keydata1 KEY2=keydata2 [SECTION2] KEYA=keydataA ...
■セクション
[ ] で囲まれた部分がセクションで、各セクションの中にキー文字列を宣言します。
■キー
各セクションの中に宣言される文字列で、その値を = で定義します。
セクションが異なれば、同じキーが在ってもOKです。
■コメント
先頭に ;(セミコロン) を置くとその行はコメント行とみなされます。
また、行の途中に ;(セミコロン) が在ると、それ以降はコメントであるとみなされます。
■エスケープシーケンス
キーの値の文字列として ;(セミコロン) :(コロン) =(等号) #(シャープ) の各文字を含めたい場合があります。その時には各文字の前に \(円マーク) を置きエスケープしてやります。
(以下のソースのクラスではエスケープシーケンスの設定と解除を関数化しています)
以下にINIファイルを取り扱うクラスのソースを示します。INIファイル読み書きクラス
Imports System.Text Imports System.Runtime.InteropServices Public Class ClsIni 'プロファイル文字列取得 'Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" ( _ ' ByVal lpApplicationName As String, _ ' ByVal lpKeyName As String, _ ' ByVal lpDefault As String, _ ' ByVal lpReturnedString As System.Text.StringBuilder, _ ' ByVal nSize As UInt32, _ ' ByVal lpFileName As String) As UInt32 '宣言修正 Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" ( _ <MarshalAs(UnmanagedType.LPStr)> ByVal lpApplicationName As String, _ <MarshalAs(UnmanagedType.LPStr)> ByVal lpKeyName As String, _ <MarshalAs(UnmanagedType.LPStr)> ByVal lpDefault As String, _ <MarshalAs(UnmanagedType.LPStr)> ByVal lpReturnedString As StringBuilder, _ ByVal nSize As UInt32, _ <MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String) As UInt32 'プロファイル文字列書込み 'Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" ( _ ' ByVal lpAppName As String, _ ' ByVal lpKeyName As String, _ ' ByVal lpString As String, _ ' ByVal lpFileName As String) As Integer '宣言修正 Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" ( _ <MarshalAs(UnmanagedType.LPStr)> ByVal lpAppName As String, _ <MarshalAs(UnmanagedType.LPStr)> ByVal lpKeyName As String, _ <MarshalAs(UnmanagedType.LPStr)> ByVal lpString As String, _ <MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String) As Integer Private strIniFileName As String = "" '''''' コンストラクタ ''' ''' <param name="strIniFile">INIファイル名(フルパス)</param> Sub New(ByVal strIniFile As String) Me.strIniFileName = strIniFile 'ファイル名退避 End Sub '''''' プロファイル文字列取得 ''' ''' <param name="strAppName">アプリケーション文字列</param> ''' <param name="strKeyName">キー文字列</param> ''' <param name="strDefault">デフォルト文字列</param> '''プロファイル文字列 Public Function GetProfileString(ByVal strAppName As String, _ ByVal strKeyName As String, _ ByVal strDefault As String) As String Try Dim strWork As System.Text.StringBuilder = New System.Text.StringBuilder(1024) Dim intRet As Integer = GetPrivateProfileString(strAppName, strKeyName, strDefault, strWork, strWork.Capacity - 1, strIniFileName) If intRet > 0 Then 'エスケープ文字を解除して返す Return ResetEscape(strWork.ToString()) Else Return strDefault End If Catch ex As Exception Return strDefault End Try End Function '''''' プロファイル文字列設定 ''' ''' <param name="strAppName">アプリケーション文字列</param> ''' <param name="strKeyName">キー文字列</param> ''' <param name="strSet">設定文字列</param> '''True:正常, False:エラー Public Function WriteProfileString(ByVal strAppName As String, _ ByVal strKeyName As String, _ ByVal strSet As String) As Boolean Try 'エスケープ文字変換 Dim strCnv As String = SetEscape(strSet) Dim intRet As Integer = WritePrivateProfileString(strAppName, strKeyName, strCnv, strIniFileName) If intRet > 0 Then Return True Else Return False End If Catch ex As Exception Return False End Try End Function '''''' エスケープ文字変換 ''' ''' <param name="strSet">設定文字列</param> '''変換後文字列 Private Function SetEscape(ByVal strSet As String) As String Dim strEscape As String = ";#=:" Dim strRet As String = strSet Try For i = 0 To strEscape.Length - 1 Dim str As String = strEscape.Substring(i, 1) strRet = strRet.Replace(str, "\" & str) Next Return strRet Catch ex As Exception Return "" End Try End Function '''''' エスケープ文字解除 ''' ''' <param name="strSet">設定文字列</param> '''変換後文字列 Private Function ResetEscape(ByVal strSet As String) As String Dim strEscape As String = ";#=:" Dim strRet As String = strSet Try For i = 0 To strEscape.Length - 1 Dim str As String = strEscape.Substring(i, 1) strRet = strRet.Replace("\" & str, str) Next Return strRet Catch ex As Exception Return "" End Try End Function End Class
このクラスを利用する例を以下に記します。 このボタン処理内では、最初にINIファイルへの書き込みを行い、その後でそのINIファイルからの読込を行っています。
Private Sub ButtonIni_Click(sender As Object, e As EventArgs) Handles ButtonIni.Click '自分自身の存在するフォルダ Dim strPath As String = System.IO.Path.GetDirectoryName(Application.ExecutablePath) 'INIファイルクラスの生成 Dim Ini As New ClsIni(strPath & "\TEST.INI") 'INIファイルへの書込みテスト Ini.WriteProfileString("SECTION1", "DATA1", "test-data-1:aaa") Ini.WriteProfileString("SECTION1", "DATA2", "test-data-2;bbb") Ini.WriteProfileString("SECTION2", "DATA1", "TEST-DATA-1=:;#AAA") 'INIファイルからの取得テスト Dim str As String str = Ini.GetProfileString("SECTION1", "DATA1", "default-data-1:aaa") Console.WriteLine("SECTION1:DATA1=" & str) str = Ini.GetProfileString("SECTION1", "DATA2", "default-data-2;bbb") Console.WriteLine("SECTION1:DATA2=" & str) str = Ini.GetProfileString("SECTION2", "DATA1", "default-DATA-1=:;#AAA") Console.WriteLine("SECTION2:DATA1=" & str) str = Console.ReadLine() End SubINIファイルへの書込みでエスケープしないといけない文字を含んでいますので、 このプログラムを実行し「TEST.INI」をテキストエディタで確認すると、 \(円マーク) が付加されて書き込まれているのがわかるはずです。
関連する記事
⇒XMLファイルをINIファイルの様に扱う処理:[XmlDocument,XmlElement,CreateElement]
おすすめ本
-
文字列の2次元配列の内容をCSVファイルに全て書き込む関数を説明します。 CSVファイルに書込む方法は、比較的簡単で、指定されたカラムデータに「”」(ダブルクォート)を全て付加して書込めばできます。
書込みは「Shift-JIS」のEncodingを指定し、System.IO.StreamWriterでファイルを開き、 指定されたカラムデータを順次書き込んで処理します。
今回の関数では CSVファイルの読込について で読込まれたデータを書込むことを 前提にしていますので、書き込みデータは文字列の2次元配列で指定します。
この関数では、全てのカラムデータにダブルクォートで囲っていますが、ダブルクォートが必要なデータのみ囲みたい場合には 指定されたカラムデータ文字列がダブルクォートを必要としているかを検査して処理する必要があります。 文字列の中に、カンマ、タブ、CR、LFが含まれていたり、前後に空白が在ればダブルクォートを必要とします。CSVファイル書込処理
''' ----------------------------------------------------------------------------- '''''' CSVファイルの書込処理 ''' ''' <param name="astrFileName">ファイル名</param> ''' <param name="aarrData">書込データ文字列の2次元配列</param> '''True:結果OK, False:NG '''カラム名をファイルに出力したい場合は、書込データの先頭に設定すること ''' ----------------------------------------------------------------------------- Private Function WriteCsv(ByVal astrFileName As String, ByVal aarrData As String()()) As Boolean WriteCsv = False 'ファイルStreamWriter Dim sw As System.IO.StreamWriter = Nothing Try 'CSVファイル書込に使うEncoding Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS") '書き込むファイルを開く sw = New System.IO.StreamWriter(astrFileName, False, enc) For Each arrLine() As String In aarrData Dim blnFirst As Boolean = True Dim strLIne As String = "" For Each str As String In arrLine If blnFirst = False Then '「,」(カンマ)の書込 sw.Write(",") End If blnFirst = False '1カラムデータの書込 str = """" & str & """" sw.Write(str) Next '改行の書込 sw.Write(vbCrLf) Next '正常終了 Return True Catch ex As Exception 'エラー MsgBox(ex.Message) Finally '閉じる If sw IsNot Nothing Then sw.Close() End If End Try End Function '仮にテストプログラム Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Try 'CSVファイル読込処理 Dim arrCsv()() As String = ReadCsv("test.csv", False, False) 'CSVファイル書込処理 Dim blnRet As Boolean = WriteCsv("testw.csv", arrCsv) Catch ex As Exception MsgBox(ex.Message) End Try End Sub関連する記事
⇒CSVファイルの読込について :[Microsoft.VisualBasic.FileIO.TextFieldParser]
⇒CSVファイルの DataGridView への読込について
⇒DataGridView からCSVファイルへの書込について
-
CSVファイルを全て読み込み、文字列の2次元配列に戻す関数を説明します。 CSVファイルを読み込むには、Microsoft.VisualBasic.FileIO.TextFieldParserクラスを使用すると割と簡単に処理すことができます。
CSVファイル名を指定し、TextFieldParserクラスのインスタンスを作成し、 さらに区切りの指定及びフィールドが引用符で囲まれているかの指定を行います。
実際のファイルの読込は、1行ずつをReadFields()関数で行います。結果は文字列配列に返りますのでそれを適切に処理してやります。 読込のループの先頭でEndOfDataプロパティをチェックし、これがTrueであれば読込が最後まで来ています。 ループを抜けてファイルを閉じてやればOKです。
関数の戻り値として、文字列の2次元配列にしていますので呼び出し側の処理の例を載せておきます。CSVファイル読込処理
''' ----------------------------------------------------------------------------- '''''' CSVファイルの読込処理 ''' ''' <param name="astrFileName">ファイル名</param> ''' <param name="ablnTab">区切りの指定(True:タブ区切り, False:カンマ区切り)</param> ''' <param name="ablnQuote">引用符フラグ(True:引用符で囲まれている, False:囲まれていない)</param> '''読込結果の文字列の2次元配列 ''' ----------------------------------------------------------------------------- Private Function ReadCsv(ByVal astrFileName As String, ByVal ablnTab As Boolean, ByVal ablnQuote As Boolean) As String()() ReadCsv = Nothing 'ファイルStreamReader Dim parser As Microsoft.VisualBasic.FileIO.TextFieldParser = Nothing Try 'Shift-JISエンコードで変換できない場合は「?」文字の設定 Dim encFallBack As System.Text.DecoderReplacementFallback = New System.Text.DecoderReplacementFallback("?") Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("shift_jis", System.Text.EncoderFallback.ReplacementFallback, encFallBack) 'TextFieldParserクラス parser = New Microsoft.VisualBasic.FileIO.TextFieldParser(astrFileName, enc) '区切りの指定 parser.TextFieldType = FieldType.Delimited If ablnTab = False Then 'カンマ区切り parser.SetDelimiters(",") Else 'タブ区切り parser.SetDelimiters(vbTab) End If If ablnQuote = True Then 'フィールドが引用符で囲まれているか parser.HasFieldsEnclosedInQuotes = True End If 'フィールドの空白トリム設定 parser.TrimWhiteSpace = False Dim strArr()() As String = Nothing Dim nLine As Integer = 0 'ファイルの終端までループ While Not parser.EndOfData 'フィールドを読込 Dim strDataArr As String() = parser.ReadFields() '戻り値領域の拡張 ReDim Preserve strArr(nLine) '退避 strArr(nLine) = strDataArr nLine += 1 End While '正常終了 Return strArr Catch ex As Exception 'エラー MsgBox(ex.Message) Finally '閉じる If parser IsNot Nothing Then parser.Close() End If End Try End Function '仮にテストプログラム Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Try Dim arrCsv()() As String = ReadCsv("test.csv", False, False) Dim strData As String = "" For Each arr() As String In arrCsv For Each str As String In arr strData &= str & "," Next strData &= vbCrLf Next MsgBox(strData) Catch ex As Exception MsgBox(ex.Message) End Try End Sub
関連する記事
⇒CSVファイルの書込について :[System.IO.StreamWriter]
⇒CSVファイルの DataGridView への読込について
⇒DataGridView からCSVファイルへの書込について