[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『テキストボックス連動について』(真由美)
いつも大変お世話になっております
教えて頂けたら幸いです
下記の様にComboBox3にTextboxを紐つけていますが
新規入力の場合 textboxを空白にする方法を教えて下さい
現在は タイトル行が表示されてしまいます
お手数ですが宜しくお願いいたします
Private Sub ComboBox3_Change()
Dim 行
行 = ComboBox3.ListIndex + 1 TextBox6.Text = Worksheets("LIST").Cells(行 + 1, 3) TextBox7.Text = Worksheets("LIST").Cells(行 + 1, 2)
End Sub
< 使用 Excel:Excel2010、使用 OS:Windows7 >
ComboBoxの利便性が消えてしまいます
ComboBoxをlistboxのように普段は使用しています
リストに無いものをわざわざ リストに追加しなくても
良い様にComboBoxを使用していますので
リスト選択で無い場合
キーボード使用による新規に入力の場合に
紐つくtextboxを空白にしたいのです
(真由美) 2017/01/05(木) 11:59
新規入力 ということは、コンボボックスのリストからの選択ではなく、ボックスに手入力ということですね。
Changeイベントを使う問題点は後回しにして
ComboBox3.LisnIndex が < 0 (0未満、実際には-1) の場合はリストにないということで TextBox の値を "" にしてやればいいと思います。
で、結果オーライですけど、Changeイベントの注意点を。
たとえばリストが aaaa と abcd の2件だったとして、リストから選ばずにボックス内に入力する場合、 a とタイプすると、プロパティ設定が規定値であれば、ボックス内は aaaa が選ばれたことになります。 ListIndex は 0 、Value は aaaa。
次に a のあとに b をタイプすると、ボックス内は abcd が選ばれた状態で、ListIndexが1、Valueは abcd。
結果オーライなんですが、1文字タイプのたびにイベントが発生します。
このボックスに xyz をいれたとします。
x で発生。ListIndex は -1。続いて、y。Value が xy で発生。ListIndex は -1。さらに z。Valueがxyzで発生。 ListIndex は -1。
繰り返しますが、今回のテーマでは『結果オーライ』です。 でも、ユーザーフォームの TextBox や ComboBox では 1文字タイプごとに Changeイベントが発生します。
このことは、ロジックによっては、重大な不具合の原因になる可能性があります。 十分注意して使うとともに、できれば Changeイベントではなく AfterUpdate や BeforeUpdate という Exit系のイベントを使うことをおすすめします。
(β) 2017/01/05(木) 12:10
>ComboBoxの利便性が消えてしまいます
あれ?じゃぁなんでテキストボックスとコンボボックスを連動させるなんてめんどくさい
ことやってるんですか?
コンボボックスの機能だけで間に合いませんか?
まぁ、いまのままでいくなら、
手入力時に、
ComboBox3.ListIndex
が何を返すかによってIf文で条件分岐したらいいのですが、
コンボボックスに必要な列数を表示するだけで、
十分用が足りると思いますが。。。。
(まっつわん) 2017/01/05(木) 12:37
失礼します。
>>コンボボックスに必要な列数を表示するだけで、 >>十分用が足りると思いますが。。。。
確かにドロップダウンリストには表示されていますけど、別コントロールに移ると これらが何であったか、見えなくなりますね。
なので、操作者に対する利便性ということもあるんだろうと思いますよ。 βであれば、そういった場合は、TextBox ではなく Label に表示しますけど。
ただ、まっつわんさんの提言は、重要ですね。リスト内に格納しておけば、シート上のセルからの抽出ではなく リスト内の値参照で可能ですから。微々たる差とはいえ、メモリー内参照とオブジェクト参照の効率の差異は ありますね。
(β) 2017/01/05(木) 12:45
>十分注意して使うとともに、できれば Changeイベントではなく AfterUpdate や BeforeUpdate という Exit系のイベントを使うことをおすすめします。
次の所にカーソルを持って行かないと イベントが発生しないって
文句言われて 致し方なく Changeイベントで逃げています
>ComboBox3.LisnIndex が < 0 (0未満、実際には-1) の場合はリストにないということで TextBox の値を "" にしてやればいいと思います。
IF条件で頑張って作ってみます
>TextBox ではなく Label に表示しますけど。
labelだと直接入力が出来なくなりますから 無理だと思います
ただ表示させるだけでなく 別シートに転記させてます
まっつわん様
コメント有難う御座います
>テキストボックスとコンボボックスを連動させるなんてめんどくさい
ことやってるんですか?
製品名 製品コード ロッド
カットレタス ( 6入り) 3292416 6
ケールサラダ(4入り) 3932560 4
千切りキャベツ (12入り) 3943109 12
このようなリストで 製品名をCombBoxに割り当てています
リストも100以上あるのですけどね
その時に 製造コード ロッドをtextboxに表示させています
新製品等が出れば当然リストにはありません
そのためのリスト更新を行ってくれる担当者もいない為
新規入力が絶対不可欠で 又リスト更新の役割
又 入力ミスを防ぐ為の連動を取っています
IFに関しては有難う御座います
考えてみます
皆様本当に有難う御座います
出来なかったら もう一度質問させていただきます
今後とも宜しくお願いいたします
(真由美) 2017/01/05(木) 13:41
笑われそうな 駄作ですけど
Private Sub CommandButton1_Click()
If Me.ComboBox3.Value = "" Then
MsgBox "製品名が未記入", 16 Me.ComboBox3.SetFocus Exit Sub End If If Me.ComboBox6.Value = "" Then MsgBox "ケース数が未記入", 16 Me.ComboBox6.SetFocus Exit Sub End If If Me.ComboBox7.Value = "" Then MsgBox "端数が未記入", 16 Me.ComboBox7.SetFocus Exit Sub End If If Me.ComboBox1.Value = "" Then MsgBox "製造工場が未記入", 16 Me.ComboBox1.SetFocus Exit Sub End If If Me.ComboBox2.Value = "" Then MsgBox "移管先が未記入", 16 Me.ComboBox2.SetFocus Exit Sub End If If Me.ComboBox5.Value = "" Then MsgBox "移管理由が未記入", 16 Me.ComboBox5.SetFocus Exit Sub End If
Dim intRow, i, k, kl, kk, km
With Worksheets("報告書")
.Range("B3") = Format(TextBox3.Text, "≪YYYY年 M月分≫")
End With With Sheets("報告書") intRow = .Cells(Rows.Count, "I").End(xlUp).Row i = 1 .Range("A" & i + intRow) = TextBox8.Text .Range("F" & i + intRow) = ComboBox3.Text .Range("E" & i + intRow) = TextBox7.Text .Range("B" & i + intRow) = ComboBox1.Text .Range("C" & i + intRow) = ComboBox2.Text .Range("D" & i + intRow) = TextBox1.Text .Range("G" & i + intRow) = ComboBox6.Text .Range("I" & i + intRow) = TextBox5.Text .Range("J" & i + intRow) = ComboBox5.Text .Range("H" & i + intRow) = ComboBox7.Text End With
With Worksheets("LIST")
intRow = .Cells(Rows.Count, "F").End(xlUp).Row k = 1 .Range("F" & k + intRow) = ComboBox5.Text .Range("$F$1:$F$100").RemoveDuplicates Columns:=1, Header:=xlYes End With
With Worksheets("LIST")
intRow = .Cells(Rows.Count, "B").End(xlUp).Row kl = 1 .Range("B" & k + intRow) = TextBox7.Text .Range("A" & k + intRow) = ComboBox3.Text .Range("C" & k + intRow) = TextBox6.Text
.Range("A:C").RemoveDuplicates Columns:=Array(2), Header:=xlYes
End With
With Worksheets("LIST") intRow = .Cells(Rows.Count, "D").End(xlUp).Row kk = 1 .Range("D" & kk + intRow) = ComboBox1.Text .Range("$D$1:$D$100").RemoveDuplicates Columns:=1, Header:=xlYes End With
With Worksheets("LIST") intRow = .Cells(Rows.Count, "D").End(xlUp).Row km = 1 .Range("D" & kk + intRow) = ComboBox2.Text .Range("$D$1:$D$100").RemoveDuplicates Columns:=1, Header:=xlYes End With
Call リスト並び替え
Dim r As Range Set r = Worksheets("LIST").Range("D2:D1000") ComboBox1.List = r.Value ComboBox2.List = r.Value ComboBox3.List = r.Offset(0, -3).Value ComboBox5.List = r.Offset(0, 2).Value ComboBox6.List = r.Offset(1, 4).Value ComboBox7.List = r.Offset(0, 4).Value ComboBox7.ListIndex = 0
ComboBox3.Text = "" TextBox7.Text = "" TextBox6.Text = "" TextBox5.Text = "" ComboBox6.Text = "" ComboBox1.Text = "" ComboBox2.Text = "" ComboBox5.Text = "" ComboBox7.Text = 0
Sheets("報告書").Select
End Sub
(真由美) 2017/01/05(木) 13:57
>>次の所にカーソルを持って行かないと イベントが発生しないって >>文句言われて 致し方なく Changeイベントで逃げています
そうなんですよね。いくら仕組みが云々といっても、特にComboBoxの場合は、操作者はリストから選択する場合が ほとんどですから、「ちゃんと選んでいるじゃないか!!」とクレームが入りますよね。
なので、COmboBoxの場合は「十分に配慮したコード記述」を行うということが必要でしょうね。 その最大のポイントは Changeイベントの最初に ListIndex が 0以上か未満かを判定することでしょうね。
>>labelだと直接入力が出来なくなりますから 無理だと思います >>ただ表示させるだけでなく 別シートに転記させてます
そういう要件であれば、もちろん TextBoxですね。
(β) 2017/01/05(木) 14:20
Option Explicit
Dim mEFlag As Boolean
Private Sub UserForm_Initialize()
Dim rngList As Range
With Worksheets("LIST").Range("A1").CurrentRegion Set rngList = Intersect(.Cells, .Offset(1)) End With
With Me.ComboBox1 .RowSource = rngList.Address(, , , True) .ColumnCount = 1 .ColumnWidths = "100" .ColumnHeads = False End With End Sub
Private Sub ComboBox1_Change()
Dim ix As Long Dim rngRow As Range
If mEFlag = True Then Exit Sub
ix = Me.ComboBox1.ListIndex With Application.Range(Me.ComboBox1.RowSource)
If ix >= 0 Then Set rngRow = .Rows(ix + 1) Else Set rngRow = .Rows(.Rows.Count + 1) End If End With With rngRow Me.TextBox1.Text = .Cells(2).Value Me.TextBox1.Tag = .Cells(2).Address(, , , True) Me.TextBox2.Text = .Cells(3).Value Me.TextBox2.Tag = .Cells(3).Address(, , , True) Me.ComboBox1.Tag = .Cells(1).Address(, , , True) End With End Sub
'登録ボタン押下
Private Sub CommandButton1_Click()
mEFlag = True With Me.TextBox1 Application.Range(.Tag).Value = .Text End With With Me.TextBox2 Application.Range(.Tag).Value = .Text End With With Me.ComboBox1 Application.Range(.Tag).Value = .Text .RowSource = Application.Range(.Tag).CurrentRegion.Address(, , , True) End With mEFlag = False End Sub
おっと、並び替えも要るのか。。。
製品コードでいいのかな。。。
ちょっとテストしてみよ^^
(まっつわん) 2017/01/05(木) 15:05
ご賛同有難う御座います
まっつわん様
いたせりつくせり状態でないと
私の体がいくつあっても足りません
笑い
コードまで有難う御座います
試してみて 使えるところは使わせていただきます
(真由美) 2017/01/05(木) 15:13
mEFlag = True With Me.TextBox1 Application.Range(.Tag).Value = .Text .Text = "" .Tag = "" End With With Me.TextBox2 Application.Range(.Tag).Value = .Text .Text = "" .Tag = "" End With With Me.ComboBox1 Application.Range(.Tag).Value = .Text .Text = "" .Tag = "" .ListIndex = -1 End With With Application.Range(Me.ComboBox1.RowSource).CurrentRegion With Intersect(.Cells, .Offset(1)) Me.ComboBox1.RowSource = .Address(, , , True) .Sort key1:=.Cells(2), Order1:=xlAscending, Header:=xlNo End With End With mEFlag = False End Sub
>私の体がいくつあっても足りません
あぁ、調べながらだとそうなりますね。
まぁ、僕も調べながら書いてるのですが、
だいたいの構造っていうか、なんとなくある程度は覚えてないと、
調べるのがつらいかもですね。
コンボボックスに値をセットする方法も3つあるので、
RowSource
List
Add
みたいなのがあったよな〜。。。
というのは何回かやっぱ作ってみないと覚えないのかなぁとは思います。
RowSouceでセットすると、シート上の変更がそのまま反映されるようですね^^
並べ替えしたいときは便利そうです^^
アドレスをTagプロパティに記録しておいて利用してますが、
コンボボックスのListIndexがいつでも利用可能ですので、
無駄なことをしてます^^;
(まっつわん) 2017/01/05(木) 15:37
有難う御座います
>RowSouceでセットすると、シート上の変更がそのまま反映されるようですね^^
って事は 毎回セットしなくてもいい
下記は不要ってことになりますね 毎回セットしてましたから
チャレンジしてみます
Dim r As Range Set r = Worksheets("LIST").Range("D2:D1000") ComboBox1.List = r.Value ComboBox2.List = r.Value ComboBox3.List = r.Offset(0, -3).Value ComboBox5.List = r.Offset(0, 2).Value ComboBox6.List = r.Offset(1, 4).Value ComboBox7.List = r.Offset(0, 4).Value ComboBox7.ListIndex = 0
本当に勉強になります
有難う御座います
(真由美) 2017/01/05(木) 15:55
コード拝見。
いくつか気になる点
・最後の、各ComboBoxにリストを再セットしているところですが、ComboBox7 が H2 からの H列、ComboBox6 が H3 からのH列。 つまり、ComboBox6には H2 がリストにはセットされないのですが、これでいいのでしょうか? ちょっと不自然な感じがします。
・上記も含めて、シートのレイアウトというか実態が見えないのですが、報告書シートには、最終行の次の同じ1行にセット。 一方、Listシートには、A:C列、D列、F列 それぞれ、別ものとして、それぞれの列の最終セルの次にセットした上で 重複を削除していますね。 まぁ、そういった性格のシートなんでしょうね。
・各ComboBox へのリストセットは Initialize でもあると思いますけど、アップされたコードの最後のものと 共通サブルーティン化することもできますかね。
と、まぁ見えないところもありますけど、コード記述の一例として、報告書シートと Listシートに転記する部分のみ。 (17:00 ちょこっと変更)
With Sheets("報告書") .Range("B3") = Format(TextBox3.Text, "≪YYYY年 M月分≫") With Cells(Rows.Count, "I").End(xlUp).Offset(1).EntireRow .Range("A1:J1").Value = Array(TextBox8.Text, ComboBox1.Text, ComboBox2.Text, TextBox1.Text, TextBox7.Text, _ ComboBox3.Text, ComboBox6.Text, ComboBox7.Text, TextBox5.Text, ComboBox5.Text) End With End With
With Worksheets("LIST") .Cells(Rows.Count, "F").End(xlUp).Offset(1).Value = ComboBox5.Text .Cells(Rows.Count, "B").End(xlUp).Offset(1).EntireRow.Range("A1:C1").Value = Array(ComboBox3.Text, TextBox7.Text, TextBox6.Text) With .Cells(Rows.Count, "D").End(xlUp) .Offset(1).Value = ComboBox1.Text .Offset(2).Value = ComboBox2.Text End With .Range("F1", .Range("F" & Rows.Count).End(xlUp)).RemoveDuplicates Columns:=1, Header:=xlYes .Range("B1", .Range("B" & Rows.Count).End(xlUp)).EntireRow.Columns("A:C").RemoveDuplicates Columns:=Array(2), Header:=xlYes .Range("D1", .Range("D" & Rows.Count).End(xlUp)).RemoveDuplicates Columns:=1, Header:=xlYes End With
(β) 2017/01/05(木) 16:06
>・最後の、各ComboBoxにリストを再セットしているところですが、ComboBox7 が H2 からの H列、ComboBox6 が H3 からのH列。
つまり、ComboBox6には H2 がリストにはセットされないのですが、これでいいのでしょうか?
ちょっと不自然な感じがします。
気がつきませんでした (;゚д゚)ァ....
>・上記も含めて、シートのレイアウトというか実態が見えないのですが、報告書シートには、最終行の次の同じ1行にセット。
一方、Listシートには、A:C列、D列、F列 それぞれ、別ものとして、それぞれの列の最終セルの次にセットした上で
重複を削除していますね。
まぁ、そういった性格のシートなんでしょうね。
リストの下のほうにあっても 直接入力してしまう方がいらっしゃるので
とりあえず 保険的にです
> ・各ComboBox へのリストセットは Initialize でもあると思いますけど、アップされたコードの最後のものと
共通サブルーティン化することもできますかね。
一行入力した後 新規書き込みの場合 一度開きなおさないと リストに反映されない為
2行目以降にも同じものを使う可能性がある為
毎回リストを読み込ませる って感じの素人的発想です
こんな短いコードまで 有難う御座います
あくまでも このファイルは テンプレートとして使用してまして
他の名前でで保存して終了みたいな感じです
Private Sub CommandButton2_Click()
On Error Resume Next If Sheets("報告書").Range("B6") = "" Then MsgBox "データ未入力です", 16 Exit Sub
Else Dim Target Sheets("報告書").Select Cells.Select Selection.Copy Sheets.Add After:=Sheets(Sheets.Count) ActiveSheet.Paste
Range("D6").Select Selection.Copy Range("I1").Select Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Range("i1").NumberFormatLocal = "yyyymmdd" ActiveSheet.Name = Range("i1").Text
Dim TargetPath As String Dim myFname As String Application.ScreenUpdating = False Application.DisplayAlerts = False
TargetPath = ThisWorkbook.Path
ActiveWorkbook.SaveAs TargetPath & "\" & _
Range("i1").Text & Range("B6").Text & Range("C6").Text
With Application .DisplayAlerts = False Sheets("LIST").Delete Sheets("報告書").Delete .DisplayAlerts = True End With ActiveWorkbook.Save ActiveWorkbook.Close End If End Sub
(真由美) 2017/01/05(木) 17:22
Private Sub CommandButton2_Click()
Dim wb As Workbook Dim sName As String
If Sheets("報告書").Range("B6").Value = "" Then MsgBox "データ未入力です", vbCritical Exit Sub Else Sheets("報告書").Copy Set wb = Workbooks(Workbooks.Count) With wb.Sheets(1) sName = Format(.Range("D6").Value, "yyyymmdd") .Range("I1").Value = sName .Name = sName wb.Close TargetPath & "\" & sName _ & .Range("B6").Text & .Range("C6").Text Set wb = Nothing End With End If End Sub (まっつわん) 2017/01/05(木) 19:49
たぶん突っ込みどころ満載かなって思って
あげてみました
本当に今回勉強になりました
有難う御座います
今後ともども宜しくお願いいたします
(真由美) 2017/01/06(金) 08:59
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.