2015-07-11

PowerShellでユーザーフォームを作る - リストボックス編 -

PowerShellでは、ユーザーの好みに合わせて、独自にフォームを作成することができます。

以前の投稿で、インプットボックスやメッセージボックスをご紹介しましたが、それは非常にシンプルなものであり、使い勝手が良い反面、自由度が低いものでした。

過去の投稿はこちら↓↓
【PowerShellでInputBoxを使用する】
【PowerShellでMessageBoxを使用する】


ユーザーフォーム 3回目は「PowerShellでユーザーフォームを作る - リストボックス編 -」です。

   ユーザーフォーム 1回目 【PowerShellでユーザーフォームを作る - 基礎編 -
   ユーザーフォーム 2回目 【PowerShellでユーザーフォームを作る - オプション紹介 -


基礎編では、入力ボックス(テキストボックス)をユーザーフォームで作成しました。
今回はその応用として、リストボックス(ListBox)の作り方をご紹介します。


<今回の完成品>



背景色などはあえて変更せず、シンプルなものにしています。

それでは例文を記述します。



---------ここから-------------------------------------------------------------------------------------
# ユーザーフォームを作る - リストボックス編 -

# アセンブリのロード
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# フォーム全体の設定
$form = New-Object System.Windows.Forms.Form
$form.Text = "選択"
$form.Size = New-Object System.Drawing.Size(250,300)
$form.StartPosition = "CenterScreen"

# ラベルを表示
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,10)
$label.Size = New-Object System.Drawing.Size(230,20)
$label.Text = "好きな果物を選択してください"

# OKボタンの設定
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(40,200)
$OKButton.Size = New-Object System.Drawing.Size(75,30)
$OKButton.Text = "OK"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK

# キャンセルボタンの設定
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(130,200)
$CancelButton.Size = New-Object System.Drawing.Size(75,30)
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel

# リストボックスの設定
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,30)
$listBox.Size = New-Object System.Drawing.Size(210,150)

# リストボックスに項目を追加
[void] $listBox.Items.Add("りんご")
[void] $listBox.Items.Add("みかん")
[void] $listBox.Items.Add("メロン")
[void] $listBox.Items.Add("レモン")
[void] $listBox.Items.Add("バナナ")
[void] $listBox.Items.Add("すいか")
[void] $listBox.Items.Add("いちご")
[void] $listBox.Items.Add("パパイヤ")
[void] $listBox.Items.Add("キュウイ")
[void] $listBox.Items.Add("オレンジ")
[void] $listBox.Items.Add("ぶどう")

# フォームにアイテムを追加
$form.Controls.Add($label)
$form.Controls.Add($OKButton)
$form.Controls.Add($CancelButton)
$form.Controls.Add($listBox)

# キーとボタンの関係
$form.AcceptButton = $OKButton
$form.CancelButton = $CancelButton

# フォームを最前面に表示
$form.Topmost = $True

# フォームを表示+選択結果を変数に格納
$result = $form.ShowDialog()

# 選択後、OKボタンが押された場合、選択項目を表示
if ($result -eq "OK")
{
$AAA = $listBox.SelectedItem
}else{
exit
}
---------ここまで-------------------------------------------------------------------------------------

上記内容をコピーし、PowerShell ISEに貼り付けて、実行してみてください。
完成品と同じものが表示されましたか??

前回までの投稿を読んでいただいていた方には、今回は解説が必要ないかもしれません。
上記例文の中で、基礎編と異なるのは、入力ボックスだった部分がリストボックスに変更されたことです。
リストボックスに関する部分のみ解説していきます。


**********************************解説*******************************************

# リストボックスの設定
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,30)
$listBox.Size = New-Object System.Drawing.Size(210,150)

・入力ボックスの場合はTextBoxクラスを使用していましたが、今回はリストボックスなのでListBoxクラスを使用しています。


# リストボックスに項目を追加
[void] $listBox.Items.Add("りんご")
[void] $listBox.Items.Add("みかん")
[void] $listBox.Items.Add("メロン")
[void] $listBox.Items.Add("レモン")
    ~(以下省略)~        

・ここでは、リストボックス内に表示させる項目を設定しています。
 今回はわかりやすくするため1つずつ指定していますが、For文を使えば配列内の要素を追加することも可能です。
***********************************************************************************

私はPowerShellで定型業務をよく簡易化していますが、このリストボックスは次のような使い方をしています。

  1.Excelファイルを読み込む
  2.シート名を全て取得し、配列として変数に格納する
  3.取得したシート名をリストボックスに表示させる
  4.作業者にシート名で選択してもらう           といった感じです。

PowerShellでExcelを操作する方法についてはこちら→【PowerShellでExcelを操作する - 基礎編 -
さて、次回はPowerShellでユーザーフォームを作る - チェックボックス編 -」を投稿したいと思います。

=======================================================================
本投稿に関する疑問や質問には可能な限りお答えさせていただきます。
お気軽にコメントやメールをお送りください。
(リクエストも歓迎します)
メール:tkk-powershell@gmail.com
また、間違いのご指摘・アドバイス等も歓迎いたします。
=======================================================================
Google+、Twitterで更新情報をお届けしています!
ぜひフォローをお願い致します!           
=======================================================================
スポンサーリンク


3 件のコメント:

  1. リストボックスで、複数行選択は簡単にできますが、
    削除は・・・できないのでしょうか?
    ユーザ操作にて、複数行を選択させて、一発削除がしたいのですが。

    返信削除
    返信
    1. コメントありがとうございます。

      リストボックスでの複数行選択→一発削除は可能です。
      本文中でご紹介しているサンプルスクリプトを改造し、ボタンを押すと、選択されている項目をすべて削除するスクリプトを作成致しましたので、下記をご参考ください。

      - - - ↓↓↓ 参照 ↓↓↓ - - - - - - - - - - - - -

      # ユーザーフォームを作る - リストボックス編 -
      Add-Type -AssemblyName System.Windows.Forms

      $form = New-Object System.Windows.Forms.Form
      $form.Text = "選択"
      $form.Size = "250,300"
      $form.StartPosition = "CenterScreen"

      $label = New-Object System.Windows.Forms.Label
      $label.Location = "10,10"
      $label.Size = "230,20"
      $label.Text = "好きな果物を選択してください"

      # 削除ボタンの設定
      $Button = New-Object System.Windows.Forms.Button
      $Button.Location = "40,200"
      $Button.Size = "75,30"
      $Button.Text = "削除"

      # ボタンのクリックイベント
      $Delete = {
      # 選択している項目のインデックス番号をすべて取得
      $select = $listBox.SelectedIndices

      # 繰り返し処理
      For($i = $select.count-1 ; $i -ge 0 ; $i--)
      {
      # 選択した項目のn番目のインデックス番号を変数に入れる
      $index = $select[$i]

      # リストボックスのn番目の項目を削除する
      $listBox.Items.RemoveAt($index)
      }
      }
      $Button.Add_Click($Delete)

      # リストボックスの設定
      $listBox = New-Object System.Windows.Forms.ListBox
      $listBox.Location = "10,30"
      $listBox.Size = "210,150"
      $listBox.SelectionMode = "MultiExtended"

      # リストボックスに項目を追加
      [void] $listBox.Items.AddRange(@("りんご","みかん","メロン","レモン","バナナ","すいか","いちご","パパイヤ","キュウイ"))

      # フォームにアイテムを追加
      $form.Controls.AddRange(@($label,$Button,$listBox))

      # フォームを表示+選択結果を変数に格納
      $result = $form.ShowDialog()
      - - - - - - - - - - - - - - - - - - - - - - - - - - -

      注目いただきたいのは「# ボタンのクリックイベント」の部分です。
      クリックイベントは、そのボタンを押したときに処理される内容です。
      (イベントの記述方法についは、http://letspowershell.blogspot.jp/2015/09/powershell_21.html を参照ください)

      まず、SelectedIndicesプロパティで選択されている項目のインデックス番号をすべて取得し、変数selectに格納しています。
      このとき変数selectは配列となります。

      次にfor文を用いた繰り返し処理を行い、RemoveAtメソッドで項目を削除します。

      for文の書き方が「繰り返すごとに増えていく」のではなく、「繰り返すごとに減っていく」ようになっていることにご注目ください。

      例えば、インデックス番号が1、3、5、6の項目を選択したとします。
      最初にインデックス1の項目を削除した時点で、インデックス番号が1つずつズレてしまい、インデックス3であったものがインデックス2となり、インデックス4であったものがインデックス3となります。
      スクリプトは次にインデックス3を削除しようとするので、元々インデックス4であった項目が削除されてしまいます。

      これを防ぐために、インデックスが大きい番号から(=リストボックスの下から)削除を行っています。

      長くなりましたが、ご参考の程、宜しくお願い致します。

      削除
  2. ご返信ありがとうございます!!

    .SelectedIndicesに.RemoveA、それにカウントダウンループ・・・・3つのハードルがあっただなんて。

    本当に助かりました!!

    返信削除

疑問・質問・リクエスト お気軽にどうぞ (^O^)/