
EXCEL VBA WEBページを参考にして、あれこれ失敗してはなんとか、色々なコードを書いてきました。そんな学び方なので、基本がきちんとわかっていないようで、いつもすんなりいきません。
さて、教えてください。
EXCEL のファイルが開いたあと、ユーザーフォームを表示して、自動的にエクセルが終了するようなマクロを作りたくて、次のようなコードを書きました。
Private Sub Workbook_Open()
Dim Waittime As Date
Worksheets("sheet1").Select
UserForm1.Show vbModeless
Waittime = Now() + TimeValue("00:0:10")
Application.Wait Waittime
Unload UserForm1
Application.DisplayAlerts = False
Application.Quit
End Sub
しかし、
ワークブックを開きにいくと、エクセルが立ち上がりにいきますが、
ワークシートが開かず、ユーザーフォームだけが表示されてエクセルが終わってしまいます。
本当は、ワークシート上に入力してある色々な内容をまず見せて、
それから最後にユーザーフォームを表示してエクセルを閉じさせたいので、ユーザーフォームが表示されるだけでは困るのです。
どのようにコードを直せば、ワークシートが開かれてシート上の内容が表示され、そのあとユーザーフォームが表示されて、エクセルが終了するようになるでしょうか。
アドバイス、どうか、よろしくお願いいたします。
No.6
- 回答日時:
回答者:Qchan1962
#5です。横から申し訳ありません。
検証せずに回答してしまいましたので検証しました。
結果的には、なされたい事に該当するかは、わかりませんが、報告します。
Target.xlsm UserForm1があるブック
trigger.xlsm ここから開くブック
trigger.xlsm 内のコード
同じ場所に保存されている事を想定
ThisWorkbookモジュール 一番初めに読まれるモジュール
Private Sub Workbook_Open()
Workbooks.Open Filename:=ThisWorkbook.Path & "\Target.xlsm"
End Sub
Target.xlsm 内のコード
同じくThisWorkbookモジュール
Private Sub Workbook_Open()
Dim Waittime As Date
Worksheets("sheet1").Select
UserForm1.Show vbModeless
Waittime = Now() + TimeValue("00:0:05")
Application.Wait Waittime
Unload UserForm1
Application.Quit
End Sub
検証の為Application.DisplayAlerts = Falseは除きました。タイムも短縮
vbModelessは、Waittimeの為、本来の機能をしないと思いますが、そのまま。
UserForm1 内コード 不要かも知れませんが
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
On Error Resume Next
Workbooks("trigger.xlsm").Close
End Sub
仕様に競合するようなら、違う形を、、、取り敢えず、検証の為
検証結果
trigger.xlsmから開くとTarget.xlsmのWorksheets("sheet1")が表示されUserForm1が表示されます。
このタイミングでは、trigger.xlsmは正しく開いていない。アクティブブックが移動したためと推測
Waittime 終了後、Unload UserForm1、 UserForm_QueryCloseが実行され、trigger.xlsmは表示される事なく閉じられました。
Target.xlsm単体で開いた場合、起動画面表示、UserForm1表示され、Waittime 終了後、正常に開くことなく終了(内部的には正常に開いて閉じられています)
単体で開いた場合、trigger.xlsmは、開いていないのでWorkbooks("trigger.xlsm").Closeはエラーになる為、On Error Resume Next 必須
結果、trigger.xlsmブックからでないと開くことが出来なくなります。
第三のブックを開いておいてTarget.xlsmを開いた場合、単独で開いた時と同じ挙動でした。
これは、SDI(シングル ドキュメント インターフェイス)によう為と思われます。(未確認)
(検証 Excel2013)SDIによるものであれば、Excel2010だと結果は違うかもしれません
ご回答ありがとうございます。
内容が、やはり自己流の見よう見まねでコードを書いてきた私には難解です。
レベルが低すぎるようです。
No.5
- 回答日時:
こんばんは、代替え案が示されたようですが、すみません私も
ご質問にある方法では、Excel起動時(ブック起動時ではありません)のインスタンスを読込完了するまでシートは表示されないと思います。
なので、別ブックから操作するようにすれば、可能です。
操作ブックのOpen系イベントに例えば、
Private Sub Workbook_Open()
Workbooks.Open Filename:=ThisWorkbook.Path & "\Target.xlsm"
End Sub
の様に記載して保存します。実際に閲覧シート、フォームのあるブックはこの場合、Target.xlsmです。
操作ブックを起動すると、End Sub まで 実行されExcelインスタンスが完了するので、Workbooks.Open で Target.xlsmは、
シートが表示されてから、ユーザーフォームが表示されるはずです。
すみません。検証しておりませんが、理屈だとそうなるはずと思います。
参考まで
No.4
- 回答日時:
で、出来たっ・・・!!
それぞれに以下のように記述してください
【Sheet1】
Private Sub Worksheet_Activate()
Application.OnTime Now + TimeValue("00:00:1"), "フォーム開く"
End Sub
【thisworkbook】
Private Sub Workbook_Open()
Sheets(2).Activate
Sheets(2).Range("A1").Select
Sheets(1).Activate
Sheets(1).Range("A1").Select
End Sub
【標準モジュール】
Function フォーム開く()
Dim Waittime As Date
UserForm1.Show vbModeless
Waittime = Now() + TimeValue("00:0:10")
Application.Wait Waittime
Unload UserForm1
Application.DisplayAlerts = False
Application.Quit
End Function
No.3
- 回答日時:
VBAProject > Microsoft Excel Object > Sheet1 があると思います。
(thisworkbookと同じ階層)Sheet1内に以下を記述してください。
以下の中で記述した処理は、ユーザーがセルをクリックして選択セルが変わったタイミングで実行されます。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
(この中でフォームを呼ぶ ~ エクセルを閉じる までの処理を記述)
End Sub
ありがとうございます。
おっしゃる通りにしましたら、シートが開き、任意のセルをクリックしたら、望む動きをしました。
最後の関門なのですが、
>ユーザーがセルをクリックして選択セルが変わったタイミングで実行
を、何も操作しなくても実行するようにはできないものでしょうか?
No.2
- 回答日時:
あ~すいません、ちゃんと読んでいませんでした。
貴方と同じ症状ですね。
おそらく、thisworkbook内でフォームを表示されるとうまくいかないような気がします。
やるとしたら、thiswork上でやるのはシート1を表示させるまでして、
Sheet1上で選択セルが変わったタイミングでフォームを表示させるといったかたちでしょうか。
>Sheet1上で選択セルが変わったタイミングでフォームを表示させる
とは、具体的に言うと、どこに、コードを書く形にすればいいのでしょうか?
それこそ、necornda さんの最初におっしゃった
sheet1 にコードを書けばいいのでしょうか?
かつてsheet1 などにコードを書いた経験がないのでわからないのです、、、。
基本は Module に、 そしてほんとにまれに thisworkbook に書いた経験しかありません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで複数のシートに画像...
-
【ExcelVBA】マクロの入ったシ...
-
エクセル、特定のシートにパス...
-
エクセルシートの見出しの文字...
-
ハイパーリンクでジャンプした...
-
エクセルを開くとメニューバー...
-
特定のシートのみ再計算させな...
-
エクセルでブック内の倍率がバ...
-
エクセルのファイルサイズが急...
-
別シートの文字列があったら現...
-
EXCELの「シートの見出し」のフ...
-
Nintendo Switch 2 キャリング...
-
ワークシートそのものの色を変...
-
Excelで条件に一致したものだけ...
-
EXCELで存在しないシート...
-
エクセルVBAでエラー!
-
エクセルの複数シートでのリン...
-
エクセルで誤ってF11キーを押す...
-
DATE関数 4月31日などのあ...
-
エクセルの2つのシートを並び...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
EXCELで複数のシートを一度に「...
-
エクセルでブック内の倍率がバ...
-
ハイパーリンクでジャンプした...
-
特定のシートのみ再計算させな...
-
【ExcelVBA】マクロの入ったシ...
-
エクセルシートの見出しの文字...
-
EXCELの図形(テキストボックス)...
-
エクセルのシー名を二段表示に...
-
エクセルのファイルサイズが急...
-
エクセルで複数のシートに画像...
-
エクセル、特定のシートにパス...
-
エクセルの複数シートでのリン...
-
ワークシートそのものの色を変...
-
Wordで差し込み印刷時に表示す...
-
Accessのテーブルを既存のExcel...
-
エクセルの2つのシートを並び...
-
EXCELで存在しないシート...
-
Nintendo Switch 2 キャリング...
-
エクセルを開くとメニューバー...
-
エクセルで、シートの名前を変...
おすすめ情報
シート1モジュールの
Workbook_SheetActivateイベントプロシジャ
にコードを書いてみました。
今度は、シート1は開きますが、一度他のシートを選択して、もう一度シート1を選択し直さないと、コード内容が実行されません。
最初にシート1が開いたときは、Workbook_SheetActivate の状態ではないということみたいです。
これがあと解決されれば、目的達成ということになりそうです。
どなたか、アドバイスいただけると幸いです。
皆さん、本当に色々と考えてくださって、お付き合いくださりありがとうございました。
Qcahan1962さんのおっしゃる通り、nekorondaさんのアドバイス通りにやってみたところ、望む結果を得ることができました。
#4あたりで、nekorondaさんの内容が難しく思えて、そのあと Worksheet activate?プロシージャに書けば全て解決みたいに安易に考えてしまいそれに飛びつき、色々とアドバイスをいただいてふらふらしているうちに、自分でやっていることが混乱、皆さんのお手を相当煩わす結果となり、反省しております。
何人もの方に、この素人の私が投げかけた、実務上意味のない内容にかかわっていただき、皆さん方全員にお礼を形にしたいのですが、ベストアンサーを無駄にはしたくないので、早期から解決策を教えてくださっていた、nekorondaさんをベストアンサーとさせていただきます。
ところで、更にこの素人の私に、もしよろしかったら、教えていただきたいことがあります。
〇 Sheet1 をActiveにするためには、一旦シート2をActiveにしないとならないのでしょうか?
〇 Worksheet Activate プロシージャから 少し時間をおいて 標準モジュールのプログラムを呼び出すという流れは、シート1が開かないうちにユーザーフォームが表示されて終わってしまうことの防止につながっているような想像をしていますが、そういうことなのでしょうか?
>シート1以外のシートをアクティブ(シート1を非アクティブ)にしてあげる必要があります。
ということは、エクセルが通常開いたときは、最初に開いているシートがアクティブである(がアクティブに変化しないとプロシージャの内容は働かない)ということなのですね、、、。
ということは、シート2を開いた状態で常に閉じるようにすれば、オープン時の命令はシート1をアクティブにする内容だけで足りるということにりますね。
Worksheet_Activate プロシージャ内の 標準モジュールのプログラムを呼び出す内容を、そのままWorksheet_Activate プロシージャ内に書いたのでは、私の考える動きは実現できないのでしょうか?
(やってみますが、)できない場合、その理由を教えていただくと、知りたがり屋の私はとてもありがたいです。
これで最後の質問にします。
本当におつきあいありがとうございました。