質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

11467閲覧

Excel VBA 意図しないところでChangeイベントが発生する

kolobokkule

総合スコア19

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2019/02/25 11:29

編集2019/02/25 13:47

前提・実現したいこと

VBAで入力情報の修正フォームを書いています。

フォーム上の値を修正したのち、実行すると、
'メイン処理
With ListBox1
Dim TargetIndex As Integer
TargetIndex = .ListIndex
のあたりで、
Private Sub ListBox1_Change()のところに戻ってしまい、リストボックス内の値が変わることなく、修正前の状態のままになってしまいます

Changeに戻らないようにするにはどうすればよいでしょうか。
Application.EnableEventではやはり解決できませんでした。

対策あれば教えていただきたいです。
よろしくお願いいたします。

※追記

2番目のソースコードを参考に今回のコードを書いたのですが、そちらではChangeイベントが発生しないまま進みます。
何の違いがあってこのようなことが起こるのか、教えていただきたいです。
よろしくお願いいたします。

該当のソースコード

Excel

1Option Explicit 2 3Private Sub UserForm_Initialize() 4 Worksheets("マスタ").Select 5 6 'リストボックスの設定 7 With ListBox1 8 .Font.Size = 10 9 .ColumnCount = 8 10 .ColumnWidths = "0;30;30;30;100;100;120" 11 .TextAlign = fmTextAlignLeft 12 .Font.Name = "MS ゴシック" 13 14 '「マスタ」シートのセルの内容をリストボックスに転記 15 Dim i As Integer 16 Dim LastRow As Integer 17 LastRow = Range("A65536").End(xlUp).Row 18 For i = 2 To LastRow 19 .AddItem Cells(i, 1).Value 20 .List(.ListCount - 1, 1) = Cells(i, 2).Value 21 .List(.ListCount - 1, 2) = Cells(i, 3).Value 22 .List(.ListCount - 1, 3) = Cells(i, 4).Value 23 .List(.ListCount - 1, 4) = Cells(i, 5).Value 24 .List(.ListCount - 1, 5) = Cells(i, 6).Value 25 .List(.ListCount - 1, 6) = Cells(i, 7).Value 26 .List(.ListCount - 1, 7) = Cells(i, 8).Value 27 Next 28 End With 29 30 'IDを変更不可能にする 31 txtID.Locked = True 32End Sub 33 34Private Sub ListBox1_Change() 35 With ListBox1 36 Dim targetRow As Integer 37 targetRow = .ListIndex 38 39 txtID.Text = .List(targetRow, 0) 40 txtName.Text = .List(targetRow, 5) 41 txtFurigana.Text = .List(targetRow, 6) 42 cmbNen.Text = .List(targetRow, 1) 43 cmbKumi.Text = .List(targetRow, 2) 44 txtNum.Text = .List(targetRow, 3) 45 cmbSex.Text = .List(targetRow, 4) 46 txtRemark.Text = .List(targetRow, 7) 47 End With 48End Sub 49 50Private Sub btnCUpdate_Click() 51 '「基本情報」を修正する 52 Dim msg As String, title As String 53 msg = "修正します。よろしいですか?" 54 title = "修正の確認" 55 56 Dim res As Integer 57 res = MsgBox(msg, vbYesNo + vbInformation, title) 58 If res = vbNo Then Exit Sub 59 60 'メイン処理 61 With ListBox1 62 Dim TargetIndex As Integer 63 TargetIndex = .ListIndex 64 .List(TargetIndex, 1) = cmbNen.Text 65 .List(TargetIndex, 2) = cmbKumi.Text 66 .List(TargetIndex, 3) = txtNum.Text 67 .List(TargetIndex, 4) = cmbSex.Text 68 .List(TargetIndex, 5) = txtName.Text 69 .List(TargetIndex, 6) = txtFurigana.Text 70 .List(TargetIndex, 7) = txtRemark.Text 71 End With 72 73 'シートのデータを変更 74 Dim tRow As Integer 75 tRow = CInt(txtID.Text) + 1 76 Cells(tRow, 2).Value = cmbNen.Text 77 Cells(tRow, 3).Value = cmbKumi.Text 78 Cells(tRow, 4).Value = txtNum.Text 79 Cells(tRow, 5).Value = cmbSex.Text 80 Cells(tRow, 6).Value = txtName.Text 81 Cells(tRow, 7).Value = txtFurigana.Text 82 Cells(tRow, 8).Value = txtRemark.Text 83 84 '各コントロールのクリア 85 cmbNen.Text = "" 86 cmbKumi.Text = "" 87 txtNum.Text = "" 88 cmbSex.Text = "" 89 txtName.Text = "" 90 txtFurigana.Text = "" 91 txtRemark.Text = "" 92End Sub 93 94Private Sub btnClose_Click() 95 Unload Me 96End Sub

Changeイベントが発生せずに進むコード

Option Explicit Private Sub btnClose_Click() Unload Me End Sub Private Sub btnDelete_Click() Dim strMsg As String Dim strTitle As String Dim res As Integer 'MsgBoxの戻り値を格納 strMsg = ListBox1.List(ListBox1.ListIndex, 1) 'リストボックスで選択された値の2列目(第2引数「1」)の値を変数に格納 strMsg = strMsg & " を削除します。よろしいですか?" strTitle = "削除の確認" res = MsgBox(strMsg, vbYesNo + vbExclamation, strTitle) If res = vbNo Then Exit Sub '削除の処理 Dim TargetRow As Integer TargetRow = ListBox1.Value + 1 'Valueプロパティにはリストボックスの選択された行の1列目の値が格納されているので、ここでは商品IDが変数に格納される Cells(TargetRow, 8).Value = 1 'リストボックスの行を削除/更新 ListBox1.RemoveItem ListBox1.ListIndex '選択されている行番号(ListBox1.ListIndex)を引数に指定して削除 End Sub Private Sub btnUpdate_Click() Dim Msg As String, Title As String Msg = "修正します。よろしいですか?" Title = "修正の確認" Dim res As Integer res = MsgBox(Msg, vbYesNo + vbInformation, Title) If res = vbNo Then Exit Sub 'メイン処理(vbYes) With ListBox1 Dim TargetIndex As Integer TargetIndex = .ListIndex 'どの行が選択されているかを変数に格納 .List(TargetIndex, 1) = txtGoods.Text .List(TargetIndex, 2) = cboCategory.Value .List(TargetIndex, 3) = txtMaker.Text .List(TargetIndex, 4) = FormatAddSpace(Format(txtPrice.Text, "#,##0"), 10) .List(TargetIndex, 5) = txtUnit.Text .List(TargetIndex, 6) = txtRemark.Text End With 'シートのデータを更新 Dim TargetRow As Integer TargetRow = CInt(txtID.Text) + 1 Cells(TargetRow, 2).Value = txtGoods.Text Cells(TargetRow, 3).Value = cboCategory.Text Cells(TargetRow, 4).Value = txtMaker.Text Cells(TargetRow, 5).Value = txtPrice.Text Cells(TargetRow, 6).Value = txtUnit.Text Cells(TargetRow, 7).Value = txtRemark.Text '各コントロール値のクリア txtID.Text = "" txtGoods.Text = "" cboCategory.Text = "" txtMaker.Text = "" txtPrice.Text = "" txtUnit.Text = "" txtRemark.Text = "" End Sub Private Sub ListBox1_Change() With ListBox1 Dim TargetRow As Integer '現在選択されている項目を識別し、行番号を変数に格納 TargetRow = .ListIndex 'ListBox.Textには選択された行の値が格納されている(複数列の場合は1列目の値) txtID.Text = .Text txtGoods.Text = .List(TargetRow, 1) cboCategory.Text = .List(TargetRow, 2) txtMaker.Text = .List(TargetRow, 3) txtPrice.Text = Trim(.List(TargetRow, 4)) 'スペース削除 txtUnit.Text = .List(TargetRow, 5) txtRemark.Text = .List(TargetRow, 6) '修正ボタンと削除ボタンを有効にする btnUpdate.Enabled = True btnDelete.Enabled = True End With End Sub Private Sub UserForm_Initialize() '「商品マスタ」をフォームが表示されたときに選択する Worksheets("商品マスタ").Select 'リストボックスの設定 With ListBox1 .Font.Size = 10 .ColumnCount = 7 .ColumnWidths = "50;100;80;80;100;30;70" .TextAlign = fmTextAlignLeft .Font.Name = "MS ゴシック" 'リストボックスにデータを表示させる Dim i As Integer, LastRow As Integer LastRow = Range("A65536").End(xlUp).Row For i = 2 To LastRow If Cells(i, 8).Value <> 1 Then .AddItem FormatAddSpace(Cells(i, 1).Value, 4) .List(.ListCount - 1, 1) = Cells(i, 2).Value .List(.ListCount - 1, 2) = Cells(i, 3).Value .List(.ListCount - 1, 3) = Cells(i, 4).Value .List(.ListCount - 1, 4) = FormatAddSpace(Format(Cells(i, 5).Value, "#,##0"), 10) .List(.ListCount - 1, 5) = Cells(i, 6).Value .List(.ListCount - 1, 6) = Cells(i, 7).Value End If Next End With '商品IDを変更不可能にする txtID.Locked = True '修正ボタンと削除ボタンを無効にしておく btnUpdate.Enabled = False btnDelete.Enabled = False End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2019/02/25 11:44

マークダウンの終わりの```がありません。
guest

回答3

0

ベストアンサー

イベントの意味を理解して適切なイベントを利用しましょう。

今回、Changeイベントを利用してますが、これだとコードでデータを変更しても発生します。AfterUpdateイベントを使えば、ユーザーが変更した時には発生しますが、コードでデータを変更した場合は発生しませんので、今回の要件ならAfterUpdateイベントを使えば解決です。

Changeイベントでフラグを使って回避するという方法もありますが、冗長な感じがぬぐえません。


追記の2つのコードを見比べても違いはないようなので、後者はChangeイベントが発生しないというのはちょっと考えにくいです。

投稿2019/02/26 01:40

hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kolobokkule

2019/02/26 02:03

AfterUpdateに変更したところ、うまく動いてくれました!本当にありがとうございます。 フラグを使うと他の部分で不具合が生じてしまうため、悩んでおりました。 同じような処理が何度も出てくるため、今回の回答は本当にありがたかったです。
guest

0

フォームにはApplication.EnableEvents = Falseは効かなかったと思います。

vba

1Private Sub ListBox1_Change() 2 Static ChangingFrag As Boolean 3 If ChangingFrag Then Exit Sub 4 ChangingFrag = True 5 '途中略 6 ChangingFrag = False 7End Sub

とすれば良いかと。

投稿2019/02/26 00:00

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

メイン処理部分で、リストボックスの内容変更してるので、Changeイベントが発生しています。

VBA

1 'メイン処理 2 With ListBox1 3 Dim TargetIndex As Integer 4 TargetIndex = .ListIndex 5 .List(TargetIndex, 1) = cmbNen.Text '←これ以降

XXXXXさんへ Excel VBA セルに書き込み時にLISTBOXのChangeイベントが発生について

投稿2019/02/25 12:06

編集2019/02/25 12:12
sazi

総合スコア25184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kolobokkule

2019/02/25 13:30

それはわかっています。 URLありがとうございます。しかし私では解決に結びつけることはできませんでした。
kolobokkule

2019/02/25 13:48

追記のようなコードですと、イベントが発生しませんでした。 書いておいて情けないのですが、その原因が分かりません。 何か気づくところはありますでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問