初めまして。
早速で申し訳ないのですが、
現在、VB6で作成されたプログラムをVB2008で作動するように書き換えを行っている中で不明な点がありましたので、
是非アドバイスを頂けたらと思い投稿しました。
こちらの動作環境は VB2008,XP(SP3) です。
フォームに CombBox...cmbA0,cmbA1,cmbB0,cmbB1,cmbC0,cmbC1があります。
cmbA0の表示が変わったら、cmbA1の表示も変わる。
cmbA1の表示が変わっても、同じようにcmbA0の表示も変わる。
cmbB0,cmbB1,cmbC0,cmbC1についても同じ動作をします。
以下、VB6で作成されたプログラムです。
'cmbA0,cmbA1
Private Sub cmbA_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbA.SelectedIndexChanged
Dim Index As Short = cmbA.GetIndex(sender)
If cmbA(0).SelectedIndex <> cmbA(1).SelectedIndex Then
cmbA(1 - Index).SelectedIndex = cmbA(Index).SelectedIndex
End If
End Sub
'cmbB0,cmbB1
Private Sub cmbB_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbB.SelectedIndexChanged
Dim Index As Short = cmbB.GetIndex(sender)
If cmbB(0).SelectedIndex <> cmbB(1).SelectedIndex Then
cmbB(1 - Index).SelectedIndex = cmbB(Index).SelectedIndex
End If
End Sub
'cmbC0,cmbC1
Private Sub cmbC_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbC.SelectedIndexChanged
Dim Index As Short = cmbC.GetIndex(sender)
If cmbC(0).SelectedIndex <> cmbC(1).SelectedIndex Then
cmbC(1 - Index).SelectedIndex = cmbC(Index).SelectedIndex
End If
End Sub
cmbA(cmbA0,cmbA1),cmbB(cmbB0,cmbB1),cmbC(cmbC0,cmbC1)はVB6→VB2008にアップグレードの際、
Microsoft.VisualBasic.Compatibility.VB6のCombBoxArrayを使用し、配列になっています。
上記をまとめて…ニュアンス的には下記のような感じにしたいのですが、
IndexOfでは一次元の配列のインデックスしか取得できないということで、
インデックス取得ができずに躓いています。
Dim cmbABC()() As ComboBox
Private Sub Form_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
cmbABC = New ComboBox()() {New ComboBox() {cmbA0, cmbA1}, New ComboBox() {cmbB0, cmbB1}, New ComboBox() {cmbC0, cmbC1}}
End Sub
Private Sub cmbABC_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbA0.SelectedIndexChanged,cmbA1.SelectedIndexChanged,cmbB0....
Dim Index As Byte = Array.IndexOf(cmbABC, sender)
If cmbABC()(0).SelectedIndex <> cmbABC()(1).SelectedIndex Then
cmbABC()(1 - Index).SelectedIndex = cmbABC()(Index).SelectedIndex
End If
End Sub
cmbABC()の一次元であれば楽にできるのですが、それですと0と1の対になっている動作が出来ずどうしたものかと・・・
やりたいことは伝わりますでしょうか?
先駆者の方々のご指摘、アドバイスをお待ちしております。
どうぞよろしくお願いいたします。
> cmbABC()の一次元であれば楽にできるのですが、それですと0と1の対になっている動作が出来ずどうしたものかと・・・
必ず2個対になってると分かってるなら2で割った商と余りで分かるのでは?
こういう事で良いのかな?
Public Class Form1
Private cmbABC()() As ComboBox
Private Sub Form_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
cmbABC = New ComboBox()() {New ComboBox() {cmbA0, cmbA1}, New ComboBox() {cmbB0, cmbB1}, New ComboBox() {cmbC0, cmbC1}}
End Sub
Private Sub cmbABC_SelectedIndexChanged(ByVal sender As ComboBox, ByVal e As EventArgs) _
Handles cmbA0.SelectedIndexChanged, _
cmbA1.SelectedIndexChanged, _
cmbB0.SelectedIndexChanged, _
cmbB1.SelectedIndexChanged, _
cmbC0.SelectedIndexChanged, _
cmbC1.SelectedIndexChanged
Dim q = cmbABC.Where(Function(x) x.Contains(sender)).Select(Function(ComboBoxes) _
New With {ComboBoxes, .Index = Array.IndexOf(ComboBoxes, sender)}).First()
If q.ComboBoxes(0).SelectedIndex <> q.ComboBoxes(1).SelectedIndex Then
q.ComboBoxes(1 - q.Index).SelectedIndex = q.ComboBoxes(q.Index).SelectedIndex
End If
End Sub
End Class
特攻隊長まるるう様
アドバイスをありがとうございます。
商と余り…[\][MOD]を使用して、ということですね。なんとなく理解できそうなので、早速やってみます。
魔界の仮面弁士様
まさに!という回答を提示して頂きまして、ありがとうございます。理想の動作をしました。
しかしながらレベルが高すぎて、理解が追いついていません…。
少しずつ調べながら紐解いていきたいと思います。
確実に動作するプログラムを頂いておいて恐縮なのですが、
理解が及ばない箇所があるのと、先に頂いたアドバイスが実行できていない為、
理解し、実行したうえで解決にさせていただきたいと思っています。
解決は今しばらくお待ちください。
{{0, 1},{2, 3},{4, 5}} という階層配列にするのではなく、
{0, 1, 2, 3, 4, 5} という 1 次元配列にて管理するならば、
Dim Index1 As Integer = Array.IndexOf(cmbABC, sender)
Dim Index2 As Integer = Index1 + If(Index1 Mod 2 = 0, 1, -1)
If cmbABC(Index1).SelectedIndex <> cmbABC(Index2).SelectedIndex Then
cmbABC(Index2).SelectedIndex = cmbABC(Index1).SelectedIndex
End If
と書けますね。
あるいは、相方を Tag プロパティに
'Form の Load イベント
cmbA0.Tag = cmbA1
cmbA1.Tag = cmbA0
cmbB0.Tag = cmbB1
cmbB1.Tag = cmbB0
cmbC0.Tag = cmbC1
とセットしておけば、SelectedIndexChanged では
Dim a As ComboBox = DirectCast(sender, ComboBox)
Dim b As ComboBox = DirectCast(a.Tag, ComboBox)
If a.SelectedIndex <> b.SelectedIndex Then
b.SelectedIndex = a.SelectedIndex
End If
のように、短く記述することができます。
魔界の仮面弁士様
>If(Index1 Mod 2 = 0, 1, -1)
という書き方があることを初めて知りました。
なるほど、私のレベルでも直感的にわかりやすい構文になっていて、他でも使い回しが出来そうです。
[Tag]の使い方も今一解らなかったのですが、提示していただいたような使い方も出来るのですね。
こちらも非常に解りやすく、使えそうです。
今回は、この6つのCombBoxを他のイベントにも使うので、
上記に提示していただいた一次元配列にしてまとめようと思います。
以下、動作済みのプログラムにです。
Dim cmbABC(5) As ComboBox
Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
cmbABC = New ComboBox() {cmbA0, cmbA1, cmbB0, cmbB1, cmbC0, cmbC1}
For i = 0 To 5
AddHandler cmbABC(i).SelectedIndexChanged, AddressOf cmbABC_SelectedIndexChanged
Next
End Sub
Private Sub cmbABC_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim Index1 As Integer = Array.IndexOf(cmbABC, sender)
Dim Index2 As Integer = Index1 + If(Index1 Mod 2 = 0, 1, -1)
If cmbABC(Index1).SelectedIndex <> cmbABC(Index2).SelectedIndex Then
cmbABC(Index2).SelectedIndex = cmbABC(Index1).SelectedIndex
End If
End Sub
特攻隊長まるるう様
魔界の仮面弁士様
頂いたアドバイスと提示して頂いたプログラムをすばやく理解できるよう、
精進していきたいと思います。
次の機会があった時、またお力を貸していただければと思います。
お付き合い頂き、ありがとうございました。