|
▼のだめ さん:
>しかし何故?という部分が勉強も兼ねて知りたいので
>rirekiの不具合というのを教えていただければ嬉しいです。
>
>rireki_clickの
>cells(行,12) = rireki.value
>がおかしいのですが
>(activecell.value = rireki.valueでもおかしい)
>何故か一つ前の選択セル値が代入され
>選択したものが二つ新たに重複して追加されます。
>
>この原因を究明したいのでお力を貸していただければ幸いです。
それは Step実行してみれば分かります。
新規Bookを作成し、その「Sheet2」の[L3]以降に
以下のようなSourceList があったとします。
L3 Jan
L4 Feb
L5 Mar
L6 Apr
L7 May
L8 Jun
L9 Jul
L10 Aug
L11 Sep
L12 Oct
UserFormから値を選んで代入するシートは このリストのあるSheet2 ではないので
このままではデバッグしにくいので、Sheet1の [L3]以降に Sheet2のL列を
参照する数式を埋め込みます。
L3: =Sheet2!L3
のように。
また、Sub rireki_Click() 内のコードを 以下のように簡単化します。
変更点
(1)Public変数 「行」を使わず、アクティブセルへの代入とする。(ダブル
クリックされたセルが J列の5行目以降という判定は ダブルクリックさ
れたシートのほうですでにやっているので )
(2)リストボックス rirekiの何行目がClickされたかは 一行づつシートの
RowSourceを調べなくても、ListBox の何行目がClickされたか
すなわち rireki.ListIndex から分かる。これを ClickRow とする。
(3)ClickRowから2行目まで セルをひとつづつ下方へシフトするのは
For 〜 Next Loop のほうが速いし読みやすい。
これでも、同じ不具合が発生します。
Private Sub rireki_Click()
Dim ClickRow As Long
Debug.Print rireki.Value; rireki.ListIndex
ActiveCell.Value = rireki.Value '<-- ●この行にブレークポイント
ClickRow = rireki.ListIndex + 1 'リストの元データ範囲内の行Index
Dim i As Long
Dim r As Range
Set r = WS2.Range("L3").Resize(10)
For i = ClickRow To 2 Step -1
'ひとつ上のセル値をCopy
r.Item(i).Value = r.Item(i - 1).Value '▲セルの値を変更
Next
r.Item(1).Value = rireki.Value
'Me.Hide
End Sub
最初の行↓
Debug.Print rireki.Value; rireki.ListIndex
に、ブレークポイントを置いて、
シートSheet1 のJ列でダブルクリックして、rirekiリストの 「Apr」を
Clickしてみます。
rireki リストから 4つめの「Apr」を選ぶと、
ダブルクリックしたセルに「Apr」を代入して、
プログラムの実行は一時停止します。
これ以降は [F8]キーで 一行づつStep実行していきます。
そうすると
> 'ひとつ上のセル値をCopy
> r.Item(i).Value = r.Item(i - 1).Value '▲セルの値を変更
のところで、L列が
RowSource範囲の
1行目 Jan
2: Feb
3: Mar
4: Mar <------ 上のデータがCopyされる
5: May
6: Jun
・・・
のように、4行目の値が変わった途端、プログラムの実行は
> Private Sub rireki_Click()
に戻っていることが分かります。
これは RowSourceのリンク先のシートのセルの値が変わったので、
また新たなClickイベントが発生したということです。
ブレークポイントでStopしたとき
2回目のときの rireki.Value は「Mar」になっています。
プログラムでそうしたからです。
> r.Item(i).Value = r.Item(i - 1).Value '▲セルの値を変更
2回目の時のFor〜Next Loop による セル値のシフトは
2行目までうまく行きます。これはListIndexが3 で、その
ListIndexに対応するセルの値に今度は変更が無く
「Mar」のままだからです。
で、プロシージャ最後の
RowSource範囲の1行目にrireki.Valueを代入して
> r.Item(1).Value = rireki.Value
一旦終了するかのように見えます。
1: Mar
2: Jan
3: Feb
4: Mar
5: May
・・・
ところが、不思議なことに、Hideした後にも
3度目のイベントが発生して、プログラムの実行は
プロシージャの振り出しに戻って実行が続きます。
これはどうしてかというと、(たぶん) 「Mar」という
リスト項目があるListIndex が 3から 0(先頭)へ
移動したためです。2回目の時は ListIndex=3 の内容が
変化したため Click Event が発生しましたが、こんどは
ListIndexが変化したため またもや Eventが発生したと
いうことです。
ActiveCellにまた「Mar」を書き込み(ただし、ListIndex=0
つまり リストの先頭行の値を、です)、For〜Nextの
Nextを実行し、、、、
結局、ほんとに終わるまで、イミディエイト・ウィンドウを
みると、
Apr 3
Mar 3
Mar 0
Mar 0
Mar 0
Mar 0
Mar 0
Mar 0
Mar 0
Mar 3
Mar 3
Jan 0
Jan 0
Jan 0
回ものイベント処理を実行していることが分かります。
のだめ さんもそちらのデータで 上に書いたDebugを
実際にやって 確かめてみてください。
RowSourceを使うと 元シート更新されるとき、思わぬ
副作用がある、ということが、お分かりになると思います。
|
|