■閉鎖した昔のブログの記事復活
[2025/05/11] 頭がよくなる 青ペン書きなぐり勉強法 (No.392)
[2025/05/11] VB.NET:標準ラベルコントロールにグラデーションを追加したGradientLabelコントロール (No.391)
[2025/05/11] VB.NET:マーシャリングを使用した、構造体からバイト配列へのコピー (No.390)
[2025/05/11] VB.NET:マーシャリングを使用した、バイト配列から構造体へのコピー (No.389)
[2025/05/11] VB.NET:ADO.NET を使用した SQL-Server へのアクセス・クラス (No.388)
[2025/05/11] VB.NET:標準ラベルコントロールにグラデーションを追加したGradientLabelコントロール (No.391)
[2025/05/11] VB.NET:マーシャリングを使用した、構造体からバイト配列へのコピー (No.390)
[2025/05/11] VB.NET:マーシャリングを使用した、バイト配列から構造体へのコピー (No.389)
[2025/05/11] VB.NET:ADO.NET を使用した SQL-Server へのアクセス・クラス (No.388)
-
青ペン書きなぐり勉強法」でなにより重要なのは、達成感です。「ペンを1本使い切った」「今日1日でインクがこんなに減った」と、効果を「見える化」することにより、その量が「こんなにやった!」と自信に変わる。そうすると、義務感にかられての勉強が、「もっとやりたいもの」に変わります。さらに続けると「青ペンを握らないと調子が出ない」と“やみつきになる効果”があります。
「何もかも書く」がポイント
―社会人で、仕事のメモ術として役立てている方もいらっしゃるそうですね。
情報の整理に役立つという声は、よく聞きます。この勉強法は、もともとは授業内容を効率的に復習できる「再現性の高いノート」を作るための技でした。だから、「情報は取捨選択しないで何もかも書く」というのがポイント。当然、ビジネスシーンでも、そのまま使えます。ホワイトボードに書かれた内容や、渡された資料だけを見るのではなく、相手が話したことを「何もかも書く」。
ところがこれが、実際にやってみると、案外難しいのです。全部書こうと思っても、手が追いつかない。無理なことに気がつく。実は、この「気づき」がとても重要なんですね。意識しないと、私たちは自分の「主観」で勝手に情報の取捨選択をしてしまいます。でも、何が重要で、何が重要でないかなんて、通常、瞬時に判断できるはずがありません。だから効率よく復習したいと思ったら、まずは「全部書く!」と決める。そこから、再現性の高いノートが生まれるのです。
元塾生で、「青ペンで勉強していると、大切な試験の当日に、突然、文字が浮き上がって見えてくる」と言った生徒がいました。書きなぐっているときには気づかないのだけれど、いつの間にか脳に「しみ込んで」、ふとしたときに再現される、と。私はこの感覚は「第六感」に近いのではないかと思います。
目で見て声に出し、それを自分の耳で聞きながら、手を動かして記憶する――。五感をフルに活用して勉強すると、私たちの潜在能力が最大限に発揮されるようになるのではないでしょうか。
=====2015/03/18:の時の情報
PR -
VB.NETで標準ラベルコントロールから派生した、背景色をグラデーション描画するGradientLabelコントロールを作成しました。
このコントロールには以下の追加プロパティが備わっています。
このGradientLabelコントロールのソースは以下の様になっています。プロパティ 概要 BackColor2グラデーション終了色
(デフォルトのBackColorからBackColor2への色の変化)FrameColorラベルの枠色 GradientModeグラデーションの方向(LinearGradientMode) GradientCountグラデーションの回数
(回数は1から10に強制的におさえている)
バックグラウンド描画イベント処理にてグラデーション用ブラシでグラデーションの色と位置を設定し、内部を描画します。 さらに、枠色で枠を描画しています。
Imports System.ComponentModel Imports System.Drawing.Drawing2D Public Class GradientLabel Inherits System.Windows.Forms.Label '''''' コンストラクタ ''' '''Public Sub New() MyBase.New() MyBase.BackColor = Color.Transparent Me._GradientMode = LinearGradientMode.Horizontal End Sub ''' ''' バックグラウンド描画イベント処理 ''' Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs) Dim g As Graphics = pevent.Graphics If Me.BackColor.A < 255 OrElse Me.BackColor2.A < 255 Then MyBase.OnPaintBackground(pevent) End If '描画領域 Dim rect As Rectangle = New Rectangle(0, 0, Me.Width, Me.Height) 'グラデーション用ブラシ Dim lgb As LinearGradientBrush = New LinearGradientBrush(rect, Color.Red, Color.Violet, Me._GradientMode) 'グラデーション用のColorBlendクラス Dim cb As ColorBlend = New ColorBlend() 'グラデーションの色と位置を設定 Dim arrColors(Me._GradientCount) As Color Dim arrPos(Me._GradientCount) As Single For i As Integer = 0 To _GradientCount If (i And 1) = 0 Then arrColors(i) = Me._BackColor Else arrColors(i) = Me._BackColor2 End If arrPos(i) = i / _GradientCount Next cb.Colors = arrColors cb.Positions = arrPos lgb.InterpolationColors = cb '複数の色による線形グラデーション定義 g.FillRectangle(lgb, rect) '描画 '枠を描画する(取敢えず線の幅は2) Using pen As New Pen(Me._FrameColor, 2) pen.DashStyle = Drawing2D.DashStyle.Solid g.DrawRectangle(pen, rect) End Using End Sub Private _BackColor As Color Public Shadows Property BackColor() As Color Get If Me._BackColor <> Color.Empty Then Return Me._BackColor End If If Me.Parent IsNot Nothing Then Return Me.Parent.BackColor End If Return Control.DefaultBackColor End Get Set(ByVal value As Color) Me._BackColor = value Me.Invalidate() '再描画 End Set End Property Private _BackColor2 As Color <Category("Display"), Description("グラデーション終了色")> _ Public Property BackColor2() As Color Get If Me._BackColor2 <> Color.Empty Then Return Me._BackColor2 End If If Me.Parent IsNot Nothing Then Return Me.Parent.BackColor End If Return Control.DefaultBackColor End Get Set(ByVal value As Color) Me._BackColor2 = value Me.Invalidate() '再描画 End Set End Property Private _FrameColor As Color = Color.Black <Category("Display"), Description("枠色")> _ Public Property FrameColor() As Color Get If Me._FrameColor <> Color.Empty Then Return Me._FrameColor End If Return Color.Black End Get Set(ByVal value As Color) Me._FrameColor = value Me.Invalidate() '再描画 End Set End Property Private _GradientMode As LinearGradientMode <Category("Display")> _ <DefaultValue(GetType(LinearGradientMode), "Horizontal"), Description("グラデーションの方向")> _ Public Property GradientMode() As LinearGradientMode Get Return Me._GradientMode End Get Set(ByVal value As LinearGradientMode) Me._GradientMode = value Me.Invalidate() '再描画 End Set End Property Private _GradientCount As Integer = 4 <Category("Display")> _ <DefaultValue(GetType(Integer), "4"), Description("グラデーションの回数")> _ Public Property GradientCount() As Integer Get Return Me._GradientCount End Get Set(ByVal value As Integer) If value < 1 Then value = 1 If value > 10 Then value = 10 Me._GradientCount = value Me.Invalidate() '再描画 End Set End Property End Class
このコントロールを使った例を以下に示します。
■GradientMode:Horizontal
左から右に向かってグラデーションされます。
BackColor⇒BackColor2の色変化のグラデーションです。
GradientCount=1の場合は、BackColor⇒BackColor2のみのグラデーションで
GradientCount=2の場合は、BackColor⇒BackColor2⇒BackColorのグラデーションとなります。
その後、GradientCountの値が増えるに従って、「BackColor2」「BackColor」が繰り返されます。
■GradientMode:Vertical
上から下に向かってグラデーションされます。
■GradientMode:ForwardDiagonal
左上から右下に向かってグラデーションされます。
■GradientMode:BackwardDiagonal
右上から左下に向かってグラデーションされます。
=====
2015/03/23:の時の情報
-
前回はバイト配列から構造体へのコピーでしたが、今回はその逆である、構造体からバイト配列へのコピーです。
例とする構造体は前回同様、4個のバイト配列変数を持った簡単な構造を例にとります。以下の様な宣言になります。 各変数は「MarshalAs」を使って、固定サイズ長を宣言してやります。
'バイト配列分解構造体 <StructLayout(LayoutKind.Sequential, Pack:=1)> _ Private Structure ByteSplit <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _ Public A As Byte() <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _ Public B As Byte() <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _ Public C As Byte() <MarshalAs(UnmanagedType.ByValArray, SizeConst:=64)> _ Public X As Byte() End Structure
この構造体からバイト配列に変換する関数を以下に示します。
Imports System.Runtime.InteropServices 'これは先頭で宣言してください '''
''' 構造体からバイト配列にコピーする ''' ''' <param name="byteSplit">構造体</param> ''' <returns>バイト配列を返す</returns> Private Function ToByteArray(ByVal byteSplit As ByteSplit) As Byte() '構造体のサイズ Dim size As Integer = Marshal.SizeOf(GetType(ByteSplit)) 'ヒープ領域にサイズ分のメモリ確保 Dim iPtr As IntPtr = Marshal.AllocHGlobal(size) '構造体をヒープ領域にコピー Marshal.StructureToPtr(byteSplit, iPtr, False) 'Byte配列の宣言 Dim newBytes As Byte() = New Byte(size - 1) {} 'ヒープ領域からByte配列にコピー Marshal.Copy(iPtr, newBytes, 0, size) 'ヒープ領域を解放 Marshal.FreeHGlobal(iPtr) 'バイト配列を返す Return newBytes End Function 'バイト配列を構造体にコピーするテスト Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click Dim x As Byte() = New Byte() {&H10, &H11, &H20, &H21, &H22, &H23, &H30, &H31, &H32, &H33, &H40, &H41} '前回の関数(バイト配列を構造体にコピー)を利用 Dim xByte As ByteSplit = ToByteSplit(x) Dim x2 As Byte() = ToByteArray(xByte) End Sub
バイト配列の「x2」には20個分の配列として値が返されます。
=====
2015/03/20:の時の情報
-
VB.NETで通信制御プログラムを組んでいると、電文解析などが必要になります。電文はバイト配列で取得しますが、 その電文を分割して処理するにも、解析用の構造体を宣言しそちらにバイト配列からコピーできると便利です。
今回は、構造体に4個のバイト配列変数を持った簡単な構造を例にとります。以下の様な宣言になります。 各変数は「MarshalAs」を使って、固定サイズ長を宣言してやります。
'バイト配列分解構造体 <StructLayout(LayoutKind.Sequential, Pack:=1)> _ Private Structure ByteSplit <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> _ Public A As Byte() <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _ Public B As Byte() <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _ Public C As Byte() <MarshalAs(UnmanagedType.ByValArray, SizeConst:=64)> _ Public X As Byte() End Structure
バイト配列からこの構造体に変換する関数を以下に示します。
■「clsSqlServer」のソース
Imports System.Runtime.InteropServices 'これは先頭で宣言してください '''
''' バイト配列を構造体にコピーする ''' ''' <param name="bytes">バイト配列</param> ''' <returns>構造体を返す</returns> Private Function ToByteSplit(ByVal bytes As Byte()) As ByteSplit '作業用Byte配列(この時点でnewBytesの内容は全て0設定) Dim newBytes As Byte() = New Byte(Marshal.SizeOf(GetType(ByteSplit)) - 1) {} '作業用Byte配列にコピー Array.Copy(bytes, newBytes, bytes.Length) '作業用Byte配列をガベージコレクタが移動できない様に固定 Dim gch As GCHandle = GCHandle.Alloc(newBytes, GCHandleType.Pinned) '構造体へコピー Dim result As ByteSplit = CType(Marshal.PtrToStructure(gch.AddrOfPinnedObject(), GetType(ByteSplit)), ByteSplit) '固定ハンドルの廃棄 gch.Free() '構造体を返す Return result End Function 'バイト配列を構造体にコピーするのテスト Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click Dim x As Byte() = New Byte() {&H10, &H11, &H20, &H21, &H22, &H23, &H30, &H31, &H32, &H33, &H40, &H41} Dim xByte As ByteSplit = ToByteSplit(x) End Sub
処理ボタンをフォームに貼り付けてテストしていますが、「x」で12個のデータを宣言していますが、 構造体の「X」には「&H40, &H41」の部分しか設定されませんが、残りには&H0が埋められます。
=====
2015/03/19:の時の情報
-
ADO.NET を使用した SQL-Server へのアクセス・クラスの簡単なものを作成してみました。
このクラスを元にして拡張したものを仕事でも使っています。
このクラス「clsSqlServer」には以下のメソッド・プロパティが備わっています。
メソッド・プロパティ 概要 Newコンストラクタ(引数にデータベース接続文字列を渡す) BeginTransactionトランザクション開始 Commitトランザクションコミット Rollbackトランザクションロールバック CloseConnectionコネクションの解除 OpenDataReaderSELECT文SQLの実行とDataReaderへの読込 CloseDataReaderDataReaderのクローズ ExeSQLDML-SQL文の実行 CnvReaderToHashtableDataReaderの結果ItemsをHashtableに変換
今回のクラスのテストプログラムを以下に載せますが、SQLサーバへの接続文字列は以下の様にしています。
キーワード 概要(設定値) Persist Security InfoID やパスワードなどのセキュリティ関連情報の破棄指定(False) Integrated Security現在のWindowsアカウントでの認証(SSPI) Databaseデータベース名(取敢えず「TEST」) Data SourceSQL 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:の時の情報