- 締切済み
エクセルVBAマクロで、一度テキストポックスに入力した値がコピーされて
エクセルVBAマクロで、一度テキストポックスに入力した値がコピーされてしまう VBAマクロ初心者です。 エクセルVBAマクロで、以下の様なプログラムを作成し計算させていますが、 一度入力した値がテキストポックスに残ってしまい、なんとかならないかなと 思っています。 (1)複数シートにそれぞれコマンドボタンを配置し、クリックすると同じユーザー フォームが立ち上がるようになっています。 (2)そのユーザーフォーム内に、テキストボックスが複数あり、それぞれ値を入力 して計算スタートさせると、ワークシートの1行目から数千行目まで計算して 各行に計算結果を表示します。 (計算は、既に各行に入力済みのデータとこのテキストボックスの値を元に算出されます) (3)次に、別のシートでコマンドボタンをクリックし、ユーザーフォームを立ち上げると、 前のシートで入力した値がそのまま各テキストボックスに入ってしまいます。 (これは、必ず起こる訳ではなく、時々起こるのですが、起こる場合は、コマンドボタン をクリックしてからユーザーフォームが立ち上がるまでの時間が若干短い感じがします) ※一度、上記の計算をさせるとテキストボックスの値がそのシートの特定のセルに入り、 次回ユーザーフォームを立ち上げた際に、テキストボックスに入るようになっています。 (Private Sub UserForm Initialize を使っています) パソコンの構造を、私はよく知らないのですが、おそらく、一度テキストボックスに値 を入力して計算させると、どこかのメモリにそれが残っていて、次にユーザーフォーム を立ち上げた際にそれが入ってしまうのかな、と思っています。 (ただし、もし前の値が入ってしまったとしても、一度そのユーザーフォームを消して から、再度立ち上げると、正常な値(そのシートの特定のセルを参照)が必ず入ります) 何か、プログラムにより、このメモリ?を消す?、あるいはうまく解決する方法など 考えられませんでしょうか? もし、詳しい方がおられましたら、御教示いただけませんでしょうか。 よろしくお願いいたします。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- nagare
- ベストアンサー率33% (280/831)
>Unload UserForm1 >を挿入しただけでも効果が見込めるなら、しばらくはこれで >様子を見てみようかと思いますが、どうでしょうか? はい それでいいですよ 初期化には2通りあって、どっちでやるか だけの話です >UserForm_Initializeを入れると、Private Sub UserForm_Initialize()との往復を繰り返してしまう為、無限ループのようになってしまうからではないかと思います。 もしかして UserForm1.Show UserForm1.UserForm_Initialize() Unload UserForm1 ということですか? これなら、完全に違いますよ >(CommandButton1 というのが、ここでは出てこない為) CommandButton1はデフォルトの値(オブジェクト名)なので、変えていたら違う名前になります >(VBAにはloadイベントがない、という意味がよくわからず、これも気になりますが) 今は気にしないでしださい >(又、UserForm_Initialize を UserForm1_Initialize にすると、コンパイルエラー:Sub 又は Function が定義されていません、というエラーが出ます) ★イベント関数名の法則★ オブジェクト名_イベント名() です
- nagare
- ベストアンサー率33% (280/831)
確認しました 1)UserForm1.Show →2)UserForm_Initialize 3)Xボタンクリック 4)Unload UserForm1 →5)UserForm_Initialize ←これは知りませんでした でした。でも、問題はありません。 えっとコントロールの初期化タイミングですが 1)UserForm_Initializeで行う 2)UserForm_Initializeで行わず、 Load UserForm1 初期化 UserForm1.Show とする のどちらかです ソースを全部見ないと原因は分からないですね (変数の初期値も正しいのですよね?) >(直接コマンドボタンをクリックすると、”スタック領域が不足しています”というエラーが出てしまいます) CommandButton1_Clickはどういうコードでしょうか? CommandButton1_Clickで画面を閉じるにはhideしないといけませんけど Private Sub CommandButton1_Click() Me.Hide End Sub ”スタック領域が不足”の原因は、 ・パラメタが多い(再帰処理を行っている場合) ・変数が多い くらいです
補足
ご回答、ありがとうございます。 おそらく、 ”スタック領域が不足しています” の原因は、 UserForm_Initialize を入れると、 Private Sub UserForm_Initialize() との往復を繰り返してしまう為、無限ループのように なってしまうからではないかと思います。 (又、UserForm_Initialize を UserForm1_Initialize にすると、 コンパイルエラー:Sub 又は Function が定義されていません、 というエラーが出ます) >CommandButton1_Clickはどういうコードでしょうか? すいませんが、これは意味がわかりませんでした。 (CommandButton1 というのが、ここでは出てこない為) >ソースを全部見ないと原因は分からないですね これは、システムの一部分になり、全部というのはもっと大きいです。 (ユーザーフォームも10個以上あります) 簡単にいいますと、 標準モジュール>Module1 の中に Sub formshow1() UserForm1.Show Unload UserForm1 End Sub のようなものが、10個以上あり、 フォーム>UserForm1 の中の一部が Private Sub UserForm_Initialize() 以下のプログラムになっており、 ”フォーム”以下にUserFormが10個以上あるといった感じです。 Private Sub UserForm_Initialize() 以下に UserForm_Initialize を入れると、必ず、上記のような無限ループのような状態になる ので、挿入することができません。 Sub formshow1() UserForm1.Show Unload UserForm1 End Sub ↑↑ Unload UserForm1 を挿入しただけでも効果が見込めるなら、しばらくはこれで 様子を見てみようかと思いますが、どうでしょうか? (VBAにはloadイベントがない、という意味がよくわからず、 これも気になりますが)
- nagare
- ベストアンサー率33% (280/831)
変ですね。。。。実際に動きますけど Private Sub CommandButton1_Click() Load UserForm1 With UserForm1 .TextBox1.Value = "a" End With UserForm1.Show Unload UserForm1 End Sub Showを飛ばしてもエラーになりませんでした ●確認 ・UserForm_Initialize() ・UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) に何か処理を書いてますか? ■訂正 VBAにはloadイベントがありませんでした(VBにはあるので勘違い) ですので 1)Load UserForm1 →2)UserForm_Initialize 3)UserForm1.Show の順になります
補足
ご回答、ありがとうございます。 >・UserForm_Initialize() >・UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) >に何か処理を書いてますか? これは、何もありません。 結局、いろいろやってみましたが、 UserForm_Initialize を入れると、何故か、そこから、 Private Sub UserForm_Initialize() のところに戻ってしまい、 F8キーで進めると、この2つを往復してしまいますね。 (直接コマンドボタンをクリックすると、”スタック領域が不足しています” というエラーが出てしまいます) それと、VBAにはloadイベントがないということですが、 そうすると、 Sub formshow1() UserForm1.Show Unload UserForm1 End Sub に変更しても、効果がないということでしょうかね。 (因みにここで、Unload UserForm1 を実行すると、 Private Sub UserForm_Initialize() のところへ 飛んで、ここを再度実行してから、End Sub に 行って終了するようでした)
- nagare
- ベストアンサー率33% (280/831)
>(Unload UserForm1 を挿入してみましたが、これで宜しいのですね?) はい その通りです >ほんの少し時間がかかるようです。 アンロード分ですね >確かめるには、かなり何度もテストしないといけません。 連続操作すれば確認できると思います 記憶なのですが、 Unloadを省略した場合、実際にUnloadされるのはOSの空時間(いつUnloadされるかわからない)となりますので、メモリに残ったままshowすれば表示だけとなります >あと、”Initializeイベントで全コンロールの初期化”というのは、具体的にどのようにすればよろしいでしょうか? 全コンロールに値を設定するということです 例えば、TextBox1.Text = "" 意味がないようでも意味ありです (この例は、Textプロパティが""なら不要ですけど) 補足:Initializeイベントで初期化しない方法 load UserForm1 with UserForm1 .TextBox1.Text = Cells(1, 10) .TextBox2.Text = Cells(1, 11) .TextBox3.Text = Cells(1, 12) .i = Range("ab65536").End(xlUp).Row .TextBox4.Text = Cells(i, 15) Select Case Cells(1, 20) Case 0 .OptionButton1.Value = True Case 1 .OptionButton2.Value = True End Select End With UserForm1.Show Unload UserForm1
補足
ご回答、ありがとうございます。 教えていただいた通り、 プログラムの最初に load UserForm1 with UserForm1 最後に End With UserForm1.Show Unload UserForm1 を付けてみたのですが、実行すると ×でユーザーフォームを閉じれなくなってしまい、 結局、Windowsタスクマネージャを出し、タスクの終了で終了しました。 それで、 UserForm1.Show を削除してみると、 実行時エラー91 オブジェクト変数またはWithブロック変数が設定されていません。 とエラーメッセージが出ました。 UserForm1.Show を実行すると、ユーザーフォームが表示されますが、一度ユーザー フォームが出ると、閉じれなくなってしまうようです。
- nagare
- ベストアンサー率33% (280/831)
そうであれば、showの後にunloadすればいいですよ コマンドボタンのクリックイベントで フォーム.show unload フォーム 尚、Initializeイベントで全コンロールの初期化をすればよりよいです (フォームプロパティで行っている場合は不要ですが)
補足
ご回答、ありがとうございます。 コマンドボタンをクリックすると以下の様な、マクロに行きますが、 Sub formshow1() UserForm1.Show End Sub このように変えてみました。 (Unload UserForm1 を挿入してみましたが、これで宜しいのですね?) ↓↓ Sub formshow1() UserForm1.Show Unload UserForm1 End Sub すると、×でユーザーフォームを閉じる際、 ほんの少し時間がかかるようです。 ただ、もともと滅多に出ない現象の為、効果があったかどうか 確かめるには、かなり何度もテストしないといけません。 あと、”Initializeイベントで全コンロールの初期化”というのは、 具体的にどのようにすればよろしいでしょうか? 因みに、Initializeのところは、だいたい以下の様な感じのプログラムになっています。 (実際のものより、かなり簡素化して書いています) Private Sub UserForm_Initialize() Dim i As Long TextBox1.Text = Cells(1, 10) TextBox2.Text = Cells(1, 11) TextBox3.Text = Cells(1, 12) i = Range("ab65536").End(xlUp).Row TextBox4.Text = Cells(i, 15) Select Case Cells(1, 20) Case 0 OptionButton1.Value = True Case 1 OptionButton2.Value = True End Select End Sub 以上の様な感じですが、具体的にどこをどういじればよいのか 御教示いただけたら幸いでございます。
- nagare
- ベストアンサー率33% (280/831)
ユーザーフォームを閉じる(消している)処理なんですけど、 hideとunloadが混在していませんか? hideプロパティはユーザーフォームを隠すだけなのでshowした場合、入力値などそのまま残っていますし、loadしないので早いです また、Initializeは動きません 対策は、unloadでユーザーフォームを閉じればいいです ユーザーフォームの正しい起動・消滅は下記となります ・load-メモリへのロード(省略可能)->loadメソッド ・show->Initializeloadメソッド ただし、load後でないと動かない また、loadが省略されている場合は、loadも行う ・hide-隠すだけ(省略可能) ・unload-メモリから解放
補足
ご回答、ありがとうございます。 ユーザーフォームを閉じる際、右上の×で閉じておりますので、hideもunloadも使っておりません。 おそらく、それを使う場合は、ユーザーフォーム上にコマンドボタンを配置し、そこをクリックした際、unloadを使ったプログラムに進むようにしておけばよいのかと思いますが、できるだけ×で閉じたいので、その場合はメモリから開封するのは無理ということでしょうか?
お礼
とりあえず、これで様子を見ようと思います。 ありがとうございました。
補足
ご回答、ありがとうございます。 >もしかして >UserForm1.Show >UserForm1.UserForm_Initialize() >Unload UserForm1 >ということですか? いえいえ、Module1 の中は、 Sub formshow1() UserForm1.Show Unload UserForm1 End Sub だけですので、関係ありません。 Private Sub UserForm_Initialize() ~End Sub の間のどこに UserForm_Initialize を入れても、 UserForm_Initialize を実行した途端に Private Sub UserForm_Initialize() に戻ってしまう為、挿入ができないのです。 とりあえず、 Unload UserForm1 の挿入のみで、様子を見てみようと思います。 いろいろと御教示ありがとうございました。