明らかに必要なのは、ユーザーの選択内容をスプレッドシートに保存する前に、それらをメモリに保存する方法です。これを行うにはいくつかの方法がありますが、経験が浅いため、単一ノードに対するユーザーの選択を表す基本クラスと、各項目がクラスのインスタンスである配列を定義するのが最も簡単な方法を検討することをお勧めします。 –ユーザー選択のセット全体を保存します。
ノード選択クラスを定義します–単一ノードの選択を表します。
Public Class NodeSelection
Public CheckA As Boolean
Public PickAIndex As Integer = -1
Public CheckB As Boolean
Public PickBIndex As Integer = -1
Public CheckC As Boolean
Public PickCIndex As Integer = -1
Public ItemProcessed As Boolean
End Class
変数を定義します–フォームクラス(サブではありません)で:
Private _userPicks(89) As NodeSelection 'Array of user's selections
Private _previousIndex As Integer = -1 'Used to record the previously selected node
フォームのLoad
イベントで配列アイテムをインスタンス化します。
'Instantiate the class for each element of the array
For i As Integer = 0 To _userPicks.Count - 1
_userPicks(i) = New NodeSelection
Next
ユーザーの選択を追跡する:
新しいノードが選択されるたびに、以前に選択されたノードの配列項目を更新してから、現在のノードのコントロールをリセットする必要があります。これは、ツリービューのAfterSelect
イベントで行うのが最適です。
Private Sub TreeView1_AfterSelect(sender As Object, e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
'Exit if the click is on the parent node (Node0)
If e.Node.GetNodeCount(False) > 0 Then Return
UpdateNodeInfo()
'If the currently selected node has already been processed,
'restore user selection values to the controls,
'otherwise reset the controls
With _userPicks(e.Node.Index)
CheckBox1.Checked = If(.ItemProcessed, .CheckA, False)
ComboBox1.SelectedIndex = If(.ItemProcessed, .PickAIndex, -1)
CheckBox2.Checked = If(.ItemProcessed, .checkB, False)
ComboBox2.SelectedIndex = If(.ItemProcessed, .PickBIndex, -1)
CheckBox3.Checked = If(.ItemProcessed, .checkC, False)
ComboBox3.SelectedIndex = If(.ItemProcessed, .PickCIndex, -1)
End With
'Color the previous selection so the user can see it's been processed
If _previousIndex >= 0 Then TreeView1.Nodes(0).Nodes(_previousIndex).BackColor = Color.AntiqueWhite
'Record this (selected) node's index for updating when the next node is selected
_previousIndex = e.Node.Index
End Sub
Private Sub UpdateNodeInfo()
If _previousIndex < 0 Then Return 'No item has been set yet
With _userPicks(_previousIndex)
.CheckA = CheckBox1.Checked
.PickAIndex = If(.CheckA, ComboBox1.SelectedIndex, -1)
.CheckB = CheckBox2.Checked
.PickBIndex = If(.CheckB, ComboBox2.SelectedIndex, -1)
.checkC = CheckBox3.Checked
.PickCIndex = If(.checkC, ComboBox3.SelectedIndex, -1)
.ItemProcessed = True 'Record the fact the item has already been processed
End With
End Sub
スプレッドシートへの値の書き込み:
配列項目の更新ルーチンを別のプロシージャに配置していることに注意してください。これは、すべてをスプレッドシートに書き出す前に、最終的な選択を更新する必要があるためです。選択内容を保存するためのボタンがあると思います。そのためUpdateNodeInfo
、配列を反復処理して値を書き込む前に、そこからsubを呼び出す必要があります。値を繰り返し処理してスプレッドシートを更新する方法は次のとおりです。
For i As Integer = 0 To _userPicks.Count - 1
With _userPicks(i)
oSheet.Cells(3, i + 2) = "Node" & (i + 1).ToString
oSheet.Cells(9, i + 2) = "Node" & (i + 1).ToString
oSheet.Cells(4, i + 2) = If(.ItemProcessed AndAlso .CheckA, 1, 0)
oSheet.Cells(5, i + 2) = If(.ItemProcessed AndAlso .CheckB, 1, 0)
oSheet.Cells(6, i + 2) = If(.ItemProcessed AndAlso .checkC, 1, 0)
oSheet.Cells(10, i + 2) = If(.ItemProcessed AndAlso .CheckA, ComboBox1.Items(.PickAIndex).ToString, "")
oSheet.Cells(11, i + 2) = If(.ItemProcessed AndAlso .CheckB, ComboBox1.Items(.PickBIndex).ToString, "")
oSheet.Cells(12, i + 2) = If(.ItemProcessed AndAlso .checkC, ComboBox1.Items(.PickCIndex).ToString, "")
End With
Next
スプレッドシートを開いたり、保存したり、閉じたりする方法をすでに知っていると思いますので、その面はあなたにお任せします。ここで概説されている方法をよく理解し、そうでない場合は別の質問を投稿してください。
ついに
上記は、あなたがやろうとしていることを達成するためのかなり簡単な方法です。クラスに機能を追加する必要があると思われる場合は、プロパティをパブリックメンバーに置き換えることを検討する必要があります。とにかくそうする必要があると言う人もいます。また、ユーザー選択の完全なセットをList( T)配列ではなくオブジェクト。