[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『ListBox間でリストの値を移動』(やさもん)
お世話になります。
ListBox1に複数列セルの内容を表示させております。
これを・・・
ListBox1で複数選択したリストを
ListBox2に転記させたいと考えております。
単列の転記はできたのですが
見よう見まねで、作成した複数列のリスト転記が分からず困っております。
すみません・・・^^;
アドバイスの程よろしくお願いします。
'2つのListBoxを連動させる(ListBox1の選択内容をListBox2へ表示)
'単列の転記
Private Sub CommandButton1_Click()
Dim i As Integer
If ListBox1.ListIndex = -1 Then Exit Sub For i = 0 To ListBox1.ListCount - 1 If ListBox1.Selected(i) Then ListBox2.AddItem ListBox1.List(i) End If Next i
End Sub
'複数列の転記
Sub CommandButton2_Click()
Dim i As Integer Dim n As Integer
n = 2 '開始行 For i = 0 To ListBox1.ListCount - 1 '選択されているかチェック If ListBox1.Selected(i) = True Then ListBox2.List(i, 0).Value = ListBox1.List(i, 0) ListBox2.List(i, 1).Value = ListBox1.List(i, 1) ListBox2.List(i, 2).Value = ListBox1.List(i, 2) n = n + 1 End If Next i End Sub
< 使用 Excel:Excel2010、使用 OS:Windows7 >
質問をお願いします^^;
重複項目は移動できないようにしたいのですがどのようにすればよろしいのでしょうか?
アドバイスの程よろしくお願いします。
'ListBox間移動(追記)
'※移動元のリストを切り取って転記
Private Sub CommandButton1_Click()
Dim i As Integer
If ListBox1.ListIndex = -1 Then Exit Sub
For i = ListBox1.ListCount - 1 To 0 Step -1
If ListBox1.Selected(i) Then
With ListBox2 .AddItem ListBox1.List(i, 0), .ListCount .List(.ListCount - 1, 1) = ListBox1.List(i, 1) End With ListBox1.RemoveItem i
End If Next i
End Sub
(やさもん) 2014/06/07(土) 17:00
>重複項目は移動できない
ListBox1で既にListBox2に移動済みの項目は、再度選択され、ボタンクリック時に移動処理を行ってもその行は、移動しないという事ですか?
方法1
最初に ListBox2.Clear を行い、ListBox2は、常に何もないところから登録を始める
最初に何もないのですから、重複することはありません。
但し、一つだけ選択して追加移動ということはできませんが・・・。
方法2
ListBox1にメンバ設定時に実際に登録する複数列以外にもう一つ列を追加し、そこに連番を入れます。
ListBox2に移行時にもその連番も移行します。
登録時には、この連番列に同じ番号があるかないかのチェックを行います。 あれば、未登録 なければ、登録 という手順でコードを書きます。
尚、連番として、List列を追加しても表示はさせないように設定します(ColumnsCount)。
(ichinose) 2014/06/07(土) 17:52
ありがとうございます。
ListBox内に重複項目があった場合削除するコードを
ネットで探しましたが、分かりませんでした。
もしよろしければ、もう少しアドバイスいただけますでしょうか?
よろしくお願いします。
(やさもん) 2014/06/07(土) 19:11
前投稿は、撤回です。 重複の意味を間違えていました。というより、重複の意味がわかりません。
私とやさもんさんが 同じブックを見るようにしましょう。
新規ブックにて、
ユーザーフォームを一つ作成してください(UserForm1)
このUserForm1に以下の順序でコントロールを作成してください。 コントロールの位置や大きさは、適当でよいです(コードで調整します)。
リストボックス(ListBox1) コマンドボタン(CommandButton1) リストボックス(ListBox2)
UserForm1のモジュールに
'====================================================================== Option Explicit Private Sub CommandButton1_Click() Dim idx As Long If ListBox1.ListIndex = 0 Then Exit Sub For idx = ListBox1.ListCount - 1 To 0 Step -1 If ListBox1.Selected(idx) Then With ListBox2 .AddItem ListBox1.List(idx, 0), .ListCount .List(.ListCount - 1, 1) = ListBox1.List(idx, 1) .List(.ListCount - 1, 2) = ListBox1.List(idx, 2) End With ListBox1.RemoveItem idx End If Next idx End Sub '================================================================================= Private Sub UserForm_Initialize() With Me .Width = 568 .Height = 190 End With With ListBox1 .Left = 18 .Top = 24 .Width = 210 .Height = 75 .ColumnCount = 3 .MultiSelect = fmMultiSelectMulti .ColumnWidths = "50;30;50" .List() = Evaluate("{""磯野波平"",54,""磯野家の大黒柱"";""磯野フネ"",53,""旧姓 石田"";" & _ """フグ田サザエ"",24,""実写版の初代は、江利チエミ"";""フグ田マスオ"",28,""早稲田大学卒業"";" & _ """磯野カツオ"",11,""想像通り B型"";""磯野ワカメ"",9,""実写版の初代は、松島トモ子"";" & _ """フグ田タラオ"",3,""太陽にほえろ と関係が深い""}")
End With With ListBox2 .Left = 330 .Top = 24 .Width = 210 .Height = 75 .ColumnCount = 3 .ColumnWidths = "50;30;50" End With With CommandButton1 .Left = 252 .Top = 50 .Width = 54 .Height = 24 .Caption = ">>" End With End Sub
標準モジュールに
Option Explicit Sub main() UserForm1.Show End Sub
以上です。
mainを実行してみてください。UserForm1が表示され、
ListBox1には、サザエさん一家の名前が表示されています。
ListBox1の中から、フグ田姓のみ選択して、[>>]ボタンをクリックしてください。
選択したフグ田姓の方だけがListBox2に移動し、ListBox1からは、削除されています。
さて、この例だと
>重複項目は移動できない
どのようなことなのでしょうか?
(ichinose) 2014/06/08(日) 11:06
丁寧に解説ありがとうございます。
ListBox1からListBox2へ値を移動する際は、解説と同じように
ListBox1から削除するようにしております。
選択→移動(ListBox1の選択したList削除)
If ListBox1.Selected(i) Then
↓
(転記処理)
↓
'ListBox1で選んだ値をリストから削除
ListBox1.RemoveItem i
そして、質問の意図ですが
(申し訳ありません・・・説明不足で・・・^^;)
※仕様上の問題もあると思いますが目をつぶってください。
ListBox1へのリスト読み込みは、複数シートの内容読み込むように
シート分のコマンドボタンを用意してListBoxに読み込んでおります。
※各sheetには、同じ名前の人が登録されていることがあります。
※各sheetを読み込む際には、ListBox1の内容を一旦クリアにして新規に読み込む形をとっております。
結果
sheet1の内容を選択しListBox2へ転記させる際に、各sheetの内容を
「読み込み→転記→読み込み→転記・・・」としていると
同じ名前の人がいることに気づかずに、ListBox2へ転記してしまうのです。
そのため
ListBox1の内容を読み込みを行う際に
ListBox2の中にあるリストに「重複データ」があれば、除外(削除)する処理方法
を考えているところです。
すみませんよろしくお願いします。
(やさもん) 2014/06/08(日) 14:07
(1)
「ListBox1の内容を」ListBox2へ読み込みを行う際に
ListBox2の中にあるリストに「重複データ」があれば、除外(削除)する処理方法
(2)
ListBox1に「シートの内容を」読み込みを行う際に
ListBox2の中にあるリストに「重複データ」があれば、除外(削除)する処理方法
ネットで探すと(2)の方法のほうが圧倒的に多いようです。
ListBox1にシートの内容を読み込む際に
↓
ListBox2に転記してあるデータに重複がないかチェック
↓
ListBox2のリストとシートの内容に重複があればシートの重複内容を除いてListBox1へセット
(やさもん) 2014/06/08(日) 14:27
Listbox2に登録されていたら、Listbox1に登録しないという仕様なら、 Listbox2のListプロパティを使って対象メンバがあるかないかを調べればよいと思います。
サザエさんのデータで言えば、
以下のようなデータ設定がされているんですよね?
前投稿と同じブックの標準モジュールに
'================================================================================== Sub データ設定() With Worksheets("sheet1") .Range("a1:c8").Value = Evaluate("{""氏名"",""年齢"",""備考"";" & _ """磯野波平"",54,""磯野家の大黒柱"";""磯野フネ"",53,""旧姓 石田"";" & _ """フグ田サザエ"",24,""実写版の初代は、江利チエミ"";""フグ田マスオ"",28,""早稲田大学卒業"";" & _ """磯野カツオ"",11,""想像通り B型"";""磯野ワカメ"",9,""実写版の初代は、松島トモ子"";" & _ """フグ田タラオ"",3,""太陽にほえろ と関係が深い""}") End With With Worksheets("sheet2") .Range("a1:c5").Value = Evaluate("{""氏名"",""年齢"",""備考"";" & _ """波野ノリスケ"",24,""サザエのいとこ"";" & _ """波野タイ子"",22,""ノリスケの妻"";" & _ """波野イクラ"",1,""原作と外見の差が大きい"";" & _ """フグ田タラオ"",3,""太陽にほえろとの関係が深い""}") End With
End Sub
Sheet1とSheet2というシート名は用意しておいてください。
データ設定を実行すると、Sheet1 Sheet2にデータが設定されます。
先のUserform1のモジュールは 以下のように変更してください
'======================================================================== Option Explicit Private Sub CommandButton1_Click() Dim idx As Long If ListBox1.ListIndex = 0 Then Exit Sub For idx = ListBox1.ListCount - 1 To 0 Step -1 If ListBox1.Selected(idx) Then With ListBox2 .AddItem ListBox1.List(idx, 0), .ListCount .List(.ListCount - 1, 1) = ListBox1.List(idx, 1) .List(.ListCount - 1, 2) = ListBox1.List(idx, 2) End With ListBox1.RemoveItem idx End If Next idx End Sub Private Sub UserForm_Initialize() With Me .Width = 568 .Height = 190 End With With ListBox1 .Left = 18 .Top = 24 .Width = 210 .Height = 75 .ColumnCount = 3 .MultiSelect = fmMultiSelectMulti .ColumnWidths = "50;30;50" End With With ListBox2 .Left = 330 .Top = 24 .Width = 210 .Height = 75 .ColumnCount = 3 .ColumnWidths = "50;30;50" End With With CommandButton1 .Left = 252 .Top = 50 .Width = 54 .Height = 24 .Caption = ">>" End With End Sub
更に標準モジュールに
'=================================================================== Sub フォーム表示() Dim rng As Range Dim crng As Range With UserForm1 .ListBox1.Clear End With With ActiveSheet Set rng = .Range("a2", .Cells(.Rows.Count, "a").End(xlUp)) End With If rng.Row > 1 Then For Each crng In rng If Not chk_listbox2(crng.Value) Then With UserForm1.ListBox1 .AddItem crng.Value .List(.ListCount - 1, 1) = crng.Offset(0, 1).Value .List(.ListCount - 1, 2) = crng.Offset(0, 2).Value End With End If Next End If UserForm1.Show vbModeless End Sub Function chk_listbox2(ByVal c_val As Variant) As Boolean Dim g0 As Long chk_listbox2 = False With UserForm1.ListBox2 For g0 = 0 To .ListCount - 1 If .List(g0, 0) = c_val Then chk_listbox2 = True Exit For End If Next End With End Function
これで Sheet1をアクティブにして、「フォーム表示」を実行してリストボックスを操作した後、
Userform1を表示した状態でSheet2をアクティブにして再度、「フォーム表示」を実行してください。
Listbox2に名前がある登場人物は、削除されてListbox1に登録されるはずです。 登録するか否かのチェック方法は他にも方法がありますが、基本的な方法を提示しました。 (ichinose) 2014/06/09(月) 00:44
ありがとうございます。
試した所、確かにListBox2に名前がある人は、ListBox1に重複して読み込まないようになっていました。
実際のファイルで、試してみます。
(やさもん) 2014/06/09(月) 08:12
リストを新たに読み込む際に、ListBox2に名前がある人は
ListBox1に読み込まないようにする方法は下記コードが判断しているのでしょうか?
比較の方法は・・・
「セル1列目」と「ListBox2の1列目」でかつ「文字列」の場合は削除されるようです。
※数値の場合はダメでした。
例えば・・・
1.検索値が、文字列ではなく数値(ID番号)だった場合
2.セルの2列目にID番号があり
ListBox1とListBox2には、ID番号が1列目の場合
色々数値を替えてやってみましたが、理解できず、書き込みさせてもらいました。
Function chk_listbox2(ByVal c_val As Variant) As Boolean Dim g0 As Long
chk_listbox2 = False
With UserForm2.ListBox2
For g0 = 0 To .ListCount - 1
If .List(g0, 0) = c_val Then
chk_listbox2 = True
Exit For
End If
Next
End With
End Function
すみません、よろしくお願いします。
(やさもん) 2014/06/09(月) 21:45
>色々数値を替えてやってみましたが、理解できず、書き込みさせてもらいました。
そのやったコードを見せてください。 >ListBox1に読み込まないようにする方法は下記コードが判断しているのでしょうか? そうです、この chk_listbox2というFunctionプロシジャーです。
そのコードを以下のように訂正してください。
Function chk_listbox2(ByVal c_val As Variant) As Boolean Dim g0 As Long Dim wkstr As String chk_listbox2 = False With UserForm1.ListBox2 For g0 = 0 To .ListCount - 1 wkstr = .List(g0, 0) If wkstr = c_val Then chk_listbox2 = True Exit For End If Next End With End Function
まだこれは、サザエさん登場人物名で重複をチェックしているコードです。
サザエさんの年齢を25にしてください。
これで年齢にダブりがなくなりますから、この年齢をIDに見立てることができますよね?
これで、年齢がダブらないように比較するには、どこを変更すればよいか?
考えてみてください。
年齢で チェックできれば、元のデータでも行けると思います。
(ichinose) 2014/06/10(火) 09:14
ありがとうございました。
おかげさまで、アドバイス通りやってみたところできました。
あとバグがないか探ってみます。
解決です(^^)
(やさもん) 2014/06/12(木) 12:17
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.