重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

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

しかし、
ワークブックを開きにいくと、エクセルが立ち上がりにいきますが、

ワークシートが開かず、ユーザーフォームだけが表示されてエクセルが終わってしまいます。

本当は、ワークシート上に入力してある色々な内容をまず見せて、
それから最後にユーザーフォームを表示してエクセルを閉じさせたいので、ユーザーフォームが表示されるだけでは困るのです。

どのようにコードを直せば、ワークシートが開かれてシート上の内容が表示され、そのあとユーザーフォームが表示されて、エクセルが終了するようになるでしょうか。

アドバイス、どうか、よろしくお願いいたします。

質問者からの補足コメント

  • うーん・・・

    シート1モジュールの
    Workbook_SheetActivateイベントプロシジャ

    にコードを書いてみました。

    今度は、シート1は開きますが、一度他のシートを選択して、もう一度シート1を選択し直さないと、コード内容が実行されません。

    最初にシート1が開いたときは、Workbook_SheetActivate の状態ではないということみたいです。

    これがあと解決されれば、目的達成ということになりそうです。

    どなたか、アドバイスいただけると幸いです。

      補足日時:2020/06/06 21:35
  • うれしい

    皆さん、本当に色々と考えてくださって、お付き合いくださりありがとうございました。
    Qcahan1962さんのおっしゃる通り、nekorondaさんのアドバイス通りにやってみたところ、望む結果を得ることができました。
    #4あたりで、nekorondaさんの内容が難しく思えて、そのあと Worksheet activate?プロシージャに書けば全て解決みたいに安易に考えてしまいそれに飛びつき、色々とアドバイスをいただいてふらふらしているうちに、自分でやっていることが混乱、皆さんのお手を相当煩わす結果となり、反省しております。
    何人もの方に、この素人の私が投げかけた、実務上意味のない内容にかかわっていただき、皆さん方全員にお礼を形にしたいのですが、ベストアンサーを無駄にはしたくないので、早期から解決策を教えてくださっていた、nekorondaさんをベストアンサーとさせていただきます。

      補足日時:2020/06/08 17:12
  • うーん・・・

    ところで、更にこの素人の私に、もしよろしかったら、教えていただきたいことがあります。
    〇 Sheet1 をActiveにするためには、一旦シート2をActiveにしないとならないのでしょうか?
    〇 Worksheet Activate プロシージャから 少し時間をおいて 標準モジュールのプログラムを呼び出すという流れは、シート1が開かないうちにユーザーフォームが表示されて終わってしまうことの防止につながっているような想像をしていますが、そういうことなのでしょうか?

      補足日時:2020/06/08 17:14
  • うれしい

    >シート1以外のシートをアクティブ(シート1を非アクティブ)にしてあげる必要があります。

    ということは、エクセルが通常開いたときは、最初に開いているシートがアクティブである(がアクティブに変化しないとプロシージャの内容は働かない)ということなのですね、、、。
    ということは、シート2を開いた状態で常に閉じるようにすれば、オープン時の命令はシート1をアクティブにする内容だけで足りるということにりますね。

    Worksheet_Activate プロシージャ内の 標準モジュールのプログラムを呼び出す内容を、そのままWorksheet_Activate プロシージャ内に書いたのでは、私の考える動きは実現できないのでしょうか?
    (やってみますが、)できない場合、その理由を教えていただくと、知りたがり屋の私はとてもありがたいです。
    これで最後の質問にします。
    本当におつきあいありがとうございました。

    No.15の回答に寄せられた補足コメントです。 補足日時:2020/06/08 20:40

A 回答 (16件中11~16件)

回答者: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だと結果は違うかもしれません
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

内容が、やはり自己流の見よう見まねでコードを書いてきた私には難解です。

レベルが低すぎるようです。

お礼日時:2020/06/05 22:46

こんばんは、代替え案が示されたようですが、すみません私も


ご質問にある方法では、Excel起動時(ブック起動時ではありません)のインスタンスを読込完了するまでシートは表示されないと思います。
なので、別ブックから操作するようにすれば、可能です。
操作ブックのOpen系イベントに例えば、
Private Sub Workbook_Open()
Workbooks.Open Filename:=ThisWorkbook.Path & "\Target.xlsm"
End Sub
の様に記載して保存します。実際に閲覧シート、フォームのあるブックはこの場合、Target.xlsmです。
操作ブックを起動すると、End Sub まで 実行されExcelインスタンスが完了するので、Workbooks.Open で Target.xlsmは、
シートが表示されてから、ユーザーフォームが表示されるはずです。
すみません。検証しておりませんが、理屈だとそうなるはずと思います。
参考まで
    • good
    • 0

で、出来たっ・・・!!


それぞれに以下のように記述してください

【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
    • good
    • 0

VBAProject > Microsoft Excel Object > Sheet1 があると思います。

(thisworkbookと同じ階層)
Sheet1内に以下を記述してください。
以下の中で記述した処理は、ユーザーがセルをクリックして選択セルが変わったタイミングで実行されます。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
   (この中でフォームを呼ぶ ~ エクセルを閉じる までの処理を記述)
End Sub
    • good
    • 0
この回答へのお礼

ありがとうございます。

おっしゃる通りにしましたら、シートが開き、任意のセルをクリックしたら、望む動きをしました。

最後の関門なのですが、

>ユーザーがセルをクリックして選択セルが変わったタイミングで実行

を、何も操作しなくても実行するようにはできないものでしょうか?

お礼日時:2020/06/04 23:29

あ~すいません、ちゃんと読んでいませんでした。


貴方と同じ症状ですね。

おそらく、thisworkbook内でフォームを表示されるとうまくいかないような気がします。
やるとしたら、thiswork上でやるのはシート1を表示させるまでして、
Sheet1上で選択セルが変わったタイミングでフォームを表示させるといったかたちでしょうか。
    • good
    • 0
この回答へのお礼

>Sheet1上で選択セルが変わったタイミングでフォームを表示させる

とは、具体的に言うと、どこに、コードを書く形にすればいいのでしょうか?

それこそ、necornda さんの最初におっしゃった
sheet1 にコードを書けばいいのでしょうか?

かつてsheet1 などにコードを書いた経験がないのでわからないのです、、、。

基本は Module に、 そしてほんとにまれに thisworkbook に書いた経験しかありません。

お礼日時:2020/06/04 22:59

私の環境ではちゃんと動きますよ。


もしかしてSheet1にVBAを記述していませんか?
ThisWorkbookに記述しないと駄目ですよ。
    • good
    • 0
この回答へのお礼

早速にご回答ありがとうございます。
Sheet1には何も書いていません。

ちゃんと動くというのは、ワークシートがまず開きますか?

だとすると何が問題なのか、いよいよわかりません。

ちなみにEXCEL2010 と古いものを未だに使っています。

お礼日時:2020/06/04 21:45

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

今、見られている記事はコレ!