[2020/03/25] 数値データを指定書式で文字列に変換する(ToString , String.Format) (No.157)
[2019/12/09] TCP (TcpListener, TcpClient)を使ったプロセス間通信について・その2 (No.146)
[2019/12/07] TCP (TcpListener, TcpClient)を使ったプロセス間通信について (No.145)
[2019/11/25] 文字列定数(改行、タブ、バックスペース等)について (No.143)
[2019/11/22] 文字列変換関数(StrConv)の使い方 (No.142)
-
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
-
数値データを表示するために各種の書式の文字列に変換することはよくあります。 各データ型が持つ ToString メソッドを使えば以下の様な感じでできます。
Console.WriteLine((12345).ToString("C")) '¥12,345 と表示 Console.WriteLine((12345).ToString("D8")) '00012345 と表示 Console.WriteLine((1234.567).ToString("00000.00")) '01234.57 と表示
上の (12345) の部分は文字列 "12345" を Integer型 データとして変換されます。 また (1234.567) の部分は文字列 "1234.567" を Double型 データとして変換され、それぞれの ToString メソッドが呼ばれます。
ToString メソッドの引数の文字列には各種存在し、 「標準の数値書式指定文字列」と「カスタム数値書式指定文字列」の2種類があります ので、順を追って説明します。■「標準の数値書式指定文字列」について
次の表に、標準の数値書式指定文字列の説明および書式指定子ごとのサンプル出力を示します。書式指定子 名称 対象データ型 結果 精度指定子 サンプル "C" or
"c"通貨型 全ての数値型 通貨値 小数部の桁数 (123.456).ToString("C") = ¥123
(-123.456).ToString("C3") = -¥123.456"D" or
"d"Decimal 整数型のみ 必要に応じて
負の符号が付く整数と小数最小桁数 (1234).ToString("D") = 1234
(-1234).ToString("D6") = -001234"E" or
"e"指数 全ての数値型 指数表記 小数部の桁数 (123.456).ToString("E") = 1.234560E+002
(0.12345).ToString("e3") = 1.235e-001"F" or
"f"固定小数点 全ての数値型 必要に応じて
負の符号が付く整数と小数小数部の桁数 (1234.567).ToString("F") = 1234.57
(1234).ToString("F1") = 1234.0
(-1234.56).ToString("F3") = -1234.560"G" or
"g"全般 全ての数値型 固定小数点表記or
指数表記の何れか簡潔な形式有効桁数 (-123.456).ToString("G") = -123.456
(123.4546).ToString("G4") = 123.5
(-1.23456E-25).ToString("G") = -1.23456E-25"P" or
"p"パーセント 全ての数値型 数値に 100 を掛けて
%記号を付けて表示小数部の桁数 (1).ToString("P") = 100.00 %
(-0.39678).ToString("P1") = -39.7 %"X" or
"x"16進数 整数型のみ 16進数文字列 結果文字列の桁数 (255).ToString("X") = FF
(-1).ToString("X") = FFFFFFFF
(255).ToString("x4") = 00ff
(1000).ToString("X4") = 03E8
書式指定子は上記の様にたくさんありますが、実際に使ったものとなると "C" と "D" ぐらいです。 指数表記は科学計算で必要になるぐらいで、私はあまり使った記憶がありません。
尚、以下のソースで簡単な例を示します。Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click '「Double」型データ Dim dbTest As Double = 0.0 '「Long」型データ Dim lngTest As Long = 0 '標準の数値書式指定文字列「C,c」 Console.WriteLine("標準の数値書式指定文字列「C,c」") dbTest = 123 Console.WriteLine(dbTest.ToString("C")) dbTest = 123.56 Console.WriteLine(dbTest.ToString("C")) dbTest = 123.456 Console.WriteLine(dbTest.ToString("C2")) dbTest = -123.56 Console.WriteLine(dbTest.ToString("C")) '標準の数値書式指定文字列「D,d」 Console.WriteLine("標準の数値書式指定文字列「D,d」") lngTest = 123 Console.WriteLine(lngTest.ToString("D")) Console.WriteLine(lngTest.ToString("D5")) lngTest = -123 Console.WriteLine(lngTest.ToString("D6")) End Sub
実行結果がコンソールには以下様に表示されます。
標準の数値書式指定文字列「C,c」 \123 \124 \123.46 -\124 標準の数値書式指定文字列「D,d」 123 00123 -000123
■「カスタム数値書式指定文字列」について
次の表に、カスタム数値書式指定文字列の説明および書式指定子ごとのサンプル出力を示します。 (よく使うものをピックアップしてあります)書式指定子 名称 説明 サンプル "0" ゼロ
プレース
ホルダー対応する数字でゼロを置き換えます。
置き換えが行われるのは対応する数字が存在する場合です。
それ以外の場合は結果の文字列にはゼロが表示されます。(1234).ToString("00000") = "01234"
(-1.23).ToString("000.000") = "-001.230"
(123.456).ToString("00.00") = "123.46""#" 桁
プレース
ホルダー対応する数字で "#" 記号を置き換えます。
置き換えが行われるのは対応する数字が存在する場合です。
それ以外の場合は結果の文字列に数字は表示されません。(1234).ToString("00000") = "01234"
(-1.23).ToString("000.000") = "-001.230"
(123.456).ToString("00.00") = "123.46""." 小数点 結果の文字列の小数点位置を決定します。 (123.45).ToString("0.0") = "123.5"
(-1.2).ToString("00.00") = "-01.20""," 桁区切り
数値位取り(0 または #) の間に1つ以上の "," が在る場合は
桁区切り記号が挿入。
数値位取りとしては
指定された "," ごとに数値を 1000 で除算します。(123456).ToString("#,0") = "123,456"
(1678).ToString("0,") = "2"
(123456789).ToString("0,,") = "123"";" セクション
区切り正、負、ゼロの数値に対して
別々の書式指定文字列でセクションを定義します。
2セクション:
・最初のセクションが正の値とゼロに適用
・2番目のセクションが負の値に適用
3セクション:
・最初のセクションが正の値に適用
・2番目のセクションが負の値に適用
・3番目のセクションがゼロに適用(12.345).ToString("#0.0#;(#0.0#);-\0-") = "12.35"
(0).ToString("#0.0#;(#0.0#);-\0-") = "-0-"
(-12.345).ToString("#0.0#;(#0.0#);-\0-") = "(12.35)""%" パーセント
プレース
ホルダー数値に 100 を乗算し結果の文字列に
パーセント記号を挿入します。(0.3697).ToString("%#0.00") = %36.97 '文字列' リテラル
文字列
区切り囲まれた文字列が結果の文字列に
そのまま出力される。(0.3697).ToString("'P:'%#0.00") = P:%36.97
尚、上記の例を以下のソースで示します。Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click '「Double」型データ Dim dbTest As Double 'カスタム数値書式指定文字列["0"] Console.WriteLine("カスタム数値書式指定文字列[""0""]") dbTest = 123 Console.WriteLine(dbTest.ToString("00000")) dbTest = 123.456 Console.WriteLine(dbTest.ToString("00000.00")) dbTest = -123.56 Console.WriteLine(dbTest.ToString("00000.00")) 'カスタム数値書式指定文字列["#"] Console.WriteLine("カスタム数値書式指定文字列[""#""]") dbTest = 123 Console.WriteLine(dbTest.ToString("#####")) dbTest = 123.456 Console.WriteLine(dbTest.ToString("#####.##")) dbTest = -123.56 Console.WriteLine(dbTest.ToString("#####.##")) 'カスタム数値書式指定文字列[";"] Console.WriteLine("カスタム数値書式指定文字列["";""]") dbTest = 123 Console.WriteLine(dbTest.ToString("#####;[#####];'ZERO'")) dbTest = 0 Console.WriteLine(dbTest.ToString("#####;[#####];'ZERO'")) dbTest = -123.56 Console.WriteLine(dbTest.ToString("#####.##;[#####.##];'ZERO'")) '最後に複合的な使い方 Console.WriteLine("最後に複合的な使い方") dbTest = 12345678.123 Console.WriteLine(dbTest.ToString("'テストデータ:'#,0.00")) End Sub
実行結果がコンソールには以下様に表示されます。
セクション区切りを使用して1個の書式文字列で、正、負、ゼロで別々の書式が指定できますので、 数値を判断して個別に処理を分けなくてもよくなります。
カスタム数値書式指定文字列["0"] 00123 00123.46 -00123.56 カスタム数値書式指定文字列["#"] 123 123.46 -123.56 カスタム数値書式指定文字列[";"] 123 ZERO [123.56] 最後に複合的な使い方 テストデータ:12,345,678.12
■「複合書式指定文字列」について
複合書式指定文字列とは、出力される固定文字列の中に挿入されるべきデータ用のプレースホルダーを記入したものです。 このプレースホルダーはインデックス化されていて、「0」から順に番号が振られます。
この複合書式指定文字列を引数として使えるメソッドに String.Format や Console.WriteLine などがあります。 複合書式指定文字列の引数の後ろに、プレースホルダーに対応する出力したいデータを記述します。
この説明ではよく分からないので、以下の例を見てください。
{ } で囲まれた数字がインデックスで、対応するデータの引数の位置を示しているのが分かります。Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click Dim intData As Integer = 10 Dim lngData As Long = 1000 Dim dblData As Double = 123.45 Console.WriteLine("Integer:{0}, Long:{1}, Double:{2}", intData, lngData, dblData) End Sub
実行結果がコンソールには以下様に表示されます。
Integer:10, Long:1000, Double:123.45
尚、プレースホルダーの書式は以下の様になっています。
<プレースホルダー書式> { index [,alignment] [:formatString] } ・index:パラメーター指定子とも呼ばれ、 オブジェクトのリスト内で対応する項目を識別するための 0 から始まる数値です。 ・[,alignment]:書式設定フィールドの幅を指定する符号付き整数です。 フィールド内の書式設定されたデータは、alignment が正の場合は右揃え、 alignment が負の場合は左揃えされます。 埋め込みが必要な場合は、空白が使用されます。 ・[:formatString]:書式設定されるオブジェクトの種類に適した書式指定文字列です。 「標準の数値書式指定文字列」「カスタム数値形式文字列」が指定できます。
プレースホルダーの書式にいろいろ付け加えて、上記のソースを以下の様にしました。Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click Dim intData As Integer = 10 Dim lngData As Long = 1000 Dim dblData As Double = 123.45 Console.WriteLine("Integer:{0,7:0.00}, Long:{1,-6:#,0}, Double:{2,10:###0.000}", _ intData, lngData, dblData) End Sub
実行結果がコンソールには以下様に表示されます。
Integer: 10.00, Long:1,000 , Double: 123.450
関連する記事
⇒指定した精度の桁数に数値を切り上げ :[Math.Ceiling,Math.Floor]
⇒文字列から数値型への変換(parse - tryparse)
⇒オブジェクト型から数値型への変換(TryParse)
PR -
前回の TCP の記事では、クライアント側で1回の通信毎に TCP の接続を切断していたので、 複数回の文字列送信ができませんでした。
それで今回は、クライアント側で TCP の接続のタイミングと、文字列送信のタイミングを別々で行う様にすることで 複数回の文字列送信を可能にしています。
これを行う為に、以下のクライアント側の処理手順の中で、(1)(2)を1個の処理として、また(5)の処理も別のタイミングに追い出します。 具体的にはそれぞれフォームにボタンを設置(「Start」「Stop」の名前で)し、それぞれのクリック処理内でそれらを行います。- (1)IP アドレスとポート番号で TcpClient クラスの生成によりTCPソケット作成・接続
- (2)TcpClient クラスの GetStream メソッドで NetworkStream を取得
- (3)NetworkStream の Write メソッドでテキストボックスの内容をバイト配列化して送信
- (4)NetworkStream の Read メソッドでサーバからの応答を受信しテキストボックスに表示
- (5)最後にネットワークストリーム、ソケットをクローズ
それでは以下にクライアント側のソースを示します。 TcpClient と NetworkStream クラスのオブジェクトを関数の外に出し、静的変数としています。
■TCP クライアント側のプログラム
Imports System.Net Imports System.Text Public Class frmTcpClient 'サーバーのIPアドレス(または、ホスト名)とポート番号 Dim strIpAddr As String = "localhost" Dim intPort As Integer = 60000 'ソケット Dim mTcpClient As Sockets.TcpClient 'ソケットストリーム Dim mNetStream As Sockets.NetworkStream '[Start]リック時イベント Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click 'ソケット生成 mTcpClient = New Sockets.TcpClient 'ソケット接続 mTcpClient.Connect(strIpAddr, intPort) 'ソケットストリーム取得 mNetStream = mTcpClient.GetStream() End Sub '[Stop]リック時イベント Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click 'ソケットクローズ mNetStream.Close() mTcpClient.Close() End Sub '[Send]リック時イベント Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click Try '送信文字列をバイト配列変換 Dim enc As Encoding = Encoding.GetEncoding("SHIFT-JIS") '最後尾にCR Dim data As Byte() = enc.GetBytes(Me.TextBox1.Text.Trim & ControlChars.Cr) Me.TextBox1.Text = "" 'ソケット送信 mNetStream.Write(data, 0, data.Count) 'サーバからの応答を受信 Dim bytRead As Byte() = New Byte(255) {} Dim intBytes As Integer = mNetStream.Read(bytRead, 0, bytRead.Length) '受信したデータを文字列に変換 Dim resMsg As String = enc.GetString(bytRead, 0, intBytes) '末尾の\rを削除し表示 Me.TextBox2.Text = resMsg.TrimEnd(ControlChars.Cr) Catch ex As Exception MsgBox(ex.Message) End Try End Sub End Class
サーバ側のプログラムに変更は無いのですが、一応ソースを載せておきます。
■TCP サーバ側のプログラム
Imports System.Net Imports System.Threading Imports System.Text Public Class frmTcpServer 'リッチテキストボックスにメッセージを表示する Public Sub DispMsg(ByVal message As String) RichTextBox1.AppendText(message & vbNewLine) RichTextBox1.SelectionStart = RichTextBox1.TextLength RichTextBox1.Refresh() End Sub '[Start]ボタンクリック Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click 'ボタン制御 Me.btnStart.Enabled = False 'ポート番号 Dim pintPort As Integer = 60000 'IPアドレス&ポート番号設定 Dim pEndPoint As New IPEndPoint(IPAddress.Any, pintPort) 'ソケット・リスナー作成 Dim pListener As New Sockets.TcpListener(pEndPoint) 'リスナー開始 pListener.Start() Call DispMsg("リスナー開始...") 'クライアントから接続有りでこの処理を抜ける Dim pTcpClient As Sockets.TcpClient = pListener.AcceptTcpClient() Call DispMsg("クライアントから接続有り...") '送受信用ソケットストリーム取得 Dim pNetStream As Sockets.NetworkStream = pTcpClient.GetStream() 'バイト配列(取敢えず受信バッファとして256バイト) Dim bytRead As Byte() = New Byte(255) {} 'ソケット受送信ループ While True 'TCP受信(バッファ領域まで) Dim intBytes As Integer = pNetStream.Read(bytRead, 0, bytRead.Count) If intBytes = 0 Then Exit While End If '受信したデータを文字列に変換 Dim enc As Encoding = Encoding.GetEncoding("SHIFT-JIS") Dim resMsg As String = enc.GetString(bytRead, 0, intBytes) '末尾の\rを削除 resMsg = resMsg.TrimEnd(ControlChars.Cr) '表示 Call DispMsg(resMsg) '正常受信の場合、送信データ作成 Dim bytSend() As Byte = enc.GetBytes(resMsg & "...ACK" & ControlChars.Cr) 'ソケット送信 pNetStream.Write(bytSend, 0, bytSend.Length) End While 'ソケットストリームクローズ pNetStream.Close() 'クライアントクローズ pTcpClient.Close() 'リスナー停止 pListener.Stop() Call DispMsg("リスナー停止...") 'ボタン制御 Me.btnStart.Enabled = True End Sub End Class
実際の実行は以下の様になります。
サーバ側の「Start」押下後、クライアント側の「Start」を押下し”abcdef”,”123456”,”ABCDEFGHI”の順に文字列を「Send」し、 更に「Stop」を押下したところまでを表しています。
ここまでのPGはサーバとクライアントが1対1のみでしか動作しません。 しかし、これでは面白くありませんので、次回は複数のクライアントからの接続を受け付けるものを紹介したいと思います。関連する記事
⇒TCP (TcpListener, TcpClient)を使ったプロセス間通信について
⇒Remoting の IPC を使ったプロセス間通信について
⇒Remoting の IPC を使ったプロセス間通信についてその2(HTTPチャネル)
⇒名前付きパイプを使ったプロセス間通信について
⇒名前付きパイプを使ったプロセス間通信についてその2(複数クライアントとの通信)
⇒名前付きパイプを使ったプロセス間通信についてその3(クライアントとの双方向通信)
-
このページでは TCP を使ったプロセス(EXE)間で通信について説明します。 (いわゆる TCP クライアント・サーバプログラム を作ることになります。)
TCP クライアントは TcpClient クラスを、 TCP サーバは TcpListener クラスを使います。
そこで先ずは TCP サーバのプログラムの例を示します。 今回の処理は TCP での受信待ち状態にし、クライアントからの1回のメッセージを受信し、 そのメッセージをクライアント側に返し、処理が終わるという簡単なものです。 以下にその手順を示します。- IP アドレスとポート番号でネットワークエンドポイントを作成し TcpListener クラスの生成
- TcpListener クラスの Start メソッドで受信接続要求の待機を開始
- TcpListener クラスの AcceptTcpClient メソッドでクライアントからの接続要求を待機
- 接続要求待機を抜けた後で送受信用ソケットストリーム取得
- ソケットストリームからデータ受信し、さらにデータを送信
- 最後にソケットストリーム等をクローズし、リスナーを停止
以下にそのソースを示します。 フォーム上にはサーバ開始用の「start」ボタンと、送受信文字列等を表示する為に RichTextBox を設置しています。
■TCP サーバープログラム
Imports System.Net Imports System.Threading Imports System.Text Public Class frmTcpServer 'リッチテキストボックスにメッセージを表示する Public Sub DispMsg(ByVal message As String) RichTextBox1.AppendText(message & vbNewLine) RichTextBox1.SelectionStart = RichTextBox1.TextLength RichTextBox1.Refresh() End Sub '[Start]ボタンクリック Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click 'ボタン制御 Me.btnStart.Enabled = False 'ポート番号 Dim pintPort As Integer = 60000 'IPアドレス&ポート番号設定 Dim pEndPoint As New IPEndPoint(IPAddress.Any, pintPort) 'ソケット・リスナー作成 Dim pListener As New Sockets.TcpListener(pEndPoint) 'リスナー開始 pListener.Start() Call DispMsg("リスナー開始...") 'クライアントから接続有りでこの処理を抜ける Dim pTcpClient As Sockets.TcpClient = pListener.AcceptTcpClient() Call DispMsg("クライアントから接続有り...") '送受信用ソケットストリーム取得 Dim pNetStream As Sockets.NetworkStream = pTcpClient.GetStream() 'バイト配列(取敢えず受信バッファとして256バイト) Dim bytRead As Byte() = New Byte(255) {} 'ソケット受送信ループ While True 'TCP受信(バッファ領域まで) Dim intBytes As Integer = pNetStream.Read(bytRead, 0, bytRead.Count) If intBytes = 0 Then Exit While End If '受信したデータを文字列に変換 Dim enc As Encoding = Encoding.GetEncoding("SHIFT-JIS") Dim resMsg As String = enc.GetString(bytRead, 0, intBytes) '末尾の\rを削除 resMsg = resMsg.TrimEnd(ControlChars.Cr) '表示 Call DispMsg(resMsg) '正常受信の場合、送信データ作成 Dim bytSend() As Byte = enc.GetBytes(resMsg & "...ACK" & ControlChars.Cr) 'ソケット送信 pNetStream.Write(bytSend, 0, bytSend.Length) End While 'ソケットストリームクローズ pNetStream.Close() 'クライアントクローズ pTcpClient.Close() 'リスナー停止 pListener.Stop() Call DispMsg("リスナー停止...") 'ボタン制御 Me.btnStart.Enabled = True End Sub End Class
以下に TCP クライアントのプログラムの例を示します。 この処理は、TCPソケットを作成・接続した後で、NetworkStream によりサーバへデータを送信し、 その後サーバからの応答を受信します。
- IP アドレスとポート番号で TcpClient クラスの生成によりTCPソケット作成・接続
- TcpClient クラスの GetStream メソッドで NetworkStream を取得
- NetworkStream の Write メソッドでテキストボックスの内容をバイト配列化して送信
- NetworkStream の Read メソッドでサーバからの応答を受信しテキストボックスに表示
- 最後にネットワークストリーム、ソケットをクローズ
以下にそのソースを示します。 フォーム上には送信文字列用と受信文字列用のテキストボックス、送信開始用の「Send」ボタンを設置しています。
■TCP クライアントプログラム
Imports System.Net Imports System.Text Public Class frmTcpClient '[Send]リック時イベント Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click Me.btnSend.Enabled = False Try 'サーバーのIPアドレス(または、ホスト名)とポート番号 Dim strIpAddr As String = "localhost" Dim intPort As Integer = 60000 'ソケット生成・指定したホストの指定したポートに接続 Dim pTcpClient = New Sockets.TcpClient(strIpAddr, intPort) 'ソケットストリーム取得 Dim pNetStream As Sockets.NetworkStream = pTcpClient.GetStream() '送信文字列をバイト配列変換 Dim enc As Encoding = Encoding.GetEncoding("SHIFT-JIS") '最後尾にCR Dim data As Byte() = enc.GetBytes(Me.TextBox1.Text.Trim & ControlChars.Cr) Me.TextBox1.Text = "" 'ソケット送信 pNetStream.Write(data, 0, data.Count) 'サーバからの応答を受信 Dim bytRead As Byte() = New Byte(255) {} Dim intBytes As Integer = pNetStream.Read(bytRead, 0, bytRead.Length) '受信したデータを文字列に変換 Dim resMsg As String = enc.GetString(bytRead, 0, intBytes) '末尾の\rを削除し表示 Me.TextBox2.Text = resMsg.TrimEnd(ControlChars.Cr) 'ソケットクローズ pNetStream.Close() pTcpClient.Close() Catch ex As Exception MsgBox(ex.Message) End Try Me.btnSend.Enabled = True End Sub End Class
実際の実行は以下の様になります。
今回のPGはクライアント側で文字列送信後すぐに接続を切っていますので、 1回の送受信毎にサーバ側で「start」をクリックしないといけないので実用には供しないですが、ご参考になればと思います。
次回はこれを踏まえて、サーバ側で開始したらそのまま連続でクライアントからの受信と送信を出来る様にしたいと思います。関連する記事
⇒TCP (TcpListener, TcpClient)を使ったプロセス間通信について・その2
⇒Remoting の IPC を使ったプロセス間通信について
⇒Remoting の IPC を使ったプロセス間通信についてその2(HTTPチャネル)
⇒名前付きパイプを使ったプロセス間通信について
⇒名前付きパイプを使ったプロセス間通信についてその2(複数クライアントとの通信)
⇒名前付きパイプを使ったプロセス間通信についてその3(クライアントとの双方向通信)
-
文字列の一種として、特殊文字の「改行」「タブ」「バックスペース」等をシステム定数として定義されています。
この定義済みの文字列を紹介します。 特殊文字として使うとすれば「復帰」「ラインフィード」「改行」「タブ」「バックスペース」ぐらいでしょうか。
以下の様にシステム定数文字列 vbCr , vbLf , vbNewLine , vbTab , vbBack を使います。 長さが1(復帰のみ2)の文字列として文字列変数にそのまま代入したり連結する形で使えます。 (これらの文字列は Microsoft.VisualBasic.Constants モジュールに定義されています。)
また Microsoft.VisualBasic.ControlChars モジュールにも同じものが定義されていますので、こちらを使うこともできます。
ところで1つはまる点があるのですが、 C# や PHP などではダブルクォテーションで文字列を定義した時に 「¥」円マーク(バックスラッシュ)でエスケープ文字として特殊文字を記述できるので VB.NET でも同じ様に記述すると 単なる「¥」と「n」等の文字そのものになります。■定義済みの文字列定数
Dim str1 As String Dim str2 As String Dim str3 As String '復帰文字 : &H0D str1 = vbCr str2 = ControlChars.Cr str3 = "\r" 'VB.NET では \ はそのままの文字列でエスケープシーケンスではない! Console.WriteLine("vbCr = ControlChars.Cr : " & (str1 = str2) & _ " ControlChars.Cr = ""\r"" : " & (str2 = str3)) 'ラインフィード文字 : &H0A str1 = vbLf str2 = ControlChars.Lf str3 = "\n" Console.WriteLine("vbLf = ControlChars.Lf : " & (str1 = str2) & _ " ControlChars.Lf = ""\n"" : " & (str2 = str3)) '復帰文字とラインフィード文字の組み合わせ : &H0D &H0A str1 = vbCrLf str2 = ControlChars.CrLf str3 = "\r\n" Console.WriteLine("vbCrLf = ControlChars.CrLf : " & (str1 = str2) & _ " ControlChars.CrLf = ""\r\n"" : " & (str2 = str3)) '改行文字(WindowsではvbCrLfと同等) str1 = vbNewLine str2 = ControlChars.NewLine str3 = "\n" Console.WriteLine("vbNewLine = ControlChars.NewLine : " & (str1 = str2) & _ " ControlChars.NewLine = ""\n"" : " & (str2 = str3)) 'タブ文字 : &H9 str1 = vbTab str2 = ControlChars.Tab str3 = "\t" Console.WriteLine("vbTab = ControlChars.Tab : " & (str1 = str2) & _ " ControlChars.Tab = ""\t"" : " & (str2 = str3)) 'バックスペース文字 : &H8 str1 = vbBack str2 = ControlChars.Back str3 = "\t" Console.WriteLine("vbBack = ControlChars.Back : " & (str1 = str2) & _ " ControlChars.Back = ""\b"" : " & (str2 = str3))
上記のソースの部分のみを実行させた場合に、デバッグ出力ウインドウに以下の様に表示されました。
vbCr = ControlChars.Cr : True ControlChars.Cr = "\r" : False vbLf = ControlChars.Lf : True ControlChars.Lf = "\n" : False vbCrLf = ControlChars.CrLf : True ControlChars.CrLf = "\r\n" : False vbNewLine = ControlChars.NewLine : True ControlChars.NewLine = "\n" : False vbTab = ControlChars.Tab : True ControlChars.Tab = "\t" : False vbBack = ControlChars.Back : True ControlChars.Back = "\b" : False
当然なのですが結果から vbCr と ControlChars.Cr は同じであることがわかります。 (他の文字列も同様です)
■定義済みの文字列定数を使う場面について
上記の定義済みの文字列定数を使えば改行等がソース上に視覚的にはっきりとわかる形で記述できます。
ではどの様な時にこれを使う意味が有るのか。 私の場合、改行文字が必要な場面と言えば、 Oracle 等のデータベースへの SQL 文を作成する場合に使用します。 以下のソースでその例をしめします。生成される SQL 文は例なので意味はありません。'接続文字列(これ自身は意味がありません) Dim strConnect As String = "Data Source=//*********/test; User ID=test;Password=test;" 'オラクル接続オブジェクト Dim Conn As New OracleConnection(strConnect) 'オラクル接続オープン Conn.Open() 'SQL文 Dim strSQL As String = "" strSQL &= "SELECT " & vbCrLf strSQL &= " TT.伝票番号, TT.伝票日付" & vbCrLf strSQL &= "FROM 売上伝票 TT" & vbCrLf strSQL &= "WHERE TT.伝票日付 = TO_DATE('2019/11/12')" & vbCrLf strSQL &= "ORDER BY TT.伝票番号" & vbCrLf 'コマンドオブジェクト(SQL文と接続オブジェクト) Dim Cmd As New OracleCommand(SQL, Conn) Cmd.CommandType = CommandType.Text '読込オブジェクトに接続 Dim dr As OracleDataReader = Cmd.ExecuteReader() '*** この後はデータ処理... ***
このソースでは SQL 文を SELECT FROM WHERE ORDER BY の各句で改行を入れています。
この改行ですが Oracle SQL 文の解析を行う時に空白文字の様にホワイトスペースとして扱われ、文字列の中では単語の区切りとみなされます。 そのため、この SQL 文では句の区切りとして使用しています。
改行を入れなくても、先頭に1文字空白を入れれば同じことにはなるのですが、テキストとして見ると改行が入った方が見やすい為です。 (先頭に空白を入れ忘れた時のバカ除けでもあります)
実際システムではよく実行 SQL 文のログを残したりしますが、 その時に長い文字列の1行よりも適当に改行が入っていた方が見やすいのです。
■ダブルクォテーションそのものを文字列の中に定義する方法
ダブルクォテーションそのものを文字列の中に宣言したい場合について説明します。 文字列はダブルクォテーションで囲まれていますが、その文字列の中でダブルクォテーションを2回連続して記述します。 (""として記述)
文字列の中にダブルクォテーションを記述する例として思い当たるのは、 上記のソースの SQL 文の中でカラム名とテーブル名が全角になっていますが、 Oracleではこれらをダブルクォテーションで 囲んだ方が安全です。(昔の Oracle ではある全角文字がうまく判定できないことがありました。)
結果として以下の様な記述になります。'SQL文 Dim strSQL As String = "" strSQL &= "SELECT " & vbCrLf strSQL &= " TT.""伝票番号"", TT.""伝票日付""" & vbCrLf strSQL &= "FROM ""売上伝票"" TT" & vbCrLf strSQL &= "WHERE TT.""伝票日付"" = TO_DATE('2019/11/12')" & vbCrLf strSQL &= "ORDER BY TT.""伝票番号""" & vbCrLf
-
文字列データを全角に全て統一したり、または半角に強制的に変換したい場合に使用するのが StrConv 関数です。 この関数は以下の様な宣言になっています。
Public Function StrConv(str As String, Conversion As Microsoft.VisualBasic.VbStrConv, Optional LocaleID As Integer = 0) As String ・str :変換する String 型の式。 ・Conversion:Microsoft.VisualBasic.VbStrConv のメンバー。 実行する比較の種類を指定する列挙値。 ・LocaleID :省略可能です。 システム LocaleID 値と異なる場合の LocaleID 値。 既定値は、システムの LocaleID です。
LocaleID の引数は通常であれば必要はありません。
尚、Conversion の引数は以下の様な種類があります。
Conversion 処理 VbStrConv.Hiragana 文字列内のカタカナをひらがなに変換します。 日本語ロケールのみに適用されます。 VbStrConv.Katakana 文字列内のひらがなをカタカナに変換します。 日本語ロケールのみに適用されます。 VbStrConv.Lowercase 文字列を小文字に変換します。 VbStrConv.Narrow 文字列内の全角文字を半角文字に変換します。 アジア ロケールに適用されます。 VbStrConv.Uppercase 文字列を大文字に変換します。 VbStrConv.Wide 文字列内の半角 (1 バイト) 文字を全角 (2 バイト) 文字に変換します。
アジア ロケールに適用されます。これらの Conversion の値を OR で連結して指定ができます。
上記の例を以下のソースで行います。
文字列変換関数(StrConv)の使用例
' 元の文字列宣言 Dim strOrg As String = "01245ABCDExyzあいうえおカキクケコサシスセソタチツテト" Dim str As String Console.WriteLine("[変換前の文字列] :" & strOrg) ' 大文字を小文字に変換 str = StrConv(strOrg, VbStrConv.Lowercase) Console.WriteLine("[大文字] ⇒[小文字] :" & str) ' 半角文字を全角文字に変換 str = StrConv(strOrg, VbStrConv.Wide) Console.WriteLine("[半角文字]⇒[全角文字]:" & str) ' 全角文字を半角文字に変換 str = StrConv(strOrg, VbStrConv.Narrow) Console.WriteLine("[全角文字]⇒[半角文字]:" & str) ' 文字列内の[カタカナ]を[ひらがな]に変換します str = Strings.StrConv(strOrg, VbStrConv.Hiragana) Console.WriteLine("[カタカナ]⇒[ひらがな]:" & str) ' 文字列内の[ひらがな]を[カタカナ]に変換します str = Strings.StrConv(strOrg, VbStrConv.Katakana) Console.WriteLine("[ひらがな]⇒[カタカナ]:" & str) ' 小文字を大文字に変換後、全角文字に変換 str = StrConv(strOrg, VbStrConv.Uppercase Or VbStrConv.Wide) Console.WriteLine("[大文字]+[全角文字] :" & str)
上記の処理を実行すると以下の様な表示が、「出力」ウインドウに表示されます。[変換前の文字列] :01245ABCDExyzあいうえおカキクケコサシスセソタチツテト [大文字] ⇒[小文字] :01245abcdexyzあいうえおカキクケコサシスセソタチツテト [半角文字]⇒[全角文字]:01245ABCDExyzあいうえおカキクケコサシスセソタチツテト [全角文字]⇒[半角文字]:01245ABCDExyzあいうえおカキクケコサシスセソタチツテト [カタカナ]⇒[ひらがな]:01245ABCDExyzあいうえおかきくけこサシスセソたちつてと [ひらがな]⇒[カタカナ]:01245ABCDExyzアイウエオカキクケコサシスセソタチツテト [大文字]+[全角文字] :01245ABCDEXYZあいうえおカキクケコサシスセソタチツテト
関連する記事
⇒文字列変換関数(StrConv)で変換が途中で切れる