-
小学校でのプログラミング教育は必要かと考えると、私は、必要無いと思います。 なぜ小学校でプログラミング教育を行うのかとの問いには、一般的に、 「これからのAI時代に対応するためには少なからずコンピュータの知識が必要になってくるので、小学校から教えておいた方が良い」 とする風潮が在る様に思います。
しかし、本当にそうでしょうか。 実際に小学生が出来ることには限界があるもので、授業で行われるプログラミング教育は、 ロボットの様なものをそれ様に作られたプログラミング言語(言語と呼ぶにはどうかと思いますが)で 動きの制御を行ったりするらしいです。
私が思うに「進め」「とまれ」「右に行け」「左に行け」「これを何回か行え」などの命令を並べて処理をさせると思います。 しかし、この様なことではたしてプログラミングの基礎が学べるのでしょうか。
プログラミングの基礎と言えば、アルゴリズム(算法と訳されます)を習うことから始まったりします。 アルゴリズムと言えば、やはり数学的(もしくは算数的)な思考が元となって成り立っています。 そのために論理的な思考を養える算数が基本ではないでしょうか。 実際にプログラマーをしている立場からすれば、おさえておくべき教科としては 「国語(日本語)」「数学(算数)」「英語」「理科」ではないでしょうか。 日本人として会話の基本は日本語ですから、日本語がしっかりしていないと全ての教科を勉強することはできません。 (この拙い文章を書いている私が言うのもおかしいですが)
後は「英語」は今後のグローバル化を見据えて必要になるでしょう。 プログラミングの為のウエブページを見ても圧倒的に英語のページの方が情報が多いものです。 英語は必要だと思います。
何かをプログラムで処理するなり、動作させるなりする場合には、 対象となるものを論理的に捉えてそれらを道筋を立てて考えなければなりません。 小学校のどの学年からプログラミングを教えていくのかは分かりませんが、 算数などの計算がしっかりできたうえで行った方が良いと思います。
(私は基本的には、小学生の知識レベルではプログラミングは無理があると考えます。)
それでも、小学校でプログラミング教育は始まってしまうので、心配な親御さんはいらっしゃるのではないでしょうか。 最近読んだ本ですが、以下の本にその参考となることが載っています。 この本の中でも書かれていますが、実際のプログラミングをそればかり行うのではなく、 先ずは子供の「考える力」「興味を持つ力」などを育てることが必要と書かれています。 やはり、プログラミングの技巧的な部分ばかりでは無く、プログラミングに必要な素養を育てるようです。 私も何となく納得しました。
⇒知識ゼロのパパ・ママでも大丈夫! 「プログラミングができる子」の育て方
プログラミング教育ですが、平成の時代に行われた「ゆとり教育」の二の舞にならなければと思うのですが。
結局は「ゆとり教育」からの揺り戻しが在って、現在は少し詰め込みを戻したようですが、あの「ゆとり教育」の失敗はちゃんと検証されたのでしょうか? 甚だ疑問です。
「ゆとり教育」も今となっては「総合」の時間などは社会に出た時に必要となる要素を勉強できて良かったのではと思います。 しかし、当時「総合」を教える教師側にも問題があって何をどの様に教えたらいいか分かっていなかったと思います。 折角目指していたことはよかったのですから。
今回の「プログラミング教育」ですが、「ゆとり教育」の時と同じ様にならないかが心配です。 これを教える先生方の教育も必要ですし、年齢の上の先生には正直きついのではないでしょうか。 まあ、これには「プログラミング教育」の民間の力が必要かもしれません。 プログラマのプロから教わることは多いと思います。
PR -
プログラムの多重起動を抑止する方法(自分自身が1回しか起動されないようにする方法)について説明します。 抑止する方法はいろいろあるのですが Mutex を使った方法が比較的簡単だと思いますので、今回はその方法について記します。
先ずは Mutex についてですが、これは排他制御を行う為の仕組みで、現在それを「使用中」か「未使用」かを示すフラグの様なものです。 あるプロセス(実行プログラム)が、ある Mutex を取得しそのフラグを「使用中」にします。 再度そのプロセスを実行した場合にその Mutex は既にフラグが「使用中」であれば、起動を中止する様にします。 (簡単な「セマフォ」であるとも言えます)
.NET には Mutex クラスがありますのでそれを使うことになります。Mutex クラスについて
<コンストラクタ> System.Threading.Mutex(initiallyOwned As Boolean, name As String, ByRef createdNew As Boolean) ・initiallyOwned:名前付きシステム ミューテックスの初期所有権を付与する場合は true。 それ以外の場合は false。 ・name :Mutex の名前です。 ・createdNew :指定した名前付きシステム ミューテックスが作成された場合はブール値 true が格納されます。 指定した名前付きシステム ミューテックスが既に存在する場合は false が格納されます。
Mutexを使ったプログラムは以下の様になります。 上記の Mutex クラスを生成した結果 createdNew フラグを確認することで Mutex が生成されたかが分かります。 true でなければ実際の処理は行わない様にして処理を抜ける様にします。
Mutexを使ったプログラムの多重起動の抑止
Module MdlMain 'Main関数 Sub Main() 'ミューテックス名(一意な名前にすること) Dim mstrMutexName As String = "TestProgramName" '(仮の名前) 'ミューテックス Dim mMutex As System.Threading.Mutex = Nothing '新規作成フラグ Dim blnCreated As Boolean = False Try Try '名前付きシステム ミューテックスの初期所有権を付与 mMutex = New System.Threading.Mutex(True, mstrMutexName, blnCreated) Catch ex As Exception MessageBox.Show("多重起動はできません。Mutex Error[" & ex.Message & "]") Return End Try 'ミューテックスが作成されたか調べる If blnCreated = False Then MessageBox.Show("多重起動はできません。") Return End If '既設のMainメソッドの処理を実行(表示させたいフォームを表示) Dim frm As New frmTest Application.Run(frm) Finally If blnCreated Then 'ミューテックスを解放する mMutex.ReleaseMutex() End If mMutex.Close() End Try End Sub End Module
プログラム中の frmTest は通常のフォームを作成しただけで、フォームの動きは特にプログラミングしていません。
実行の様子を下図に示します。作成された実行ファイルを起動し、その後同じものを起動した時の様子です。
尚、今回の例では Sub Main() メソッドを開始指定(エントリポイント指定)をしてやるのですが、 「プロジェクト・プロパティ」の中の「アプリケーション」タブにある「スタートアップフォーム」でエントリポイントを指定するのですが、 このままでは Sub Main() が中に表示されません。
そこで「アプリケーションフレームワークを有効にする」チェックボックスを無効にすると 「スタートアップフォーム」は「スタートアップオブジェクト」の表示となり、 Sub Main() が出てきますので、それを指定します。
-
フォーム上のコントロールへのイベント処理を宣言する場合には AddHandler メソッドを使うことを以下の記事で紹介しました。
⇒コントロールの同じイベント処理に複数の関連付けをテスト:[AddHandler,DirectCast]
この記事の中で、各イベントの処理を1個の関数で処理できることを示しましたが、そのなかでは同じ処理を行っていました。 今回はこの関数の中でそれぞれのコントロールに対して内部で処理を分けることで、 同じコントロールのイベント関数としては入口は1個ですが、別々の処理を記述できます。 これはコントロールを配列で処理する方法の逆のアプローチになると思います。
⇒コントロールを配列で処理する方法 :[AddHandler,DirectCast]
今回のソースでは KeyPress イベント用関数を追加し、テキストボックスコントロールのそのイベントに関連付けます。 KeyPress イベント用関数のなかでは、どのテキストボックスから呼ばれたのかを判別する為、 呼び出し元オブジェクトの sender の名前 name を使って場合分けします。
今後、テキストボックスが増えた場合にはこの判定と、その処理を追加することになります。フォーム上のコントロールのイベント処理の一括関連付けその2
Public Class frmAddHandler2 ' フォームロードイベント Private Sub frmAddHandler_Load(sender As Object, e As EventArgs) Handles Me.Load 'コントロールへのイベントハンドラ関連付け Call Me.SetEvent(Me.Controls) 'フォームがすべてのキー イベントを受け取る Me.KeyPreview = True End Sub ' コントロールへのイベントハンドラ関連付け ' param CtrlColl :コントロールコレクション Private Sub SetEvent(ByVal CtrlColl As Control.ControlCollection) 'コントロール変数 Dim objControl As Control 'テキストボックスコントロール変数 Dim objTextBox As TextBox 'コントロールがある分だけループ For Each objControl In CtrlColl If TypeOf objControl Is TextBox Then 'テキストボックスコントロールに変換 objTextBox = DirectCast(objControl, TextBox) 'Enterイベントの関連付け AddHandler objTextBox.Enter, AddressOf CtrlEnterEvent 'Changedイベントの関連付け AddHandler objTextBox.TextChanged, AddressOf CtrlTextChangedEvent 'KeyPressイベントの関連付け AddHandler objTextBox.KeyPress, AddressOf CtrlTextKeyPressEvent Else End If Next End Sub ' コントロールのEnterイベント処理 Private Sub CtrlEnterEvent(ByVal sender As Object, ByVal e As System.EventArgs) If TypeOf sender Is TextBox Then 'TextBoxのとき DirectCast(sender, TextBox).SelectAll() End If End Sub ' コントロールのTextChangedイベント処理 Private Sub CtrlTextChangedEvent(ByVal sender As Object, ByVal e As System.EventArgs) If TypeOf sender Is TextBox Then 'TextBoxのとき Dim objTextBox As TextBox = DirectCast(sender, TextBox) '仮の処理として表示内容をTagに退避 objTextBox.Tag = objTextBox.Text End If End Sub ' コントロールのKeyPressイベント処理(1カ所で集中管理する) Private Sub CtrlTextKeyPressEvent(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) 'コントロールの名前により処理を分ける Select Case sender.name Case "TextBox1" '[TextBox1]は数字のみ入力とする If Not ("0" <= e.KeyChar And e.KeyChar <= "9") Then e.Handled = True End If Case "TextBox2" '[TextBox2]は英字大文字の A ~ Z のみ入力とする If Not ("A" <= e.KeyChar And e.KeyChar <= "Z") Then e.Handled = True End If Case "TextBox3" '[TextBox3]は英字子文字の a ~ z のみ入力とする If Not ("a" <= e.KeyChar And e.KeyChar <= "z") Then e.Handled = True End If End Select End Sub ' フォームKeyDownイベント Private Sub frmEnterNext_KeyDown(ByVal sender As Object, _ ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown If e.KeyCode = Keys.Enter Then If e.Control = False Then '[Enter]キーで次の TabIndex があるコントロールへフォーカスを移す Me.SelectNextControl(Me.ActiveControl, Not e.Shift, True, True, True) End If End If End Sub ' フォームKeyPressイベント Private Sub frmEnterNext_KeyPress(ByVal sender As Object, _ ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress If e.KeyChar = ControlChars.Cr Then '[Enter]キーで音が出るので、キーイベントが処理されたことにして音を消す e.Handled = True End If End Sub End Class
これを実行すると以下の様に TextBox1 には数字のみ TextBox2 には英大文字("A"~"Z")のみ TextBox3 には英子文字("a"~"z")のみ、の入力ができます。
今回の方法は、とにかく同じコントロールの同じイベント処理を1個の関数で集中的に処理したい場合には有効だと思います。 テキストボックスのそれぞれのイベントで記述すれば同じじゃないかという突っ込みはあると思いますが...関連する記事
⇒フォーム上のコントロールのイベント処理の一括関連付け:[AddHandler,DirectCast]
-
あるEXEファイルから、他のEXEファイルの中のフォームを強制的に表示する方法として以下の記事で説明しましたが、
⇒他のEXEファイルにあるフォームを表示する方法(Activator.CreateInstanceの使い方)
この方法ではフォームを表示するだけで、面白味が在りませんので、今回はフォームにプロパティとメソッドを追加して それらに対するアクセス方法を説明します。
先ずは、フォームにテキストボックスを1個追加し、それに対して値を設定したり取得するプロパティと、 テキストボックスの内容を表示するメソッドを追加します。呼び出される側のフォーム
Public Class Form1 Private mstrParamData As String 'テキストボックスに値を設定するプロパティ Public WriteOnly Property SetParamData As String Set(value As String) Me.TextBox1.Text = value End Set End Property 'テキストボックスの内容を取得するプロパティ Public ReadOnly Property GetTextData As String Get Return Me.TextBox1.Text End Get End Property '外部からアクセス可能なメソッド Public Sub DspTextBox() MessageBox.Show("TextBox1.Text : " & Me.TextBox1.Text) End Sub 'ボタンクリックイベント Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '自分を閉じる Me.Close() End Sub End Class
上記のフォームが含まれる REF0002.EXE を呼出す側のソースは以下の通りです。
こちらの方は、特にフォームを持たずにMain() 関数からの実行となっています。呼び出す側のMainソース
Public Module Main Sub Main() '自分自身の実行ファイルのパスを取得する Dim appPath As String = _ System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) 'アセンブリ"REF0002.exe"を読み込む(「REF0002.EXE」は「REF0001.EXE」が存在するフォルダに在ります) Dim asmExe As System.Reflection.Assembly = _ System.Reflection.Assembly.LoadFile(appPath & "\REF0002.exe") 'Form1のTypeを取得する(名前空間を指定しているのでフォーム名の前に名前空間を付加) Dim typForm As Type = asmExe.GetType("REF0002.Form1") 'フォーム作成用変数 Dim frm As Form 'フォームのインスタンスを作成 Dim obj As Object = Activator.CreateInstance(typForm) 'インスタンスをフォームとして扱う frm = DirectCast(obj, Form) 'プロパティの設定 Dim pinf As System.Reflection.PropertyInfo = typForm.GetProperty("SetParamData") pinf.SetValue(frm, "Set From REF0001", Nothing) 'フォームの ShowDialog メソッドを使用する frm.ShowDialog() 'プロパティの取得 pinf = typForm.GetProperty("GetTextData") Dim str As String = CStr(pinf.GetValue(frm, Nothing)) MessageBox.Show(str) 'メソッドの利用 Dim minf As System.Reflection.MethodInfo = typForm.GetMethod("DspTextBox") minf.Invoke(frm, Nothing) End Sub End Module
プロパティの情報(System.Reflection.PropertyInfo)を取得する為に、Typeの GetProperty メソッドを使います。 その PropertyInfo の SetValue メソッドでプロパティへの値を設定します。
また、 PropertyInfo の GetValue メソッドでプロパティの値の取得を行います。
さらにメソッドの実行は、プロパティと同様にTypeの GetMethod メソッドによりメソッド情報(System.Reflection.MethodInfo)を取得し PropertyInfo の Invoke メソッドで該当するメソッドの実行を行います。
これを実行すると以下の様な表示になります。関連する記事
⇒他のEXEファイルにあるフォームを表示する方法(Activator.CreateInstanceの使い方)
-
あるEXEファイルから、他のEXEファイルの中のフォームを強制的に表示するにはどうすれば出来るのかを調べてみました。
方法として、EXEファイルの中にあるアセンブリ名(フォーム名)を指定して型情報(Type)を取得し、 そのTypeを利用して Activator.CreateInstance メソッドでフォームのインスタンスが生成されます。
そのインスタンスが持っているフォームの表示メソッドを使えば、そのフォームの表示が行えます。
先ずは、呼び出されるフォーム側のソースです。こちらの方はEXE名を REF0002.EXE となる様に設定してます。 また、名前空間も同様に REF0002 としています。呼び出される側のフォーム
Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '自分を閉じる Me.Close() End Sub End Class
上記のフォームが含まれる REF0002.EXE を呼出す側のソースは以下の通りです。
こちらの方は、特にフォームを持たずにMain() 関数からの実行となっています。呼び出す側のMainソース
Public Module Main Sub Main() '自分自身の実行ファイルのパスを取得する Dim appPath As String = _ System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) 'アセンブリ"REF0002.exe"を読み込む(「REF0002.EXE」は「REF0001.EXE」が存在するフォルダに在ります) Dim asmExe As System.Reflection.Assembly = _ System.Reflection.Assembly.LoadFile(appPath & "\REF0002.exe") 'Form1のTypeを取得する(名前空間を指定しているのでフォーム名の前に名前空間を付加) Dim typForm As Type = asmExe.GetType("REF0002.Form1") 'フォーム作成用変数 Dim frm As Form 'フォームのインスタンスを作成 Dim obj As Object = Activator.CreateInstance(typForm) 'インスタンスをフォームとして扱う frm = DirectCast(obj, Form) 'フォームの ShowDialog メソッドを使用する frm.ShowDialog() End Sub End Module
これを実行すると以下の様な表示になります。
ソースは特に難しいところは無いかと思います。 Form1のTypeを取得するところで asmExe.GetType("REF0002.Form1") としていますが、これは REF0002.EXE での名前空間を REF0002 に 設定してあるからです。 この名前空間を空白にすれば asmExe.GetType("Form1") で可能です。関連する記事
⇒他のEXEファイルにあるフォームを表示する方法その2(Activator.CreateInstanceの使い方)