PowerShellでタスク管理ツールを作成

PowerShellでタスク管理ツールを作成

 PowerShellでWindowsフォームを作ることができることがわかったので、下記のようなタスク管理ツールを作ってみた。データはフォルダとフォルダ内にあるTask.xmlで保持するようにしてみた。

 frm010_000_Project.ps1にすべての処理を記載してあり、ファイルの分割などは行っていない。ただどうしてもアセンブリ読み込みの関係で単一ファイルにすることができなかった。   

下記のアセンブリ読み込みを実行しないとFormの継承をすることができなく、スクリプト上で指定をしていてもスクリプトを開く前に実行をしておかないと読み込みができずエラーが発生する。※Classの読み込みがスクリプト上のAdd-Typeよりも先に実行されるためだと思うが・・・。スクリプト上でClassをインスタンス化して処理をしている可能性があるので、当然といえば当然の気もする・・・・。
<事前実行する必要のあるアセンブリ読み込みコマンド>
 Add-Type -AssemblyName System.Windows.Forms;
 Add-Type -AssemblyName System.Drawing;

そのため、Main.ps1を実行すると、アセンブリ読み込みを行った後に同階層にある「frm010_000_Project.ps1」を読み込んで、インスタンス化するような形で作成している。

このツールのいいところはインストール不要であり、フリーソフトなどのファイルをダウンロードすることができない環境でもコピペすれば使えること。
問題は、まだタスクの検索機能や削除機能、終了したタスクをアーカイブする処理を作っていないこと・・・。
試してはいないが、Tree階層をフォルダ階層で表していて、1タスク1フォルダで、データは各フォルダに配置されているTask.xmlにそれぞれ管理しているので共通フォルダに「Main.ps1」「frm010_000_Project.ps1」「Data」フォルダを配置することで複数人で利用できるはず。試していないけど。

ソースコード

Main.ps1
-------
Add-Type -AssemblyName System.Drawing;
Add-Type -AssemblyName System.Windows.Forms;


$CurrentDir  = Split-Path $MyInvocation.MyCommand.path;
$ScriptName = $MyInvocation.MyCommand.path;
$Basename    = $MyInvocation.MyCommand.Name;

#   読み込むファイル
$MenuFile = $CurrentDir + "\frm010_000_Project.ps1";
.$MenuFile;

[Application]::EnableVisualStyles();
$form = [frm010_000_Projet]::new();
$form.fstrCurrentPath = $CurrentDir;
$form.StartPosition="CenterScreen";   # 列挙体は文字列で指定する必要がある
$form.ShowDialog();



frm010_000_Project.ps1
-------
using namespace System.Windows.Forms;
using namespace System.Drawing;

#デバッグ する際にはターミナルで流しておく必要がある。Classの継承を行っており、Class定義がスクリプトの中で一番最初に読み込まれる(?)ためエラーが出る。先に別ファイルやターミナルで実行することで回避

Add-Type -AssemblyName System.Windows.Forms;
Add-Type -AssemblyName System.Drawing;

# [void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
# [void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

# [void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
# [void][reflection.assembly]::LoadWithPartialName("System.Drawing")

$CurrentDir  = Split-Path $MyInvocation.MyCommand.path;
$ScriptName = $MyInvocation.MyCommand.path;
$Basename    = $MyInvocation.MyCommand.Name;

# ------------------------------------------------------------------------------------------------------------
#  メイン画面を作成
# ------------------------------------------------------------------------------------------------------------
# Formクラスを継承して新しいクラスを作成する
Class frm010_000_Projet :System.Windows.Forms.Form{
   
    [string]$fstrCurrentPath; # インスタンス後に設定される。$MyInvocation.MyCommandはスクリプト内で定義されており、ウォッチ式は見れるがクラスの中では取得できない。
    [System.Collections.Generic.Dictionary[string,TreeNode]]$fdicNodes;
    [System.Collections.Generic.Dictionary[string,TreeNode]]$fdicNodesById;
    [System.Data.DataSet]$fdsCurrentData ;
    [string]$DATA_FILE_NAME = "Task.xml";
    [string]$DATA_TABLE_NAME_CONTENT = "ContentsData";
    [string]$DATA_TABLE_NAME_HISTORY = "HistoryData";

    [string]$COLNAME_CONTENTS_TITLE = "Title";
    [string]$COLNAME_CONTENTS_LIMITDAY = "LimitDay";
    [string]$COLNAME_CONTENTS_LIMITALERTDAYCOUNT = "LimitAlertDayCount";
    [string]$COLNAME_CONTENTS_STATUS = "Status";
    [string]$COLNAME_CONTENTS_COLORLABEL = "ColorLabel";
    [string]$COLNAME_CONTENTS_MEMBER = "Member";
    [string]$COLNAME_CONTENTS_CLASS = "Class";
    [string]$COLNAME_CONTENTS_CREATEIONDATETIME = "CreateDateTime";
    [string]$COLNAME_CONTENTS_CONTENTS = "Contents";
    [string]$COLNAME_CONTENTS_NOTE = "Note";

    [string]$COLNAME_HISTORY_PATTERN = "Pattern";
    [string]$COLNAME_HISTORY_CONTROL = "Control";
    [string]$COLNAME_HISTORY_CREATEIONDATETIME = "CreateDateTime";
    [string]$COLNAME_HISTORY_USERNAME = "UserName";
    [string]$COLNAME_HISTORY_HISTORYCONTENTS = "HistoryContents";

    [string]$DGV_COLNAME_TRKDATETIME = "colTrkDateTime";
    [string]$DGV_COLNAME_KBN = "colKbn";
    [string]$DGV_COLNAME_CONTROL = "colControl";
    [string]$DGV_COLNAME_HOSTNAME = "colHostName";
    [string]$DGV_COLNAME_CONTENTS = "colContents";

    [string]$DGV_ALIGN_MIDDLECENTER = "MiddleCenter";
    [string]$DGV_ALIGN_MIDDLELEFT = "MiddleLeft";
    [string]$DGV_ALIGN_MIDDLERIGHT = "MiddleRight";

    [string]$STATUS_TODO = "作業前";
    [string]$STATUS_DOING = "作業中";
    [string]$STATUS_DONE = "作業完了";

    [string]$PATTERN_AUTO = "自動";
    [string]$PATTERN_CHANGELOG = "変更";
    [string]$PATTERN_COMMENT = "コメント";

    [string]$LABELCOLOR_RED = "赤";
    [string]$LABELCOLOR_PINK = "桃";
    [string]$LABELCOLOR_PURPLE = "紫";
    [string]$LABELCOLOR_ORANGE = "橙";
    [string]$LABELCOLOR_YELLOW = "黄";
    [string]$LABELCOLOR_GREEN = "緑";
    [string]$LABELCOLOR_LIGHTBLUE = "水";
    [string]$LABELCOLOR_BLUE = "青";

    # ↓↓↓↓↓  Design Start
    # 色:https://www.lab-nemoto.jp/www/leaflet_edu/else/ColorMaker.html
    #   ▼タイトル
    $lblTitle=[Label]@{
        Location = [Point]::new(5,5);
        Size=[Size]::new(80,20);
        Text = “タイトル”;
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }

    $txtTitle=[TextBox]@{
        Location = [Point]::new(88,5);
        Size=[Size]::new(20,20);
        Anchor="Top,Left,Right";
        Text = “”;
    }

    #   ▼期限
    $lblLimit=[Label]@{
        Location = [Point]::new(5,30);
        Size=[Size]::new(80,20);
        Text = “期限”;  
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $txtLimit=[TextBox]@{
        Location = [Point]::new(88,30);
        Size=[Size]::new(90,30);
        Anchor="Top,Left";
        Text = “”;
    }

    #   ▼期限通知カウント
    $txtAlertDayCount=[TextBox]@{
        Location = [Point]::new(180,30);
        Size=[Size]::new(20,30);
        Anchor="Top,Left";
        TextAlign = [System.Windows.Forms.HorizontalAlignment]::Right;
        MaxLength = 1;
        Text = “”;
    }
    $lblAlertDayCount=[Label]@{
        Location = [Point]::new(202,32);
        Size=[Size]::new(85,20);
        Text = “日前に通知”;        
        Anchor="Top,Left";
        BorderStyle="None";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
   
    #   ▼進捗状況
    $lblStatus=[Label]@{
        Location = [Point]::new(290,30);
        Size=[Size]::new(75,20);
        Text = “進捗状況”;        
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $cboStatus=[ComboBox]@{
        Location = [Point]::new(368,30);
        Size=[Size]::new(90,20);
        DropDownStyle = "DropDownList";
    }

    #   ▼色
    $lblColorLabel=[Label]@{
        Location = [Point]::new(465,30);
        Size=[Size]::new(50,20);
        Text = “色”;        
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $cboColorLabel=[ComboBox]@{
        Location = [Point]::new(517,30);
        Size=[Size]::new(45,20);
        DropDownStyle = "DropDownList";
    }
    $lblStickyNote=[Label]@{
        Location = [Point]::new(565,30);
        Size=[Size]::new(20,20);
        Text = “”;        
        #BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }

    #   ▼担当
    $lblMember=[Label]@{
        Location = [Point]::new(5,55);
        Size=[Size]::new(80,20);
        Text = “担当”;        
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $txtMember=[TextBox]@{
        Location = [Point]::new(88,55);
        Size=[Size]::new(115,30);
        Anchor="Top,Left";
        Text = “”;
    }

    #   ▼分類
    $lblClass=[Label]@{
        Location = [Point]::new(212,55);
        Size=[Size]::new(60,20);
        Text = “分類”;        
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $txtClass=[TextBox]@{
        Location = [Point]::new(275,55);
        Size=[Size]::new(90,30);
        Anchor="Top,Left";
        Text = “”;
    }

    #   ▼登録日時
    $lblCreateDateTime=[Label]@{
        Location = [Point]::new(367,55);
        Size=[Size]::new(65,20);
        Text = “登録日時”;        
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $txtCreateDateTime=[TextBox]@{
        Location = [Point]::new(435,55);
        Size=[Size]::new(165,30);
        Anchor="Top,Left";
        Text = “”;
        ReadOnly = $True
    }

    #   ▼コンテンツ
    $lblContents=[Label]@{
        Location = [Point]::new(5,80);
        Size=[Size]::new(80,20);
        Text = “内容”;        
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $txtContents=[TextBox]@{
        Location = [Point]::new(88,80);
        Size=[Size]::new(20,105);
        Anchor="Top,Left,Right";
        Text = “”;
        WordWrap = $False;
        ScrollBars = "Both";
        Multiline = $True;
    }

    #   ▼備考
    $lblNote=[Label]@{
        Location = [Point]::new(5,190);
        Size=[Size]::new(80,20);
        Text = “備考”;        
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $txtNote=[TextBox]@{
        Location = [Point]::new(88,190);
        Size=[Size]::new(20,65);
        Anchor="Top,Left,Right";
        Text = “”;
        WordWrap = $False;
        ScrollBars = "Both";
        Multiline = $True;
    }

    #   ▼メインとなるテーブルレイアウトパネル
    $tlpMainLayout=[TableLayoutPanel]@{
        ColumnCount = 1;
        RowCount=2;
        Dock= "Fill";
    }
   
    #   ▼変更履歴を表示するかどうかのチェックボックス
    $chkShowHistory=[CheckBox]@{
        Location = [Point]::new(5,2);
        Size=[Size]::new(140,20);
        Anchor="Top,Left";
        Text = "変更履歴を表示"
        Checked=$false;
    }

    #   ▼変更履歴及びコメント一覧
    $dgv = [DataGridView]@{
        Location = [Point]::new(5,23);
        Size=[Size]::new(140,20);
        Anchor="Top,Left,Right,Bottom";
        AutoGenerateColumns=$false;
        AllowUserToAddRows=$False;
        AllowUserToDeleteRows=$False;
        ReadOnly=$True;
    }

    #   ▼履歴内容
    $lblHistoryContents=[Label]@{
        Location = [Point]::new(5,5);
        Size=[Size]::new(270,20);
        Text = “履歴内容”;        
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $txtHistoryContents=[TextBox]@{
        Location = [Point]::new(5,28);
        Size=[Size]::new(270,15);
        Anchor="Top,Bottom,Left";
        Text = “”;
        WordWrap = $False;
        ScrollBars = "Both";
        ReadOnly=$true;
        Multiline = $True;
    }

    #   ▼コメント
    $lblComments=[Label]@{
        Location = [Point]::new(278,5);
        Size=[Size]::new(270,20);
        Text = “追加コメント”;        
        BackColor = [System.Drawing.Color]::FromArgb(213, 219, 255);
        Anchor="Top,Left";
        BorderStyle="FixedSingle";
        TextAlign = "MiddleLeft";
        AutoSize = $False;
    }
    $txtComments=[TextBox]@{
        Location = [Point]::new(278,28);
        Size=[Size]::new(270,15);
        Anchor="Top,Bottom,Left";
        Text = "";
        WordWrap = $False;
        ScrollBars = "Both";
        Multiline = $True;
    }

    #   ▼追加ボタン
    $btnAddComment=[Button]@{
        Location = [Point]::new(553,100);
        Size=[Size]::new(50,25);
        BackColor = "Silver";
        Anchor="Top,Left";
        Text = "追加";
    }

    #   ▼登録内容と履歴内容の区切り(TreeViewとその右側の区切り)
    $SpContainVertical=[SplitContainer]@{
        Dock="Fill";
        Orientation = "Vertical";
        BorderStyle = "FixedSingle"
    }

    #   ▼登録内容と履歴内容の区切り(タスク内容と履歴内容の水平区切り)
    $SpContainTask=[SplitContainer]@{
        Dock="Fill";
        Orientation = "Horizontal";
        BorderStyle = "FixedSingle";
        # Initializeでコントロールの追加をしてからでないとうまく反映できないためコメントアウト
        # SplitterDistance = 50;
    }

    $SpContainHorizontal=[SplitContainer]@{
        Dock="Fill";
        Orientation = "Horizontal";
        BorderStyle = "FixedSingle";
    }

    #   ▼TreeView
    $tvTasks = [TreeView]@{
        Dock="Fill";
        AllowDrop = $True;
        HideSelection = $False; # フォーカスを失ってもノードの選択状態を維持する
    }

    #   ▼メニューバー
    $menuFormMain = [MenuStrip]@{

    }

    # ↑↑↑↑↑ Design End


    # ↓↓↓↓↓ Method

    # コンストラクタ
    frm010_000_Projet(){

        $this.Initialize();

        # Load_Events
        $frm_Load = {
            $this.RefreshTreeViewNodes();
            $this.SpContainTask.SplitterDistance = 260;
            $this.SpContainHorizontal.SplitterDistance = 150;
        }
        $this.add_Load($frm_Load);

    }  

    # ------------------------------------------------------------------------------------------------------------
    # 初期化処理
    # ------------------------------------------------------------------------------------------------------------
    Initialize() {
        $this.Text = "Task"
        $this.Size = [Size]::new(950, 670);
        $this.Font = New-Object Drawing.Font("MS Gothic",10) ;
        $this.dgv.Font = New-Object Drawing.Font("MS Gothic",9) ;
        $this.chkShowHistory.Font = New-Object Drawing.Font("MS Gothic",9) ;
       
        #$this.Font = New-Object Drawing.Font("BIZ UDGothic",10) ;
        #$this.dgv.Font = New-Object Drawing.Font("BIZ UDGothic",9) ;
        #$this.chkShowHistory.Font = New-Object Drawing.Font("BIZ UDGothic",9) ;
       
        $this.BackColor = [System.Drawing.Color]::FromArgb(232, 241, 255);

        $this.fdicNodes = [System.Collections.Generic.Dictionary[String, PSObject]]::new();
        $this.fdicNodesById = [System.Collections.Generic.Dictionary[String, PSObject]]::new();
       
        # コントロールを追加
        # レイアウトロジックを停止する
        $this.SuspendLayout()
   
        #  Menuを追加する
        $this.MenuControlInit()

        # 各種パネルを追加する
        #    TableLayoutPanelを主に配置し、SplitContainerパネルを配置していく
        $this.Controls.Add($this.tlpMainLayout)
        $this.tlpMainLayout.RowStyles.Add((New-Object System.Windows.Forms.RowStyle("Absolute",70)));
        $this.tlpMainLayout.CellBorderStyle = "Single";
        $this.tlpMainLayout.Controls.Add($this.SpContainVertical,0,1);
        $this.SpContainVertical.Panel2.Controls.Add($this.SpContainTask);
        $this.SpContainTask.Panel2.Controls.Add($this.SpContainHorizontal);
   
        # 画面右側のタスクの登録項目を配置していく
        $this.SpContainTask.Panel1.Controls.Add($this.lblTitle);
        $this.SpContainTask.Panel1.Controls.Add($this.txtTitle);
        $this.SpContainTask.Panel1.Controls.Add($this.lblLimit);
        $this.SpContainTask.Panel1.Controls.Add($this.txtLimit);
        $this.SpContainTask.Panel1.Controls.Add($this.txtAlertDayCount);
        $this.SpContainTask.Panel1.Controls.Add($this.lblAlertDayCount);
        $this.SpContainTask.Panel1.Controls.Add($this.lblStatus);
        $this.SpContainTask.Panel1.Controls.Add($this.cboStatus);
        $this.SpContainTask.Panel1.Controls.Add($this.lblColorLabel);
        $this.SpContainTask.Panel1.Controls.Add($this.cboColorLabel);
        $this.SpContainTask.Panel1.Controls.Add($this.lblStickyNote);
        $this.SpContainTask.Panel1.Controls.Add($this.lblMember);
        $this.SpContainTask.Panel1.Controls.Add($this.txtMember);        
        $this.SpContainTask.Panel1.Controls.Add($this.lblClass);
        $this.SpContainTask.Panel1.Controls.Add($this.txtClass);
        $this.SpContainTask.Panel1.Controls.Add($this.lblCreateDateTime);
        $this.SpContainTask.Panel1.Controls.Add($this.txtCreateDateTime);
        $this.SpContainTask.Panel1.Controls.Add($this.lblContents);
        $this.SpContainTask.Panel1.Controls.Add($this.txtContents);
        $this.SpContainTask.Panel1.Controls.Add($this.lblNote);
        $this.SpContainTask.Panel1.Controls.Add($this.txtNote);

        # 履歴一覧を表示する
        $this.SpContainHorizontal.Panel1.Controls.Add($this.dgv);
        $this.SpContainHorizontal.Panel1.Controls.Add($this.chkShowHistory);

        # 履歴コメントを表示する
        $this.SpContainHorizontal.Panel2.Controls.Add($this.lblHistoryContents);
        $this.SpContainHorizontal.Panel2.Controls.Add($this.txtHistoryContents);
        $this.SpContainHorizontal.Panel2.Controls.Add($this.lblComments);
        $this.SpContainHorizontal.Panel2.Controls.Add($this.txtComments);
        $this.SpContainHorizontal.Panel2.Controls.Add($this.btnAddComment);
       
        $this.SpContainVertical.Panel1.Controls.Add($this.tvTasks);

        # コンボボックスの選択肢を生成
        #  進捗状況コンボボックス
        $this.cboStatus.Items.Clear();
        $this.cboStatus.Items.Add($this.STATUS_TODO);
        $this.cboStatus.Items.Add($this.STATUS_DOING);
        $this.cboStatus.Items.Add($this.STATUS_DONE);

        #  色コンボボックス
        $this.cboColorLabel.Items.Clear();
        $this.cboColorLabel.Items.Add("");
        $this.cboColorLabel.Items.Add($this.LABELCOLOR_RED);
        $this.cboColorLabel.Items.Add($this.LABELCOLOR_PINK);
        $this.cboColorLabel.Items.Add($this.LABELCOLOR_PURPLE);
        $this.cboColorLabel.Items.Add($this.LABELCOLOR_ORANGE);
        $this.cboColorLabel.Items.Add($this.LABELCOLOR_YELLOW);
        $this.cboColorLabel.Items.Add($this.LABELCOLOR_GREEN);
        $this.cboColorLabel.Items.Add($this.LABELCOLOR_LIGHTBLUE);
        $this.cboColorLabel.Items.Add($this.LABELCOLOR_BLUE);
        $cboColorLabel_Leave={
            $sender = $args[0];
            $e = $args[1];
            $sender.FindForm().SetStickyNoteColor($sender);
        }
        $this.cboColorLabel.add_Leave($cboColorLabel_Leave);
       
        # ■ 各種イベントを追加
        # タイトル
        $txtTitle_Leave={
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();
            $form.tvTasks.SelectedNode.Text = $form.txtTitle.Text;
            $form.SaveFile($form.tvTasks.SelectedNode.Tag);
        }
        $this.txtTitle.add_Leave($txtTitle_Leave);

        # 期限
        $txtLimitDay_Leave={
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();
            $sender.Text = $form.GetDateTryConvertFromString($sender.Text);
        }
        $this.txtLimit.add_Leave($txtLimitDay_Leave);

        # 期限通知日数
        $txtAlertDayCount_Leave = {
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();
            if ([double]::TryParse($sender.Text,[ref]$null) -ne $true){
                $sender.Text = "";
                [System.Windows.Forms.MessageBox]::Show("数値で入力してください", "エラー");
                $sender.Focus();
            } elseif ($sender.Text.Length -ne 1) {
                $sender.Text = "";
                [System.Windows.Forms.MessageBox]::Show("1桁で入力してください", "エラー");
                $sender.Focus();
            }

        }
        $this.txtAlertDayCount.add_Leave($txtAlertDayCount_Leave);

        # 処理状況
        $cboStatus_Leave={
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();
            $form._SetTreeNodeStyle($form.tvTasks.SelectedNode,$form.cboStatus.Text,$form.txtLimit.Text,$form.txtAlertDayCount.Text,$form.cboColorLabel.Text);
            $form.SaveFile($form.tvTasks.SelectedNode.Tag);
        }
        $this.cboStatus.add_Leave($cboStatus_Leave);

        # 履歴表示
        $chkShowHistory_CheckedChange={
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();

            $form.dgv.CurrentCell = $null; # Nullにしておかないと行を非表示にした時にエラー "現在のカレンシー マネージャーの位置に関連付けられた行を非表示にすることはできません。"が発生
            foreach($dgvRow in $form.dgv.Rows){
                if ($dgvRow.Cells[$form.DGV_COLNAME_KBN].Value -eq $form.PATTERN_CHANGELOG) {$dgvRow.Visible=$form.chkShowHistory.Checked;}
            }
        }
        $this.chkShowHistory.add_CheckedChanged($chkShowHistory_CheckedChange);

        # 履歴一覧
        $dgv_CurrentCellChanged = {
            $sender = $args[0];
            $e = $args[1];
            $form =$sender.FindForm();
            if ( $form.dgv -eq $null) { return;}
            if ( $form.dgv.CurrentRow -eq $null) { return;}
           
            $form.txtHistoryContents.Text = $form.dgv.CurrentRow.Cells[$form.DGV_COLNAME_CONTENTS].Value;

        }
        $this.dgv.add_CurrentCellChanged($dgv_CurrentCellChanged);

        # ■TreeView関連
        #  選択変更前に画面上の内容を保存する
        $TreeView_BeforeSelect ={
            $sender = $args[0];
            $e = $args[1];
           
            $CurrentSelectedNode = $sender.SelectedNode;
            if ($CurrentSelectedNode -ne $null){
                $thisForm = $sender.FindForm();
                $thisForm.SaveFile($CurrentSelectedNode.Tag);
                $CurrentSelectedNode.Text = $thisForm.GetTaskTitle($CurrentSelectedNode.Tag);
            }
        };
        $this.tvTasks.add_BeforeSelect($TreeView_BeforeSelect);
       
        #  選択された内容を画面上に表示する
        $TreeView_AfterSelect={
            $sender = $args[0];
            $e = $args[1];
            $sender.FindForm().SetDataFromFile($e.Node.Tag)
        };
        $this.tvTasks.add_AfterSelect($TreeView_AfterSelect);

        #  TreeViewのDragDrop処理
        $TreeView_ItemDrag = {
            $sender = $args[0];
            $e = $args[1];
            [TreeView]$tv = $sender;
            $tv.SelectedNode = $e.Item;
            $tv.Focus();
            # ノードのドラッグを開始する
            $dde = $tv.DoDragDrop($e.Item , [System.Windows.Forms.DragDropEffects]::All);
        };
        $TreeView_DragOver = {
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();

            #ドラッグされているデータがTreeNodeか調べる
            if ($e.Data.GetDataPresent([TreeNode])){
                $e.Effect = [DragDropEffects]::Move;
            } else {
                # TreeNodeでなければ受け入れない
                $e.Effect = [DragDropEffects]::None;
            }

            # マウス下のNodeを選択する
            if ($e.Effect -ne [DragDropEffects]::None)
            {
                [TreeView] $tv = $sender;
                # マウスのあるNodeを取得する
                [TreeNode] $target = $tv.GetNodeAt($tv.PointToClient([Point]::new($e.X, $e.Y)));
                #ドラッグされているNodeを取得する
                [TreeNode] $source =$e.Data.GetData([TreeNode]);
                #マウス下のNodeがドロップ先として適切か調べる
                if (($target -ne $Null) -And ($target -ne $source) -And ($form.IsChildNode($source, $target) -ne $True))
                {
                    if ( $target.IsSelected -eq $false) {
                        $tv.SelectedNode = $target;
                    }
                }
                else {
                    $e.Effect = [DragDropEffects]::None;
                }
            }
        };
        $TreeView_DragDrop = {
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();

            if ($e.Data.GetDataPresent([TreeNode])){
                $e.Effect = [DragDropEffects]::Move;
                [TreeView] $tv = $sender;
                # ドロップされたデータ(TreeNode)を取得
                [TreeNode] $source = $e.Data.GetData([TreeNode]);
                # ドロップ先のTreeNodeを取得する
                [TreeNode] $target = $tv.GetNodeAt($tv.PointToClient([Point]::new($e.X, $e.Y)));
                # マウス下のNodeがドロップ先として適切か調べる
                if (($target -ne $Null) -And ($target -ne $source) -And ($form.IsChildNode($source, $target) -ne $True))
                {
                    $dicInfoSource = New-Object System.IO.DirectoryInfo($source.Tag);
                    $dicInfoTarget = New-Object System.IO.DirectoryInfo($target.Tag);

                    $strChangeLog = "";
                    $strChangeLog += $form.GetTaskTitle($dicInfoSource.Parent.FullName) + "`r`n";
                    $strChangeLog += "↓↓↓↓↓↓`r`n";
                    $strChangeLog += $form.GetTaskTitle($dicInfoTarget.FullName) + "`r`n";

                    $tv.SelectedNode = $source;
                    $form.OpenFile($dicInfoSource.Tag)

                    $strPathFrom = $dicInfoSource.FullName;
                    $strPathTo = $dicInfoTarget.FullName;
                    $strId_To = $form.GetIdFromPath($strPathTo);
                   
                    # フォルダを移動
                    Move-Item $strPathFrom $strPathTo
                   
                    # 移動した履歴を登録する
                    $form._AddHistory("フォルダ移動" + "`r`n" + $strChangeLog,$false);
   
                    # TreeViewを再構築
                    $form.RefreshTreeViewNodes();

                    $target = $form.fdicNodesById[$strId_To];
                    $target.Expand();

                    #  追加されたNodeを選択
                    $tv.SelectedNode = $target;

                } else {$e.Effect = [DragDropEffects]::None;}

            } else {
                # TreeNodeでなければ受け入れない
                $e.Effect = [DragDropEffects]::None;
            }

        }
        $this.tvTasks.add_ItemDrag($TreeView_ItemDrag);
        $this.tvTasks.add_DragOver($TreeView_DragOver);
        $this.tvTasks.add_DragDrop($TreeView_DragDrop);

        # コメント追加ボタン
        $btnAddComment_Click = {
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.FindForm();
            $form._AddHistory($form.txtComments.Text,$False);
        }
        $this.btnAddComment.add_Click($btnAddComment_Click);

        # 画面上のキー押下処理
        $this.KeyPreview=$True;
        $KeyDownEvent={
                $sender = $args[0];
                $e = $args[1];
                $this.RunFunctionKeyDownEvents($sender,$e);
        }
        $this.add_KeyDown($KeyDownEvent);

        # DataGridViewを設定
        $this.DataGridViewInit();

        # レイアウトを再開
        $this.ResumeLayout();


    }
   
    # ------------------------------------------------------------------------------------------------------------
    # Function Key 押下時イベント
    # ------------------------------------------------------------------------------------------------------------
    RunFunctionKeyDownEvents([object] $sender, [KeyEventArgs] $e){
        $PushKeyCode= $e.KeyCode;
       
        $selectedTask = $this.tvTasks.SelectedNode;
        if (( $e.Control -eq $true) -And ( $e.KeyCode -eq ([System.Windows.Forms.Keys]::S)) ) {
            # 上書き保存し、Treeを再描画
            $this.SaveFile($selectedTask.Tag);
            $this.RefreshTreeViewNodes();
        }

        If ( $PushKeyCode -eq "F1" ) {
            #[System.Windows.Forms.MessageBox]::Show("押されたキーは:${PushKeyCode}です", "結果")

            # 下のレベルにタスクを追加
            if ($selectedTask -eq $null){ $this.AddTaskNode($this.GetDataFolderPath(), $false);}
            else {$this.AddTaskNode($selectedTask.Tag, $false);}

        } ElseIf ($PushKeyCode -eq "F2" ){

            # 同じレベルにタスクを追加
            if ($selectedTask -eq $null){ $this.AddTaskNode($this.GetDataFolderPath(), $false);}
            else {$this.AddTaskNode($selectedTask.Tag, $true);}
           
        } ElseIf ($PushKeyCode -eq "F3" ){
           
            # タスクを上へ移動
            if ($selectedTask -ne $null){ $this.MoveTask($selectedTask, $true);}

        } ElseIf ($PushKeyCode -eq "F4" ){
           
            # タスクを下へ移動
            if ($selectedTask -ne $null){ $this.MoveTask($selectedTask, $false);}

        } ElseIf ($PushKeyCode -eq "F5" ){
           
            # 再描画
            $this.RefreshTreeViewNodes();

        } ElseIf ($PushKeyCode -eq "F6" ){
            #$this.btnF06.PerformClick();
        } ElseIf ($PushKeyCode -eq "F7" ){
            #$this.btnF07.PerformClick();
        } ElseIf ($PushKeyCode -eq "F8" ){
            #$this.btnF08.PerformClick();
        } ElseIf ($PushKeyCode -eq "F9" ){
            #$this.btnF09.PerformClick();
        } ElseIf ($PushKeyCode -eq "F10" ){
            # [System.Windows.Forms.MessageBox]::Show("押されたキーは:${PushKeyCode}です", "結果")
            #$this.btnF10.PerformClick();
        } ElseIf ($PushKeyCode -eq "F11" ){
            #$this.btnF11.PerformClick();
        } ElseIf ($PushKeyCode -eq "F12" ){
            #$this.btnF12.PerformClick();
        }
    }

   
    # ------------------------------------------------------------------------------------------------------------
    # 渡された日付をyyyy/MM/dd形式に変換する
    # 変換できない場合は空白を返す
    # https://teratail.com/questions/118618
    # ------------------------------------------------------------------------------------------------------------
    [string]GetDateTryConvertFromString([string]$userInputDate){
        # 対応する入力パターン
        [string[]]$dateFormats = @(
            'yyyy/MM/dd'
            'yyyy/m/d'
            'yy/m/d'
            'yyyyMMdd'
        )

        # 適当な値で初期化
        [datetime]$parsedDate = [datetime]::MinValue

        # 変換して $parsedDate へ。失敗したら $parseSuccess が $false。
        [bool]$parseSuccess = [datetime]::TryParseExact(
                $userInputDate,
                $dateFormats,
                [Globalization.DateTimeFormatInfo]::CurrentInfo,
                [Globalization.DateTimeStyles]::AllowWhiteSpaces,
                [ref]$parsedDate
            )

        if ($parseSuccess) {
            #Write-Host ('Parse success. input = {0}' -f $userInputDate)
            return $parsedDate.ToShortDateString();
        } else {
            #Write-Host ('Parse fail. input = {0}' -f $userInputDate)
            return "";
        }

        return "";
    }


    # ------------------------------------------------------------------------------------------------------------
    # カラーコンボボックスの色に応じてラベルの色を変更する
    # ------------------------------------------------------------------------------------------------------------
    SetStickyNoteColor([ComboBox]$cbo){
        $form  = $cbo.FindForm();
        $form.lblStickyNote.BackColor = $form._GetColor($cbo.Text);
        $selectedNode = $form.tvTasks.SelectedNode;
        if($selectedNode -ne $null) {$selectedNode.BackColor =$form.lblStickyNote.BackColor; }
    }

    # ------------------------------------------------------------------------------------------------------------
    # 区分に応じて色のColorインスタンスを取得する
    # ------------------------------------------------------------------------------------------------------------
    [Color]_GetColor([string]$strColor) {
        if ($strColor -eq $this.LABELCOLOR_RED) {
            return [System.Drawing.Color]::FromArgb(248, 91, 89);
        } elseif ($strColor -eq $this.LABELCOLOR_PINK) {
            return [System.Drawing.Color]::FromArgb(255 ,189 , 255);
        } elseif ($strColor -eq $this.LABELCOLOR_PURPLE) {
            return [System.Drawing.Color]::FromArgb(198,133,255);
        } elseif ($strColor -eq $this.LABELCOLOR_ORANGE) {
            return [System.Drawing.Color]::FromArgb(255,176,104);
        } elseif ($strColor -eq $this.LABELCOLOR_YELLOW) {
            return [System.Drawing.Color]::FromArgb(248, 255, 89);;
        } elseif ($strColor -eq $this.LABELCOLOR_LIGHTBLUE) {
            return [System.Drawing.Color]::FromArgb(32,241,234);
        } elseif ($strColor -eq $this.LABELCOLOR_BLUE) {
            return [System.Drawing.Color]::FromArgb(124, 124, 255);;
        } elseif ($strColor -eq $this.LABELCOLOR_GREEN) {
            return [System.Drawing.Color]::FromArgb(167, 255, 156);
        }
        return [System.Drawing.Color]::FromArgb(255, 255, 255);
    }

    # ------------------------------------------------------------------------------------------------------------
    # Nodeの内容をフォーム変数に格納しておく
    # 連想配列に格納しておくことで、参照型であるClassを名前ですぐにインスタンスを取得し、高速にアクセスできる
    # ------------------------------------------------------------------------------------------------------------
    SetSystemKeyValues([string] $strFullPath,[TreeNode]$tnTgtNode){
        $this.fdicNodes.Add($strFullPath,$tnTgtNode);
        $this.fdicNodesById.Add($strFullPath.Substring($strFullPath.length- 17,17),$tnTgtNode);
    }

    # ------------------------------------------------------------------------------------------------------------
    # パスからタスクのIDを取得する(yyyyMMddHHmmssがID)
    # ------------------------------------------------------------------------------------------------------------
    [string] GetIdFromPath([string]$strFolderPath){
        return $strFolderPath.Substring($strFolderPath.Length - 17,17);
    }

    # ------------------------------------------------------------------------------------------------------------
    # あるTreeNodeが別のTreeNodeの子ノードか調べる
    #  引数1:親ノードか調べるTreeNode
    #  引数2:子ノードか調べるTreeNode
    #  戻り値:子ノードの時はTrue
    # ------------------------------------------------------------------------------------------------------------
    [bool] IsChildNode([TreeNode] $parentNode, [TreeNode] $childNode)
    {
        if ($childNode.Parent -eq $parentNode) {
            return $true;
        } elseif ($childNode.Parent -ne $Null) {
            return $this.IsChildNode($parentNode, $childNode.Parent);
        } else {
            return $false;
        }
    }

    # ------------------------------------------------------------------------------------------------------------
    # DataGridViewの初期設定を実施
    # ------------------------------------------------------------------------------------------------------------
    DataGridViewInit(){
       
        $this.dgv.Columns.Clear();
       
        $dc = $this.GetDataGridColumnText($this.DGV_COLNAME_TRKDATETIME,"登録日時",120,$this.DGV_ALIGN_MIDDLECENTER,$this.COLNAME_HISTORY_CREATEIONDATETIME);
        $this.dgv.Columns.Add($dc)
        $dc = $this.GetDataGridColumnText($this.DGV_COLNAME_KBN,"区分",50,$this.DGV_ALIGN_MIDDLECENTER,$this.COLNAME_HISTORY_PATTERN);
        $this.dgv.Columns.Add($dc)
        $dc = $this.GetDataGridColumnText($this.DGV_COLNAME_CONTROL,"コントロール",70,$this.DGV_ALIGN_MIDDLECENTER,$this.COLNAME_HISTORY_CONTROL);
        $this.dgv.Columns.Add($dc)
        $dc = $this.GetDataGridColumnText($this.DGV_COLNAME_HOSTNAME,"PC名",80,$this.DGV_ALIGN_MIDDLECENTER,$this.COLNAME_HISTORY_USERNAME);
        $this.dgv.Columns.Add($dc)
        $dc = $this.GetDataGridColumnText($this.DGV_COLNAME_CONTENTS,"内容",280,$this.DGV_ALIGN_MIDDLELEFT,$this.COLNAME_HISTORY_HISTORYCONTENTS);
        $this.dgv.Columns.Add($dc)

        # $dt = New-Object System.Data.DataTable;
        # $dt.Columns.Add("strInsDateTime",[string])
        # $dt.Columns.Add("strKbn",[string])
        # $dt.Columns.Add("strHostName",[string])
        # $dt.Columns.Add("strContents",[string])

        # $dr = $dt.NewRow();
        # $dr["strInsDateTime"] ="2023/12/16 12:10:05";
        # $dr["strKbn"] ="自動";
        # $dr["strHostName"] = (Get-ChildItem Env:\USERNAME).Value;
        # $dr["strContents"] ="データ更新" ;
        # $dt.Rows.Add($dr);

        $this.dgv.DataSource = $null;

    }

    # ------------------------------------------------------------------------------------------------------------
    # DataGridViewのColumnを取得する
    # ------------------------------------------------------------------------------------------------------------
    [DataGridViewTextBoxColumn]GetDataGridColumnText([string] $strName,[string]$strHeaderText,[int]$intWidth,[string]$strCellTextAligment,[string]$strDataPropName) {
        $dc = New-Object DataGridViewTextBoxColumn ;
        $dc.Name = $strName;
        $dc.HeaderText = $strHeaderText;
        $dc.Width = $intWidth;
        $dc.DefaultCellStyle.Alignment = $strCellTextAligment;
        $dc.HeaderCell.Style.Alignment = "MiddleCenter";
        $dc.ReadOnly=$True;
        $dc.AutoSizeMode = "NotSet"      # 処理速度向上
        $dc.SortMode = "NotSortable";    # 並び替えを行わないようにすることでヘッダのテキストを中央寄せにできる
        $dc.DataPropertyName = $strDataPropName;
        return $dc;
    }

    # ------------------------------------------------------------------------------------------------------------
    # Menuコントロール設定処理
    # ------------------------------------------------------------------------------------------------------------
    MenuControlInit(){
        $this.menuFormMain.SuspendLayout()

        #「ファイル(&F)」メニュー項目を作成する
        $fileMenuItem = New-Object ToolStripMenuItem;
        $fileMenuItem.Text = "ファイル(&F)";
        $this.menuFormMain.Items.Add($fileMenuItem);

        #「上書き保存(&S)」メニュー項目を作成する
        $saveMenuItem = New-Object ToolStripMenuItem;
        $saveMenuItem.Text = "上書き保存(&S)";
        $fileMenuItem.DropDownItems.Add($saveMenuItem);

        # セパレータ
        $sepa = New-Object ToolStripSeparator;
        $fileMenuItem.DropDownItems.Add($sepa);

        #「終了(&X)」メニュー項目を作成する
        $closeMenuItem = New-Object ToolStripMenuItem;
        $closeMenuItem.Text = "終了(&X)";
        $fileMenuItem.DropDownItems.Add($closeMenuItem);

        #「ファイル(&F)」メニュー項目を作成する
        $operateMenuItem = New-Object ToolStripMenuItem;
        $operateMenuItem.Text = "操作(&E)";
        $this.menuFormMain.Items.Add($operateMenuItem);

        #「再描画(&R)」メニュー項目を作成する
        $refreshMenuItem = New-Object ToolStripMenuItem;
        $refreshMenuItem.Text = "再描画(&R)";
        $refreshMenuItem_Click_RefreshTreeView={
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.OwnerItem.Owner.FindForm();
            $form.RefreshTreeViewNodes();
        }
        $refreshMenuItem.add_Click($refreshMenuItem_Click_RefreshTreeView);
        $operateMenuItem.DropDownItems.Add($refreshMenuItem);

        # セパレータ
        $sepa = New-Object ToolStripSeparator;
        $operateMenuItem.DropDownItems.Add($sepa);

        #「下のレベルに追加(&A)」メニュー項目を作成する
        $addMenuItem = New-Object ToolStripMenuItem;
        $addMenuItem.Text = "下のレベルに追加(F1)(&A)";
        $addMenuItem_Click_AddNode_Under={
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.OwnerItem.Owner.FindForm();
            $selectedTask = $form.tvTasks.SelectedNode;
            if ($selectedTask -eq $null){ $form.AddTaskNode($form.GetDataFolderPath(), $false);}
            else {$form.AddTaskNode($selectedTask.Tag, $false);}
            $form.ClearInit();
        }
        $addMenuItem.add_Click($addMenuItem_Click_AddNode_Under);
        $operateMenuItem.DropDownItems.Add($addMenuItem);

        #「同じレベルに追加(&M)」メニュー項目を作成する
        $addSameMenuItem = New-Object ToolStripMenuItem;
        $addSameMenuItem.Text = "同じレベルに追加(F2)(&M)";
        $addSameMenuItem_Click_AddNode_Same={
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.OwnerItem.Owner.FindForm();
            $selectedTask = $form.tvTasks.SelectedNode;
            if ($selectedTask -eq $null){
                # Nodeが一つもない場合は必ず下のレベルに追加にする
                $form.AddTaskNode($form.GetDataFolderPath(), $false);
            }
            else {$form.AddTaskNode($selectedTask.Tag, $true);}
           
            $form.ClearInit();

        }
        $addSameMenuItem.add_Click($addSameMenuItem_Click_AddNode_Same);
        $operateMenuItem.DropDownItems.Add($addSameMenuItem);

        #「削除(&D)」メニュー項目を作成する
        $deleteMenuItem = New-Object ToolStripMenuItem;
        $deleteMenuItem.Text = "削除(&D)";
        $operateMenuItem.DropDownItems.Add($deleteMenuItem);

        # セパレータ
        $sepa = New-Object ToolStripSeparator;
        $operateMenuItem.DropDownItems.Add($sepa);

        #「上へ(&U)」メニュー項目を作成する
        $upMenuItem = New-Object ToolStripMenuItem;
        $upMenuItem.Text = "タスクを上へ(F3)(&U)";
        $upMenuItem_Click_MoveUp={
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.OwnerItem.Owner.FindForm();
            $selectedTask = $form.tvTasks.SelectedNode;
            if ($selectedTask -eq $null){
                #[System.Windows.Forms.MessageBox]::Show("未選択です", "結果")
                return;
            }
            else {
                $form.MoveTask($selectedTask,$True);
            }
            #$form.ClearInit();
        }
        $upMenuItem.add_Click($upMenuItem_Click_MoveUp);
        $operateMenuItem.DropDownItems.Add($upMenuItem);

        #「下へ(&U)」メニュー項目を作成する
        $downMenuItem = New-Object ToolStripMenuItem;
        $downMenuItem.Text = "タスクを下へ(F4)(&D)";
        $upMenuItem_Click_MoveDown={
            $sender = $args[0];
            $e = $args[1];
            $form = $sender.OwnerItem.Owner.FindForm();
            $selectedTask = $form.tvTasks.SelectedNode;
            if ($selectedTask -eq $null){
                #[System.Windows.Forms.MessageBox]::Show("未選択です", "結果")
                return;
            }
            else {
                $form.MoveTask($selectedTask,$False);
            }
            #$form.ClearInit();
        }
        $downMenuItem.add_Click($upMenuItem_Click_MoveDown);
        $operateMenuItem.DropDownItems.Add($downMenuItem);

        # フォームにMenuStripを追加する
        $this.Controls.Add($this.menuFormMain);

        # フォームのメインメニューとする
        $this.MainMenuStrip = $this.menuFormMain;

        # レイアウトロジックを再開する
        $this.menuFormMain.ResumeLayout($false);
        $this.menuFormMain.PerformLayout();

    }

    # ------------------------------------------------------------------------------------------------------------
    # 選択されているNodeの下の階層にフォルダを追加したうえで、TreeViewのNodeに追加する
    # ------------------------------------------------------------------------------------------------------------
    RefreshTreeViewNodes() {
        # 展開状態を覚えておく
        $strSelectedNode = "";
        $selectedNode = $this.tvTasks.SelectedNode;
        if ($selectedNode -ne $null) {$strSelectedNode = $selectedNode.Tag.Substring($selectedNode.Tag.length-17,17)};
        $lstExpandNodes = New-Object 'System.Collections.Generic.List[string]';
        foreach ($key in $this.fdicNodes.Keys) {
            [TreeNode] $node = $this.fdicNodes[$key];
            if ($node.IsExpanded -eq $true) {
                $lstExpandNodes.Add($key.Substring($key.length-17,17));
            }
        }

        # クリア処理
        $this.SuspendLayout();
        $this.tvTasks.SuspendLayout();
        $this.tvTasks.Nodes.Clear();
        $this.fdicNodes.Clear();
        $this.fdicNodesById.Clear();

        # フォルダパスをすべて取得し、並び替えを行う
        $directrys = [System.IO.Directory]::GetDirectories($this.GetDataFolderPath(), "*", [System.IO.SearchOption]::AllDirectories);
        $directrys = $directrys | Sort-Object
        $parentNode = New-Object TreeNode;

        foreach ($path in $directrys){
            $dicInfo = New-Object System.IO.DirectoryInfo($path);
            $dicParentInfo = New-Object System.IO.DirectoryInfo($dicInfo.Parent.FullName);
           
            $node = New-Object TreeNode;
           
            # TreeNodeの値やフォントを設定する
            [System.Data.DataRow]$dr = $this.GetTaskDataRow($dicInfo.FullName)

            #  タイトル
            if ($dr[$this.COLNAME_CONTENTS_TITLE] -eq "") { $node.Text= "[No Title]";}
            else { $node.Text= $dr[$this.COLNAME_CONTENTS_TITLE]; }

            #  進捗状態に合わせてフォントを変更
            #  背景などのフォントスタイル設定のテスト
            $this._SetTreeNodeStyle($node,$dr[$this.COLNAME_CONTENTS_STATUS],$dr[$this.COLNAME_CONTENTS_LIMITDAY],$dr[$this.COLNAME_CONTENTS_LIMITALERTDAYCOUNT],$dr[$this.COLNAME_CONTENTS_COLORLABEL])

            # Nodeのタグ値にキーとなるパスを設定する
            $node.Tag = $path;

            # フォーム変数に覚えている全Nodeリストに追加する(忘れないようにすること)
            $this.SetSystemKeyValues($path.ToString(),$node);

            # タスクを追加する
            if ($dicParentInfo.FullName -eq $this.GetDataFolderPath() ){
                $this.tvTasks.Nodes.Add($node);
            } else {
                # 既に追加されているものから探してくる
                $parentNode = $this.fdicNodes[$dicParentInfo.FullName];
                $parentNode.Nodes.Add($node);
            }
        }

        # 事前に保存している内容で設定する(展開状況と選択ノードを元に戻す)
        foreach ($strId in $lstExpandNodes) {
            [TreeNode] $node = $this.fdicNodesById[$strId];
            $node.Expand();
        }
        if ($strSelectedNode -ne "")
        {
            $this.tvTasks.SelectedNode = $this.fdicNodesById[$strSelectedNode];
        };

        # 描画を開始
        $this.tvTasks.ResumeLayout();
        $this.ResumeLayout();

    }

    # ------------------------------------------------------------------------------------------------------------
    # Nodeのスタイルを設定する
    # ------------------------------------------------------------------------------------------------------------
    _SetTreeNodeStyle([TreeNode]$node,[string] $strStatus,[string] $strLimitDay,[string] $strAlertDayCount,[string] $strColorPattern) {
        # 初期化
        $node.NodeFont = New-Object Drawing.Font($this.Font, [System.Drawing.FontStyle]::Regular) ;
        $node.ForeColor = "Black";
       
        # 状態によってフォントを変更する
        if ($strStatus -eq $this.STATUS_DONE) {
            $node.NodeFont = New-Object Drawing.Font($this.Font, [System.Drawing.FontStyle]::Strikeout) ;
        } elseif ($strStatus -eq $this.STATUS_DOING) {
            $node.NodeFont = New-Object Drawing.Font($this.Font, [System.Drawing.FontStyle]::Italic) ;
            $node.ForeColor = "Blue";
        }

        $strLimitDay = $this.GetDateTryConvertFromString($strLimitDay);
        if (($strLimitDay -ne "") -And ($strStatus -ne $this.STATUS_DONE)) {
            [datetime]$parsedDate = [datetime]::Parse($strLimitDay);
            $intConvertCount = 0;
            if ([double]::TryParse($strAlertDayCount,[ref]$intConvertCount) -eq $true){
                $parsedDate.AddDays($intConvertCount);
            }

            [datetime]$now = [datetime]::Now;
            if ($parsedDate.ToShortDateString() -le $now.ToShortDateString()) {
                $node.NodeFont = New-Object Drawing.Font($this.Font, [System.Drawing.FontStyle]::Bold) ;
                $node.ForeColor = "Red";
            }
        }
       
        # ノードの背景色を設定
        if($strColorPattern -ne "") {$node.BackColor = $this._GetColor($strColorPattern); }

    }

    # ------------------------------------------------------------------------------------------------------------
    # 履歴を追加する
    # ------------------------------------------------------------------------------------------------------------
    _AddHistory([string]$strContents,[bool]$blnAutoHistory) {
        if ($this.fdsCurrentData -eq $null) {return;}
        if ($this.fdsCurrentData.Tables[$this.DATA_TABLE_NAME_CONTENT] -eq $null) {return;}

        if ($blnAutoHistory -eq $True) {
            [string]$strChangeLog = "";

            $dt = $this.fdsCurrentData.Tables[$this.DATA_TABLE_NAME_CONTENT];
           
            # タイトル
            if ($this.txtTitle.Text -ne $dt.Rows[0][$this.COLNAME_CONTENTS_TITLE]){
                $strChangeLog = "";
                $strChangeLog += $dt.Rows[0][$this.COLNAME_CONTENTS_TITLE] + "`r`n";
                $strChangeLog += "↓↓↓↓↓↓`r`n";
                $strChangeLog += $this.txtTitle.Text + "`r`n";
                $this._AddRow_Hisotory($this.PATTERN_CHANGELOG,"タイトル",$strChangeLog);
            };

            # 期限
            if ($this.txtLimit.Text -ne $dt.Rows[0][$this.COLNAME_CONTENTS_LIMITDAY]){
                $strChangeLog = "";
                $strChangeLog += $dt.Rows[0][$this.COLNAME_CONTENTS_LIMITDAY] + "`r`n";
                $strChangeLog += "↓↓↓↓↓↓`r`n";
                $strChangeLog += $this.txtLimit.Text + "`r`n";
                $this._AddRow_Hisotory($this.PATTERN_CHANGELOG,"期限",$strChangeLog);
            };

            # 期限前通知
            if ($this.txtAlertDayCount.Text -ne $dt.Rows[0][$this.COLNAME_CONTENTS_LIMITALERTDAYCOUNT]){
                $strChangeLog = "";
                $strChangeLog += $dt.Rows[0][$this.COLNAME_CONTENTS_LIMITALERTDAYCOUNT] + "`r`n";
                $strChangeLog += "↓↓↓↓↓↓`r`n";
                $strChangeLog += $this.txtAlertDayCount.Text + "`r`n";
                $this._AddRow_Hisotory($this.PATTERN_CHANGELOG,"期限前通知",$strChangeLog);
            };

            # 進捗状況
            if ($this.cboStatus.Text -ne $dt.Rows[0][$this.COLNAME_CONTENTS_STATUS]){
                $strChangeLog = "";
                $strChangeLog += $dt.Rows[0][$this.COLNAME_CONTENTS_STATUS] + "`r`n";
                $strChangeLog += "↓↓↓↓↓↓`r`n";
                $strChangeLog += $this.cboStatus.Text + "`r`n";
                $this._AddRow_Hisotory($this.PATTERN_CHANGELOG,"進捗状況",$strChangeLog);
            };

            # カラーラベル
            if ($this.cboColorLabel.Text -ne $dt.Rows[0][$this.COLNAME_CONTENTS_COLORLABEL]){
                $strChangeLog = "";
                $strChangeLog += $dt.Rows[0][$this.COLNAME_CONTENTS_COLORLABEL] + "`r`n";
                $strChangeLog += "↓↓↓↓↓↓`r`n";
                $strChangeLog += $this.cboColorLabel.Text + "`r`n";
                $this._AddRow_Hisotory($this.PATTERN_CHANGELOG,"進捗状況",$strChangeLog);
            };

            # カラーラベル
            if ($this.txtMember.Text -ne $dt.Rows[0][$this.COLNAME_CONTENTS_MEMBER]){
                $strChangeLog = "";
                $strChangeLog += $dt.Rows[0][$this.COLNAME_CONTENTS_MEMBER] + "`r`n";
                $strChangeLog += "↓↓↓↓↓↓`r`n";
                $strChangeLog += $this.txtMember.Text + "`r`n";
                $this._AddRow_Hisotory($this.PATTERN_CHANGELOG,"担当",$strChangeLog);
            };

            # 分類
            if ($this.txtClass.Text -ne $dt.Rows[0][$this.COLNAME_CONTENTS_CLASS]){
                $strChangeLog = "";
                $strChangeLog += $dt.Rows[0][$this.COLNAME_CONTENTS_CLASS] + "`r`n";
                $strChangeLog += "↓↓↓↓↓↓`r`n";
                $strChangeLog += $this.txtClass.Text + "`r`n";
                $this._AddRow_Hisotory($this.PATTERN_CHANGELOG,"分類",$strChangeLog);
            };

            # 内容
            if ($this.txtContents.Text -ne $dt.Rows[0][$this.COLNAME_CONTENTS_CONTENTS]){
                $strChangeLog = "";
                $strChangeLog += $dt.Rows[0][$this.COLNAME_CONTENTS_CONTENTS] + "`r`n";
                $strChangeLog += "↓↓↓↓↓↓`r`n";
                $strChangeLog += $this.txtContents.Text + "`r`n";
                $this._AddRow_Hisotory($this.PATTERN_CHANGELOG,"内容",$strChangeLog);
            };

            # 備考
            if ($this.txtNote.Text -ne $dt.Rows[0][$this.COLNAME_CONTENTS_NOTE]){
                $strChangeLog = "";
                $strChangeLog += $dt.Rows[0][$this.COLNAME_CONTENTS_NOTE] + "`r`n";
                $strChangeLog += "↓↓↓↓↓↓`r`n";
                $strChangeLog += $this.txtNote.Text + "`r`n";
                $this._AddRow_Hisotory($this.PATTERN_CHANGELOG,"分類",$strChangeLog);
            };

        } else {
            if ($strContents -ne "") {
                $this._AddRow_Hisotory($this.PATTERN_COMMENT,"コメント",$this.txtComments.Text);
            } else {
                $this._AddRow_Hisotory($this.PATTERN_AUTO,"",$strContents);
            }
        }

    }


    # ------------------------------------------------------------------------------------------------------------
    # 履歴一覧に値を追加する
    # ------------------------------------------------------------------------------------------------------------
    _AddRow_Hisotory([string]$strPattern,[string]$strControl,[string]$strHistoryContents){
        $dr = $this.fdsCurrentData.Tables[$this.DATA_TABLE_NAME_HISTORY].NewRow();
        $dr[$this.COLNAME_HISTORY_PATTERN] = $strPattern;
        $dr[$this.COLNAME_HISTORY_CONTROL] = $strControl;
        $dr[$this.COLNAME_HISTORY_CREATEIONDATETIME] = Get-Date -Format "yyyy/MM/dd HH:mm:ss";
        $dr[$this.COLNAME_HISTORY_USERNAME] = (Get-ChildItem Env:\USERNAME).Value;
        $dr[$this.COLNAME_HISTORY_HISTORYCONTENTS] = $strHistoryContents;
        $this.fdsCurrentData.Tables[$this.DATA_TABLE_NAME_HISTORY].Rows.Add($dr);
    }

    # ------------------------------------------------------------------------------------------------------------
    # 選択されているNodeの下の階層にフォルダを追加したうえで、TreeViewのNodeに追加する
    #  RefreshTreeViewNodesを使うとTreeViewのNodeがすべて再構築されるので、選択状態が消える
    # 毎回最新を取得して選択状態を取得したほうが安全か・・・?
    # ------------------------------------------------------------------------------------------------------------
    AddTaskNode([string] $strFolderPath,[bool] $blnSameLevel) {
        $strNow = Get-Date -Format "yyyyMMddhhmmssfff";
        $dicInfo = New-Object System.IO.DirectoryInfo($strFolderPath);
        if ($blnSameLevel -eq $true) {
            $dicInfo = $dicInfo.Parent;
        }
       
        $strFolderNo =  "0000" + ($dicInfo.GetDirectories().Count + 1) ;
        $strFolderNo = $strFolderNo.Substring($strFolderNo.Length - 4 ,4);
        $strNewFolderPath = $dicInfo.FullName + "\" +  $strFolderNo +  "_" + $strNow ;

        New-Item $strNewFolderPath -ItemType Directory;

        # Nodeを追加する
        $dicInfo = New-Object System.IO.DirectoryInfo($strNewFolderPath);
        $node = New-Object TreeNode;
        #$node.Text= $this.GetTaskTitle($dicInfo.FullName);
        $node.Tag = $dicInfo.FullName;
        # 全Nodeリストに追加する(忘れないようにすること)
        $this.SetSystemKeyValues($dicInfo.FullName,$node);
        # $this.fdicNodes.Add($dicInfo.FullName,$node);
        # $this.fdicNodesById.Add($dicInfo.FullName.Substring($dicInfo.FullName.length-14,14),$node);

        # 既に追加されているものから探してくる
        if ($dicInfo.Parent.FullName -eq $this.GetDataFolderPath() ){
            $this.tvTasks.Nodes.Add($node);
        } else {
            # 既に追加されているものから探してくる
            $parentNode = $this.fdicNodes[$dicInfo.Parent.FullName];
            $parentNode.Expand();
            $parentNode.Nodes.Add($node);
        }

        # 画面を初期化する
        $this.ClearInit();

        # ファイルを保存する
        $this.SaveFile($dicInfo.FullName);

        # TreeViewのNodeを再構築する
        $this.RefreshTreeViewNodes();

        # 追加したNodeを選択状態にすることで現在選択されているNodeの内容が保存される
        $this.tvTasks.SelectedNode = $this.fdicNodesById[$node.Tag.Substring($node.Tag.Length - 17,17)];
        # すぐに入力できるようにフォーカスを設定
        $this.txtTitle.Focus();
    }

    # ------------------------------------------------------------------------------------------------------------
    # タスクを移動する
    # ------------------------------------------------------------------------------------------------------------
    MoveTask([TreeNode]$selectedTask,[bool]$blnMoveUp) {
        $tnParent = $selectedTask.Parent;
       
        if ($tnParent -eq $null){return;}
        if ($tnParent.Nodes -eq $null){return;}

        $index = $tnParent.Nodes.IndexOf($selectedTask);
        $insertIdx = 0;
        if ($blnMoveUp) {
            $insertIdx = $index - 1;
            if ($insertIdx -lt 0 ) {
                [System.Windows.Forms.MessageBox]::Show("これ以上上に行けません", "エラー");
                return;
                }
        } else {
            $insertIdx = $index + 1;
            if ($insertIdx -gt $tnParent.Nodes.Count - 1 )
            {
                [System.Windows.Forms.MessageBox]::Show("これ以上下に行けません", "エラー");
                return;
            }
        }

        $selectedTask.Remove();
        $tnParent.Nodes.Insert($insertIdx, $selectedTask);
        $this.tvTasks.SelectedNode = $selectedTask;

        for ($i = 0; $i -lt $tnParent.Nodes.Count; $i++) {
            $dicInfo = New-Object System.IO.DirectoryInfo($tnParent.Nodes[$i].Tag);
            $strNo = ("0000" + ( $i + 1 ));
            $strNo = $strNo.Substring($strNo.Length - 4 , 4 );
            $strNewFolderName = $strNo + "_" + $dicInfo.Name.Substring($dicInfo.Name.Length - 17 , 17);
           
            # フォルダをリネーム(番号が変わる場合のみ)
            if ($dicInfo.Name -ne $strNewFolderName) {
                Rename-Item $dicInfo.FullName $strNewFolderName
            }
        }

        # TreeViewを再構築する
        $this.RefreshTreeViewNodes()

    }

    # ------------------------------------------------------------------------------------------------------------
    # ファイルを開いてタスクのタイトルを取得する
    # ------------------------------------------------------------------------------------------------------------
    [string]GetTaskTitle([string]$strDicPath) {
        if ($this.OpenFile($strDicPath) -eq $true ){
            $dt = $this.fdsCurrentData.Tables[$this.DATA_TABLE_NAME_CONTENT];
            if ($dt.Rows[0][$this.COLNAME_CONTENTS_TITLE] -eq "") { return "[No Title]" } # Titleが空白の場合にTreeView上で選択できなくなるため
            else {return $dt.Rows[0][$this.COLNAME_CONTENTS_TITLE];}
        } else {
            return "[Not Exists Task.xml]" + $strDicPath;
        }
    }

    # ------------------------------------------------------------------------------------------------------------
    # ファイルを開いてタスクのデータを返す
    # ------------------------------------------------------------------------------------------------------------
    [System.Data.DataRow]GetTaskDataRow([string]$strDicPath) {
        if ($this.OpenFile($strDicPath) -eq $true ){
            $dt = $this.fdsCurrentData.Tables[$this.DATA_TABLE_NAME_CONTENT];
            return $dt.Rows[0];
        } else {
            return $null;
        }
    }

    # ------------------------------------------------------------------------------------------------------------
    # ファイルを開いて画面に値を設定する
    # ------------------------------------------------------------------------------------------------------------
    SetDataFromFile([string]$strDicPath){
       
        $this.ClearInit();

        if ($this.OpenFile($strDicPath) -eq $true ){
            $dt = $this.fdsCurrentData.Tables[$this.DATA_TABLE_NAME_CONTENT];
            $this.txtTitle.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_TITLE];
            $this.txtLimit.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_LIMITDAY];
            $this.txtAlertDayCount.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_LIMITALERTDAYCOUNT];
            $this.cboStatus.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_STATUS];
            $this.cboColorLabel.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_COLORLABEL];
            $this.lblStickyNote.BackColor = $this._GetColor($this.cboColorLabel.Text);
            $this.txtMember.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_MEMBER];
            $this.txtClass.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_CLASS];
            $this.txtCreateDateTime.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_CREATEIONDATETIME];
            $this.txtContents.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_CONTENTS];
            $this.txtNote.Text = $dt.Rows[0][$this.COLNAME_CONTENTS_NOTE];
        }
    }

    # ------------------------------------------------------------------------------------------------------------
    # 画面上の値をクリアする
    # ------------------------------------------------------------------------------------------------------------
    ClearInit(){
        $this.txtTitle.Text = "";
        $this.txtLimit.Text = "";
        $this.txtAlertDayCount.Text = "3";
        $this.cboStatus.Text = "作業前";
        $this.cboColorLabel.Text = "";
        $this.txtMember.Text = "";
        $this.txtClass.Text = "";
        $this.txtCreateDateTime.Text = "";
        $this.txtContents.Text = "";
        $this.txtNote.Text = "";

        $this.DataGridViewInit();
    }

    # ------------------------------------------------------------------------------------------------------------
    # ファイルの内容を開く
    # ------------------------------------------------------------------------------------------------------------
    [bool]OpenFile([string]$strDicPath) {
        $strFilePath = $strDicPath + "\" + $this.DATA_FILE_NAME;
        if ((Test-Path $strFilePath) -eq $true) {
            $ds = New-Object System.Data.DataSet;
            $ds.ReadXml($strFilePath);
            $this.fdsCurrentData = $ds;
            if ($this.fdsCurrentData.Tables[$this.DATA_TABLE_NAME_HISTORY] -eq $null) {return $false;}

            $this.dgv.DataSource = $this.fdsCurrentData.Tables[$this.DATA_TABLE_NAME_HISTORY];

            $this.dgv.CurrentCell = $null; # Nullにしておかないと行を非表示にした時にエラー "現在のカレンシー マネージャーの位置に関連付けられた行を非表示にすることはできません。"が発生
            foreach($dgvRow in $this.dgv.Rows){
                if ($dgvRow.Cells[$this.DGV_COLNAME_KBN].Value -eq $this.PATTERN_CHANGELOG) {$dgvRow.Visible=$this.chkShowHistory.Checked;}
                if ($dgvRow.Cells[$this.DGV_COLNAME_KBN].Value -eq $this.PATTERN_COMMENT)
                {
                    foreach ($cell in $dgvRow.Cells){
                    $cell.Style.ForeColor = "Blue";
                }
            }
            }
            return $true;
        } else {
            return $false;
        }
    }    

    # ------------------------------------------------------------------------------------------------------------
    # 画面上の値をファイルに保存する
    # ------------------------------------------------------------------------------------------------------------
    SaveFile([string]$strDicPath) {
        $dicInfo = New-Object System.IO.DirectoryInfo($strDicPath);

        # 変更履歴を追加
        $this._AddHistory("",$true);

        $ds = New-Object System.Data.DataSet;
        $ds.DataSetName = "TaskDate";

        # コンテンツテーブル作成
        $dtContents = New-Object System.Data.DataTable;
        $dtContents.TableName = $this.DATA_TABLE_NAME_CONTENT;
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_TITLE,[string]);
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_LIMITDAY,[string]);
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_LIMITALERTDAYCOUNT,[string]);
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_STATUS,[string]);
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_COLORLABEL,[string]);
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_MEMBER,[string]);
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_CLASS,[string]);
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_CREATEIONDATETIME,[string]);
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_CONTENTS,[string]);
        $dtContents.Columns.Add($this.COLNAME_CONTENTS_NOTE,[string]);

        # データを登録
        $strDateTime = $strDicPath.Substring($strDicPath.Length - 17,17);
        $strDateTime = $strDateTime.Substring(0,4) + "/" + $strDateTime.Substring(4,2) + "/" + $strDateTime.Substring(6,2) + " " + $strDateTime.Substring(8,2) + ":" + $strDateTime.Substring(10,2) + ":" + $strDateTime.Substring(12,2) + ":" + $strDateTime.Substring(14,3)
        $dr = $dtContents.NewRow();
        $dr[$this.COLNAME_CONTENTS_TITLE]=$this.txtTitle.Text;
        $dr[$this.COLNAME_CONTENTS_LIMITDAY]=$this.txtLimit.Text;
        $dr[$this.COLNAME_CONTENTS_LIMITALERTDAYCOUNT]=$this.txtAlertDayCount.Text;
        $dr[$this.COLNAME_CONTENTS_STATUS]=$this.cboStatus.Text;
        $dr[$this.COLNAME_CONTENTS_COLORLABEL]=$this.cboColorLabel.Text;
        $dr[$this.COLNAME_CONTENTS_MEMBER]=$this.txtMember.Text;
        $dr[$this.COLNAME_CONTENTS_CLASS]=$this.txtClass.Text;
        $dr[$this.COLNAME_CONTENTS_CREATEIONDATETIME]=$strDateTime;
        $dr[$this.COLNAME_CONTENTS_CONTENTS]=$this.txtContents.Text;
        $dr[$this.COLNAME_CONTENTS_NOTE]=$this.txtNote.Text;
        $dtContents.Rows.Add($dr);
        $ds.Tables.Add($dtContents);

        # 履歴テーブル作成
        $dtHistorys = New-Object System.Data.DataTable;
        $dtHistorys.TableName = $this.DATA_TABLE_NAME_HISTORY;
        $dtHistorys.Columns.Add($this.COLNAME_HISTORY_CREATEIONDATETIME,[string]);
        $dtHistorys.Columns.Add($this.COLNAME_HISTORY_CONTROL,[string]);
        $dtHistorys.Columns.Add($this.COLNAME_HISTORY_PATTERN,[string]);
        $dtHistorys.Columns.Add($this.COLNAME_HISTORY_USERNAME,[string]);
        $dtHistorys.Columns.Add($this.COLNAME_HISTORY_HISTORYCONTENTS,[string]);

        $dt_dgv = $this.dgv.DataSource;
        foreach ($dr_dgv in $dt_dgv.Rows) {
            $dr = $dtHistorys.NewRow();
            $dr[$this.COLNAME_HISTORY_PATTERN]=$dr_dgv[$this.COLNAME_HISTORY_PATTERN];
            $dr[$this.COLNAME_HISTORY_CREATEIONDATETIME]=$dr_dgv[$this.COLNAME_HISTORY_CREATEIONDATETIME];
            $dr[$this.COLNAME_HISTORY_CONTROL]=$dr_dgv[$this.COLNAME_HISTORY_CONTROL];
            $dr[$this.COLNAME_HISTORY_USERNAME]=$dr_dgv[$this.COLNAME_HISTORY_USERNAME];
            $dr[$this.COLNAME_HISTORY_HISTORYCONTENTS]=$dr_dgv[$this.COLNAME_HISTORY_HISTORYCONTENTS];
            $dtHistorys.Rows.Add($dr);
        }

        # 新規追加の場合は、新規登録された履歴を登録。履歴が0件だとエラーが発生する
        if ($dtHistorys.Rows.Count -eq 0 ) {
            $dr = $dtHistorys.NewRow();
            $dr[$this.COLNAME_HISTORY_PATTERN]=$this.PATTERN_AUTO;
            $dr[$this.COLNAME_HISTORY_CREATEIONDATETIME] = Get-Date -Format "yyyy/MM/dd HH:mm:ss";
            $dr[$this.COLNAME_HISTORY_CONTROL]="-";
            $dr[$this.COLNAME_HISTORY_USERNAME] = (Get-ChildItem Env:\USERNAME).Value;
            $dr[$this.COLNAME_HISTORY_HISTORYCONTENTS]="新規作成";
            $dtHistorys.Rows.Add($dr);
        }

        $ds.Tables.Add($dtHistorys);
        $ds.WriteXml($dicInfo.FullName + "\" + $this.DATA_FILE_NAME);
        # 保存したファイルを再度開くことでfdsの内容を変更する
        $this.OpenFile($dicInfo.FullName)

    }    

    # ------------------------------------------------------------------------------------------------------------
    # データを保存しているフォルダを取得する
    # ------------------------------------------------------------------------------------------------------------
    [string] GetDataFolderPath(){
        return  ($this.fstrCurrentPath + "\Data");
    }

}

#   呼び出し用のMain.ps1は別途作成する必要がある
# Debug用 デバッグする際にはコメントアウトを削除し、VisualStudioCodeなどでF5。事前に「Add-Type -AssemblyName System.Windows.Forms;」「Add-Type -AssemblyName System.Windows.Forms;」の実行が必要
# [Application]::EnableVisualStyles();
# $form = [frm010_000_Projet]::new();
# $form.fstrCurrentPath = $CurrentDir; # インスタンス化してから、スクリプト上で設定しないと、クラスの中ではMyInvocationが取得できない。
# $form.StartPosition="CenterScreen";   # 列挙体は文字列で指定する必要がある
# $form.ShowDialog();

PowerShellでEdgeを自動化(インストール不要。参考:郵便追跡サービス自動操作)

1.経緯について  RPAのソフトをインストールできないので、これまでVBSでCreateObjectでブラウザの自動操作をすることがたまにあった。 ※いざというときの手札として持っているだけで安心感が段違い  見た目上IEがインストールされていなくても、CreateObject...