none
サーバー上の 最初に Application.OnKey が動作するエクセルファイルを開くとエラーになる RRS feed

  • 質問

  • サーバー上に置いたエクセルブックを開くとき、Application.OnKey が最初に動作するよう定義していますが、その個所がエラーになります。


    動作手順
    ・エクセルのブック起動時に、Application.OnKey が動作するように定義した状態でネットワークのサーバー上から直接起動すると[保護ビュー]での動作となります。
    ・このとき[編集を有効にする]ボタンをクリックして編集ができる状態にします。
    ・VBAの実行時エラー1004が表示され、定義したApplication.OnKey の設定ができません。

    ・サーバー上でなく、ローカルにコピーして起動するとApplication.OnKey の設定が有効であり、定義通り動作(下記の設定手順で作成したファイルを開いたとき、[F1]キーを押すとUserForm1が開く)します。

     上記の実行時エラーを回避する方法はありますか。

    設定手順は以下の通りです。
    (1)ユーザーフォームを作成します。
    オブジェクト名  UserForm1

    (2)フォーム上に[閉じる]ボタンを配置し、動作を定義します。
    Private Sub FormClose_Click()
      Unload UserForm1
    End Sub

    (3)シート上にボタンを配置し、マクロを登録します。
    Sub UserForm_Click()
      UserForm1.Show
    End Sub

    (4)ブックを開いたときの動作をThisWorkbookのコードに定義します。
    Private Sub Workbook_Open()
      Application.OnKey "{F1}", "UserForm_Click"
    End Sub


    動作環境
    Windows 10 Pro 20H2
    Excel   Excel for Microsoft 365 MSO(16.0.13628.20128) 32ビット



    2021年2月28日 21:44

回答

  • ちょっと試してみた結果をご報告します。

    セキュリティレベルが最低のままでは、共有サーバーにコピペした本件ファイルを、マクロを無効にして開くことはできませんでした。

    そこで、セキュリティレベルを上から2番目に変更して開いたうえでセキュリティレベルを最低に戻すやり方でやってみましたら、うまくいきました。これで試してみたらよいのではないかと思いますので、以下に手順を記します。

    1.予め別のエクセルファイルを開いて、セキュリティレベルを上から2番目に変更します。このファイルは閉じても良いです。

    2.次に共有サーバーにコピペした本件フィアルを開くと、保護ビューが表示された後でセキュリティの警告が出て止まります。

    3.その段階でセキュリティのレベルを最低に戻します。

    4.次に本件ファイルを上書き保存して、閉じます。(必ずしもVBEを開いてVBAコードを編集する必要はないようです。)

    5.以上で、次に開くときからは保護ビューが表示されなくなり、OmKeyが機能するようになります。

    この手順で共有サーバーに保存するのであれば、最初に示されたhighlnd1150さんの元の簡単なコードのままでも、同様にエラーを出さずに動作させることができました。要するに、最初に開くときに保護ビューが表示されないようにすれば、以後も問題がないわけです。保護ビューが表示されるからエラーが起きるのだから保護ビューが表示されない様にすればよい、と考えれば、解決策は意外と簡単であった感じですね。

    ただし、そのファイルを共有サーバー上でコピペすると、コピペされたファイルを起動すると保護ビューが表示されます。なので、コピペするたびにコピペしたファイルについて上記の1~5の処理をしなければなりません。結構面倒ですね。保護ビューが教示されたときに一旦ブックを閉じるという小生のコードがうまく動けば、こんな面倒な手順をしなくてよいので、よろしいのではないかと思うのですが、highlnd1150さんのネットワーク上では動きませんかねぇ?

    以上、お試しください。

    2021年3月3日 5:57

すべての返信

  • highlnd1150さん、こんにちは。

    小生も同様の現象に困って、Private Sub Workbook_Open() の最初に次の様な数行のコードを入れてエラーで止まるのを回避しています。残念ながら、一旦閉じられたファイルを開き直す必要がありますが、再度開いたときは、大抵、普通に動作します。一応「上記の実行時エラーを回避する方法はありますか。」とのご質問なので、エラーは回避できる、ということで、ご参考までに以下にコードを提示します。どなたか、一旦閉じずに、処理を継続実行できるやり方をご存じの方がいらっしゃったら、小生もそのやり方を知りたいので、是非、そのやり方を教えてください。よろしくお願いします。

    Dim tempObjCount As Integer
      '起動時に保護ビューが表示された場合にワークシートを表示する段階でエラーが生じる事への対処
      tempObjCount = Application.ProtectedViewWindows.Count
      If tempObjCount > 0 Then
        MsgBox "このままでは正常に作動しないので、一旦閉じます。その後で開き直してやり直してください。", _
        ThisWorkbook.Saved = True                '上書き保存しない
        Application.DisplayAlerts = False
        ThisWorkbook.Close
        Application.DisplayAlerts = True
        Exit Sub
      End If





    2021年3月1日 1:11
  • Highlnd1150さん、こんにちは。

    先ほどお示ししたコードをちょっといじって、ブックを閉じずに継続できないか、試してみました。エラーは出ないのですが、保護ビューが出ないので、実際に期待通りに動くのか確信がいまいち持てないところです。そこでちょっと試していただけたらどうかな、と思いますので、次にご提示します。先ほどと同様、Private Sub Workbook_Open()の最初に書き込みます。

    Dim tempObjCount as Integer
    Dim i as integer
    tempObjCount = Application.ProtectedViewWindows.Count
    If tempObjCount > 0 Then
    For i = 1 To tempObjCount
    If Application.ProtectedViewWindows(i).Workbook.Name = ThisWorkbook.Name Then
    Application.ProtectedViewWindows(i).Close
    ThisWorkbook.Activate
    End If
    Next i
    End If
    ※ 最初にご提示したときのコードにタイプミスがありましたので修正しました。「Wiew」→「View」




    2021年3月1日 5:49
  • KokemomoYamamomoさん、回答いただきありがとうございます。

    2案提示いただきましたが、最初の案(A案とします)を試した結果をお伝えします。


    サーバー上に組み込んで試したときの手順を以下に示します。

    (A案)
    (1)試すファイルにご提示いただいたソースを組み込みます。
      Private Sub Workbook_Open()の Application.OnKey の前に記述しました。
    (2)セーブして閉じます。

     保存されたので実行します。
    (3)ブックを開きます。
    (4)保護ビューのメッセージが出ますので[編集を有効]にします。
    (5)MsgBoxのメッセージが表示されますので、[OK]をクリックします。
    (6)ブックが閉じないので、×にて閉じます。

    (7)再度ブックを開きます。以降(3)から(6)の繰り返しになってしまいます。


    (8)(6)のときにブックを閉じないでファイルから選択して起動します。
      このときも、動作としては(4)から(6)と同じ動作になっています。

    以上の試みでは、(5)の後VBAを編集しようとしてもコードを表示してくれないようです。


    このままでは、まだ残念ながらエラーを回避していないようです。
    以上の手順で間違いは無いと思います。


    もう一案(B案とします)の結果は、追って試してみます。

    2021年3月1日 9:23
  • KokemomoYamamomoさん、ご教示ありがとうございます。

    (B案)を試してみます。
    (1)ファイルにご提示いただいたソースを組み込みます。
     (ローカル上のエクセルファイルに組み込みます)
     組み込んだ個所は以下の通りです。

    Private Sub Workbook_Open()
    
        Dim tempObjCount As Integer
        Dim i As Integer
    
        tempObjCount = Application.ProtectedViewWindows.Count
        If tempObjCount > 0 Then
            For i = 1 To tempObjCount
                If Application.ProtectedViewWindows(i).Workbook.Name = ThisWorkbook.Name Then
                    Application.ProtectedViewWindows(i).Close
                    ThisWorkbook.Activate
                End If
            Next i
        End If
    
        Application.OnKey "{F1}", "UserForm_Click"
    
    End Sub

    (2)セーブして閉じます。
     (セーブ後サーバー上にコピーします)

     サーバー上のエクセルブックを実行します。
    (3)ブックを開きます。
    (4)保護ビューのメッセージが出ますので[編集を有効]にします。
    (5)「実行時エラー'-2147417848(80010108) Closeメソッドは失敗しました ProtectedViewWindowオブジェクト」 が表示されますので[終了]を押します。
    (6)(操作を何もしなくても)ブックが終了します。

    (7)再度サーバー上のブックを起動します。
    (8)開いて修復を表示しながら再度ブックを表示し、保護ビューになりますので[編集を有効]にします。
    (9)その後、(5)と同じ表示後、自動で起動します。
    (10)その後、エクセルのファイル選択(ホーム)の画面が起動します。
    (11)サーバー上の同じブックを指定します。
    (12)左ペインに「ドキュメントの回復」の表示し、保護ビューでブックが起動します。
    (13)(5)と同じ実行時エラーが表示されます。

    以降繰り返し((7)以降)になってしまいます。
    VBAの記述内容をきちんと理解していないこともあり、手順が間違っているかもしれません。
    よろしくご教示をお願いします。

    P.S.タイプミスは見つかりませんでした。

    ※お断りなく案に名前を付けてしまいましたが、ご容赦願います。

    2021年3月1日 11:28
  • highlnd1150さん、今晩は。

    お試しいただいた結果をご報告いただき、ありがとうございます。
    小生の職場の共用サーバーのエクセルファイルのマクロで症状が起きているのと、同じかな、と思ったのですが・・・。小生のケースでは、保護ビューを解除して、マクロを有効にして、マクロが実行される当初にエラーが発生するので、保護ビューのウインドウがまだ残っていて悪さをしてしまうのかと考えて、一旦、A案ではThisWorkbookをCloseしたり、B案では保護ビューのウインドウをCloseしてみたらよいのではないかと考えて作ったコードです。一応、Windows10+Excel2019 及びWindows10+Excel 2016で、いずれもエラーは発生しません。そちらはWindows10で同じ(細かいバージョンは違うと思いますが)ですが、Excelが365ですね。そこらへんで動作が異なるのでしょうか。当方にはExcel 365がないので何とも動作確認はできません。

    一応、メッセージが表示されているので、やはりProtectedViewWindowオブジェクトが残っていたわけで、それが確認できたのは良いのですが、「ThisWorkbook.Close」というありきたりのブックを閉じるやり方を掲載するウェブサイトに出ている典型的なコードでエラーが出るというのは、訳が分かりません。

    サーバー上での実行結果はわかりましたが、参考までにローカルで起動した場合にこのコードでエラーが出るかどうか確認していただけるでしょうか。なお、ローカルもExcel365でしょうか?

    それから、「Application.ProtectedVieWindows(i).Close」を「Application.ProtectedVieWindows(i).Workbook.Close」にしてみても駄目でしょうか?当てずっぽうみたいな話でお恥ずかしいですが、ProtextedViewWindows(i)が閉じれないなら、その中のブックを閉じてみたら、ということです。一応、こちらではコードからはエラーは発生しませんでした。

    何ともお役に立てなくて申し訳ないうえに、厚かましいお願いをして、誠に申し訳ありませんが、よろしくお願いします。







    2021年3月1日 11:57
  • その後。B案で「If tempObjCount > 0 then 」の下に「MsgBox ”tempObjCount>0”」を記入して、当初お示しいただいたコードを記入したエクセルブックを職場の共用サーバーに配置して、共用サーバー上から実行してみたのですが、編集制限>マクロ制限>マクロ解除でマクロが起動されるものの、残念ながらこのメッセージが表示されず、要するに問題の数行のコードは実行されることがありませんでした(Windows10+Excel2019)。当然ながら、onkeyはきちんと機能していて、F1を押すとユーザーフォームが表示されました。もう少し、試してみます。

    と言って、以前、トラブったファイルにこの数行のコード(MsgBox織り込み済み)を仕組んで試してみたものの、全くトラブルが再現できず、今までのところ、実行エラーが出るかどうか確認できませんでした。


    2021年3月1日 13:31
  • A案の動作についてのご報告で、ちょっと解せないところがあるので、確認させてください。

    (4)保護ビューのメッセージが出ますので[編集を有効]にします。
    すると、次に(5)MsgBoxのメッセージが表示されますので~ とのことなのですが、その前に、セキュリティの警告が出て、コンテンツの有効化をしてマクロを有効にするステップがあると思うのですが。マクロを有効にしないと、メッセージも表示されるわけがないわけです。少なくともExcel2016やExcel2019では、編集を有効にして、次にマクロを有効にして、という最大2段階の関門があって、それをくぐり抜けるとマクロが起動するという様になっています。Excel365では、編集を有効にするだけでマクロが走るのでしょうか?

    同様に、B案の動作についてのご報告でも、編集を有効にすると、Closeでエラーが発生するとされています。ということは、やはりマクロが実行されていると理解できます。

    以上のA案とB案のご報告が間違いないとすると、Excel365の場合は、編集を有効にすると途端にマクロが走り出す、という理解になりますが、間違いないでしょうか?

    間違いないとすると、Excel2016やExcel2019と明らかにマクロが稼働するまでのステップが異なりますので、いろいろ違いが出てくるのは当然なのかなという気もします。





    2021年3月1日 16:10
  • 以前エラーが出て困ったファイルにB案のコードを書き加えたものを使って、これを共有サーバーに置いて、いろいろ繰り返し開いてみました。1回だけ、「Application.ProtextedViewWindows(i).Close」でエラーが出ました。これを「Application.ProtextedViewWindows(i).Workbook.Close」にしてみましたが、今度は、エラーの箇所が分かりませんでしたが、多分ここしかないと思うのですが、やはりエラーが出ました。合計2回だけ。なかなかエラーを再現できませんでした。

    一方、B案もA案も書いていない同じファイルで試したところ、4~5回、エラーが出ました。これは以前経験したとおりのエラーでした。

    結局B案もA案も書いていないとエラーが発生する頻度が高い、と思われますが、しかし、B案もExcel2016やExcel2019でも駄目という事のようですから、なぜ頻度が低くなるのかはミステリーです。A案は、Excel2016やExcel2019で機能していますので、小生の環境では問題はないと思いますが、問題は、Excel365では「Thisworkbook.Close」が動作しない事ですね。しかし、この1行は、極めてポピュラーなVBAのコードだと思います。これが動作しないわけがないと思うので、動作しないということは、その前のコードでエラーが発生しているのでしょうか。しかしその前のコードも、MsgBoxのコードとの間のコードは、極めてポピュラーなコードですので、ここでエラーが発生しているとすると、それも極めて不思議です。はまってしまいました。

    いずれにしても、B案は撤回せざるを得ません。問題は、Excel365の場合、A案で、どうやったらThisworkbookを閉じることができるのか、です。

    ※【2021/03/02】追記
    推測ですが、どうやら保護ビューが残っている段階では「Thisworkbook」がエラーを起こすではないかと思われます。

    2021年3月1日 17:14
  • ネットをググってみたら、次のURLを見つけました。参考になるかも。

    http://sunlight.cocolog-nifty.com/sunlight/2016/08/excelworkbook_o.html

    どうやら保護ビューが表示される場合は、Workbook_Open()のタイミングではちょっと早すぎるのかもしれませんね。「Workbook_Open()」の代わりに「Workbook_Activate()」を使ってみては?

    一応、提示されたコードをローカルで試してみたら、同じように機能しました。後は、共有サーバーでどうなるかですが。

    いろいろぐちゃぐちゃコードをご提示しましたが、全く的外れな方向へ誘導してしまったかもしれない、と反省しております。例のエラーが出て困っていたファイルも、余計なコードを削って、Workbook_Activaateに変えてみようと思います。勉強になりました。ありがとうございました。

    しかし、、、エクセルファイルをサーバー上に置こうがローカルに置こうが、ローカルのパソコンがファイルを読み込んで、ローカルのパソコンにプログラムを展開して、ローカルのパソコンのCPUが処理を実行してくのだろうと理解しています。なぜ、違いが出るのか、不思議です。

    ※【追記】
    ただ、Workbook_Activate()だと、ワークブックが他のブックの陰に隠れていた場合にシートをクリックして最前面表示にするたびに起動されるので、ちょっとその点がジャマクサイ感じがしますね。
    Worksheet_Open()にこだわるとすれば、A案でエラーが出るのは、ThisWorkbook.Closeのところだとすると、これをやめて(又はそのコードの前に)、しばらく(1秒未満)時間が経つのを待つコードを書いて、保護ビューが消え去るのを待つ方法もあり得るかもしれませんね。保護ビューが消え去ってしまえば、エラーが生じることは無いのではないかと推測するものですから。

    2021年3月1日 17:36
  • KokemomoYamamomoさん、いろいろお示しいただきありがとうございます。

    使える範囲のPCの調査等をしていますが、所用があり、調べたことがすぐにお知らせできません。

    少しお待ちください。

    2021年3月2日 1:53
  • ※【撤回修正】
    Weitで時間稼ぎをしてその間に保護ビューが閉じられるのを待つコードも作ってみたものの、ダメでしたので、撤回しました。それで、最初のA案に戻って、A案をちょっと変えた案です。もともと小生の例の困ったファイルでは、こちらを使っておりました。しかし、冗長だなぁ、ということでA案の様に余計だと思われる行を削って短くしたのですが、A案はエラーが出てダメでしたので、元の冗長なタイプに変えたものを以下に提示します。
    highlnd1150さんと同じくセキュリティレベルを最低にして、セキュリティの警告が出ないようにしましたら、メッセージの「hit」が表示されるようになりました。ただし、こちらの案ではエラーが出ずにブックが閉じられました。
    また、セキュリティレベルを上から2番目に変更してみましたら、セキュリティの警告が出るようになるのですが、hitのメッセージは出ないでOnkeyが機能するようになりました。
    なお、セキュリティの設定は、エクセルのアプリケーション毎の設定の様なので、ファイルごとに設定レベルを変えることはできないみたいですね。
    さて、Excel365ではどんな動作になるでしょうか?  (なお、撤回修正でWeitのコードと説明を全面的に書き直しましたので、下の追記と後先になりました。要するに、保護ビューが読み取り専用で残っていると、画面には2重にワークシートが表示されるのですが、それがWorkbook_Open()が終了するまで続きます。なので、一旦、hitのメッセージが表示されるような状態に陥ると、もうどうしようもない感じで、一旦ブックを閉じるしかない、というところです。)

    Option Explicit
    Private Sub Workbook_Open()
    Dim tempObjCount As Integer
    Dim hitFlag As Integer
      tempObjCount = Application.ProtectedViewWindows.Count
      If tempObjCount > 0 Then
        MsgBox "hit"  '--- これは目印用で本来不要
        hitFlag = 1
      End If
      DoEvents
      If hitFlag = 1 Then
        MsgBox "このブックを閉じます。"
        If Workbooks.Count = 1 Then
          Application.Quit
        End If
        ThisWorkbook.Close
      Else
        Application.OnKey "{F1}", "UserForm_Click"
        MsgBox "Hello!"  '---これはサブプロシージャの終了告知用で本来不要
      End If
    End Sub

    ※【追記】
    なお、highlnd1150さんのA案についての起動時の様子についての先のご報告での「(4)保護ビューのメッセージが出ますので[編集を有効]にします。(5)MsgBoxのメッセージが表示されますので、[OK]をクリックします。」という進行結果に関して、小生のパソコンでは(4)の次にセキュリティの警告が出るので変だなぁ365ならではなのかなぁと思ってご指摘しましたが、365ならではではなくて、highld1150さんのエクセルのマクロのセキュリティの設定が一番緩い設定(すべてのマクロを有効にする)にしているからではないか、と思い至りました。上から2番目の「警告を表示してすべてのマクロを無効にする」にすると、小職のパソコンと同様に、保護ビューの解除(編集を有効にする)の次、メッセージ表示の前にセキュリティの警告が出てマクロの有効化/無効化を選択するステップが表示されると思います。このステップが表示されるとめんどくさい感じもしますが、マイクロソフトさんも「推奨しません」ということですし、本件のエラーに多少影響しているかもしれませんので、余計なお世話かもしれませんが、このステップが表示されるよう、マクロのセキュリティを変更されることをお勧めします。

    2021年3月2日 6:27
  • KokemomoYamamomoさん、いろいろご教示いただきありがとうございます。


    ご質問等について、まとめてお伝えします。

    (1)ローカルで使用しているExcelのバージョンは、「Excel for Microsoft 365 MSO」です。
      サーバーにアクセスできるPCが何台かあります。そのバージョンは以下の表を参照ください。

    (2)いくつかのExcelバージョンの違いと、ローカルまたはサーバーからダウンロードしたときの実行結果は次の通りです。

         ローカルでの実行  サーバー上での実行  VPNサーバー上での実行
    Excel 2010     OK                  NG                      NG

    Excel 2013     OK                  NG                      NG

    Excel 365      OK                  NG                      NG

     ※ いずれも(A案)(B案)(C案)を実行した結果です。
     ※ (C案)は Application.ProtectedVieWindows(i).Close -> Application.ProtectedVieWindows(i).Workbook.Close としています。
     ※ マクロの設定は、ご指摘のとおり「すべてのマクロを有効にする」としています。
       マクロは、多くのブックで使用していますので、操作が煩雑にしないことが望ましいためこのようにしています。
      (セキュリティ上の問題があるかもしれませんが、セキュリティソフトでブロック・検閲を実行する、その他で回避しています)
     ※ 上表のOKは、F1キーの割り当てができています。
     ※ NGは、保護ビューとして立ち上がり、その後に Workbook_Open() が実行されますが、F1キーの割り当てができません。

        手許にExcel 2019 のバージョンは、ありません。


    現時点では次のようになります。
    ・Application.OnKey の動作を決めるのはエクセルが起動した時点での設定あるいはOSの情報による動作であると思います。
      先にお伝えしたように保護ビューが動作した後に Workbook_Open() が動くようです・・・
      また、Application.IsSandboxed を Workbook_Open() に組み込んでみましたが、ブックが [保護されたビュー] ウィンドウで開いてないようで、その後に指定した Application.OnKey でも、F1キーに割り当てができません。

    Private Sub Workbook_Open()
    
        Dim wbk As Workbook
        Set wbk = ThisWorkbook
        
        MsgBox wbk.Application.IsSandboxed
    
        Application.OnKey "{F1}", "UserForm_Click"
    
    End Sub
      考え違いをしていなければ、Workbook_Open() での記述では困難であると考えます。

    ・従って別な方法に変えようと思っています。案としては次のようになるでしょうか。
    【1】信頼できるフォルダーとして指定する。
        グループポリシーにて設定が可能なようです。
    【2】レジストリの値を変更する。
        レジストリはPowerShellにて操作できるのですが、危険も伴います。
        また、以前のバージョンでは、設定値が判明しているようですが、365はどこに設定されているかわかりませんでした。
    【3】その他


    最後にご提示いただいたコードについては、追って試したいと思います。

    2021年3月2日 14:48
  • highlnd1150さん、ご報告有難うございます。
    先ず、セキュリティレベルの設定は変えることを考えていない前提で了解いたしました。
    次に、「wbk.Application.IsSandboxed」はFalseとなるのは確認しました。つまりご指摘の様に「ブックが [保護されたビュー] ウィンドウで開いてない」わけですが、保護されたビューではないマクロが走るウィンドウで開かれています。それは、小生の確認した動作状況からしても、保護ビューが解除されたThisworkbookの裏陰に保護ビューの残滓のブックの2つのブックが併存しているような状況にあり、したがって、wbkの方がFalseでも保護ビュー(の残滓?)が残っていてエラーが生じるのではないかと考えます。したがって、エラーが生じるかどうかの判定には、wbk.Application.IsSandboxedは使えないと思います。

    その後、セキュリティレベルを最低にして共有サーバー上のファイルで試行しましたら、保護ビューが出る状況となり、いろいろ試行錯誤してみて、必ずしも先にお示しした冗長なコードである必要は無いように思われました。また、A案については、あのコードではブックを閉じてもエクセルが残る現象が生じるのは当然なので、その点の手当てが必要であると気がつきました。

    なお、B案に記したような「Close」メソッドは、ProtectedViewWindowにはないことが分かりました。エラーが出て当然です。ということで、保護ビューが表示されたときに、それを一発で回避する方策は、小生には見つけられませんでした。結局A案で、最初の1回目は閉じられてしまうけれども、再度開けばうまく動く、というやり方しかないように思います。

    ただ、そちらの環境で、再度開けばうまく動くのかどうかは、当方では分かりかねるところです。けれど、一応、冗長なものでなくシンプルにしたコードを記しておきます。当方では、共有サーバーに置いて、エラーが出ずに動きます。なお、エラーが出る場合には、on Error ~ で対処するのも方策かとは思います。一応、コードで対応するとすれば、ここまでだろうと思いますので、Highlnd1150さんが記していたような信頼できるフォルダーとして指定する、などの対策がよろしいのかもしれませんね。

    Option Explicit
    Private Sub Workbook_Open()
      If Not Application.ActiveProtectedViewWindow Is Nothing Then
        MsgBox "このままでは正常に作動しないので、一旦閉じます。その後で開き直してください。"
        ThisWorkbook.Saved = True                '上書き保存しない
        If Workbooks.Count = 1 Then
          Application.Quit
        End If
        ThisWorkbook.Close
      Else
        Application.OnKey "{F1}", "UserForm_Click"
      End If
    End Sub

    ※【追記;コードの修正についてのコメント;2021/3/3 13:27】
    上記のMsgBox文の末尾に不要な", _"が付いていたので、削除しました。

    2021年3月2日 15:32
  • > 考え違いをしていなければ、Workbook_Open() での記述では困難であると考えます。


    私の手元には環境がなく再現ができず、また、これまでのやりとりも斜め読みなので的外れかもしれませんが・・・

    Openイベントで動作しないなら、からOnTimeメソッドでプロシージャを呼び出すとか。

    Private Sub Workbook_Open()
        Call Application.OnTime(Now() + TimeSerial(0, 0, 1), ThisWorkbook.CodeName & ".SetOnKey")
    End Sub

    Private Sub SetOnKey()
        Application.OnKey "{F1}", "UserForm_Click"
    End Sub
    2021年3月2日 23:58
  • minmin312さん、ありがとうございます。

    残念ながら、共有サーバーに保存して実行すると、やはりエラーが出ます。(実行時エラー '1004':’OnTime’メソッドは失敗しました:'_Application'オブジェクト)

    OnTimeメソッドでも、Weitと同様、かつ、別関数にして呼び出しても、いずれもWorkbook_Openの範囲内での処理では、画面上では保護ビューの残滓がメインのワークシートの背後にややずれて隠れて表示されて残っており、エラーが出ます。Workbook_Openが一旦終了すると、保護ビューの残滓も消えて無くなるので、別途マクロを走らせればうまく動くわけです。

    なお、ローカル(自分のパソコン)に保存されたファイルであれば、エラーは出ません。

    また、エクセルのセキュリティレベルが上から2番目の、メッセージを表示してすべてのマクロを無効にする、という設定であれば、保護ビューを解除して、次に表示されるセキュリティの警告メッセージの段階で保護ビューが完全に無くなるので、エラーは起きません。それは小生のコードでも同じ。セキュリティレベルを最低にすることにこだわっているので、なかなか難しいわけです。

    2021年3月3日 1:02
  • > いずれもWorkbook_Openの範囲内での処理では、画面上では保護ビューの残滓がメインのワークシートの背後にややずれて隠れて表示されて残っており、エラーが出ます。

    > Workbook_Openが一旦終了すると、保護ビューの残滓も消えて無くなるので、別途マクロを走らせればうまく動くわけです。

    そうなのですね。

    Auto_Open  でも同じ状況ですか?

    2021年3月3日 1:31
  • Auto_Openの次の段階で実行されるAuto_Openが有るのですね。

    ローカルで問題なく動作するのは同じです。

    共有サーバーに置いて起動した場合、Auto_Openの次の段階で実行されるので、空の又は数を100数えるだけのAuto_Openが書かれていてもいなくても、保護ビューの残滓が消えてからAuto_Openが実行されているのが分かります。

    エラーは発生せず、Sheet1が表示されます。ただ、残念ながら、どういう訳か、Auto_Openに書き込んであるOnkeyが機能しておらず、F1キーを押すとHelpが表示されます。

    一旦閉じて、再度開くと、問題なく、Onkeyが機能することが分かります。

    なぜOnkeyが機能しないのでしょう。

    2021年3月3日 2:19
  • いろいろチェックした結果、共有サーバーに置いて実行して、保護ビューが表示された場合、Auto_Openが実行されていない、ということが分かりました。OnKeyが機能しないわけです。2回目以降開いた時は、保護ビューが表示されず、実行されています。

    こんな記事がありました。やはり。
    https://answers.microsoft.com/ja-jp/msoffice/forum/msoffice_excel-mso_other-mso_2010/%E4%BF%9D%E8%AD%B7%E3%81%95%E3%82%8C%E3%81%9F/79ff065c-b58d-4fbd-b21b-67e4bd090a67

    2021年3月3日 2:53
  • highlnd1150さん、こんにちは。

    小生の現段階の結論は、小生が検証することができる環境での話ではありますが、エクセルのセキュリティレベルを最低にし、保護ビューは表示される設定のままである場合、共有サーバー上に置いた本件のエクセルファイルをそのまま共有サーバー上から開く場合、1発目からエラーを生じさせずにOnkeyを機能させる方法はない、ということです。そして、その補完方法としては、このテーマの第13番目の返信に記載したコードであれば、1回目からOnkeyを有効にするのは無理だけれど、2回目以降開くときにはOnkeyを有効にさせることができる、ということです。(あくまでも小生の環境の範囲内の話であり、highlnd1150さんのネットワークのサーバー上からの起動については、別途検証が必要ですね。)

    なお、共有サーバー上に置くに当たっては、メールの添付ファイルにして自分に送って、それを共有サーバー上にコピペすることにより、保護ビューが表示されるようにいたしました。そして、その共有サーバー上のファイルについて、上述の様な結論となりました。

    なお、例えば、メールの添付ファイルのまま起動いたしますと、保護ビューが表示されて、ファイルは閉じられます。もう一度、メールの添付ファイルのまま起動しても、やはり保護ビューが表示されて、ファイルは閉じられます。これは、何度繰り返しても同じで、進展はありません。
    何故かというと、ご承知とは思いますが、添付ファイルのままでファイルを開くときには、パソコンの特別なフォルダに添付ファイルがコピペされて、それが開かれる、という動作が背後で実行されており、毎回、新たにコピペされて開かれる、という具合になっているから、と小生は理解しています。
    もしもhighlnd1150さんの環境で、ネットワークのサーバー上から直接起動するときに、そのような処理が背後で実行されているようであれば、添付ファイルのままで開くのと同じことになります(そんな処理が背後で実行されているとは思えませんが、念のため言及しました)。

    それから、ファイルをネットワーク上のサーバーにコピペして最初に開く際に、マクロを無効にして開いて、ネットワーク上で編集して上書き保存すると、ひょっとすると、次に開くときは、1発目から保護ビューの表示を回避できてOnkeyが正常に機能するるかもしれません。ちょっと試してみます。

    本件については、かなりはまってしまいましたが、小生の当初のコードの問題点も分かり、小生にとっても勉強になりました。ありがとうございました。

    なお、釈迦に説法で余計な話とは存じつつ、恐れながら申し上げると、やはり、セキュリティレベルは上から2番目の通常レベルにして使われた方がよろしいかと存じます。何が起きるか分からない、100%の安全はない、というのがセキュリティの世界だと理解しておりますので、老婆心ながら心配いたす次第です。余計なことを申しました。ご容赦ください。



    2021年3月3日 4:54
  • ちょっと試してみた結果をご報告します。

    セキュリティレベルが最低のままでは、共有サーバーにコピペした本件ファイルを、マクロを無効にして開くことはできませんでした。

    そこで、セキュリティレベルを上から2番目に変更して開いたうえでセキュリティレベルを最低に戻すやり方でやってみましたら、うまくいきました。これで試してみたらよいのではないかと思いますので、以下に手順を記します。

    1.予め別のエクセルファイルを開いて、セキュリティレベルを上から2番目に変更します。このファイルは閉じても良いです。

    2.次に共有サーバーにコピペした本件フィアルを開くと、保護ビューが表示された後でセキュリティの警告が出て止まります。

    3.その段階でセキュリティのレベルを最低に戻します。

    4.次に本件ファイルを上書き保存して、閉じます。(必ずしもVBEを開いてVBAコードを編集する必要はないようです。)

    5.以上で、次に開くときからは保護ビューが表示されなくなり、OmKeyが機能するようになります。

    この手順で共有サーバーに保存するのであれば、最初に示されたhighlnd1150さんの元の簡単なコードのままでも、同様にエラーを出さずに動作させることができました。要するに、最初に開くときに保護ビューが表示されないようにすれば、以後も問題がないわけです。保護ビューが表示されるからエラーが起きるのだから保護ビューが表示されない様にすればよい、と考えれば、解決策は意外と簡単であった感じですね。

    ただし、そのファイルを共有サーバー上でコピペすると、コピペされたファイルを起動すると保護ビューが表示されます。なので、コピペするたびにコピペしたファイルについて上記の1~5の処理をしなければなりません。結構面倒ですね。保護ビューが教示されたときに一旦ブックを閉じるという小生のコードがうまく動けば、こんな面倒な手順をしなくてよいので、よろしいのではないかと思うのですが、highlnd1150さんのネットワーク上では動きませんかねぇ?

    以上、お試しください。

    2021年3月3日 5:57
  • KokemomoYamamomoさん、多くのサジェッションをありがとうございました。
    minmin312さんにもご参加いただきありがとうございました。

    皆様からいただいた内容から、試行したところ問題点は意外とシンプルに解決できそうだと気づきました。
    「こうしたらこうである」と決めつけるステレオタイプであったのではと反省しています。


    (1)マクロのセキュリティですが、4段階あり、マクロを動かすには[すべてのマクロを有効にする]が警告を出さずに実行でき、一番良いと思っていました。

    (2)KokemomoYamamomoさんからの説明で、セキュリティレベルを[警告を表示してすべてのマクロを無効にする]に変更しました。

    (3)その状態で Workbook_Open() に Application.OnKey を記述したブックを実行します。
      すると、[保護ビュー <編集を有効にする>]が表示されますので、有効にします。
      次に[セキュリティの警告 <コンテンツの有効化>]が表示されますので、コンテンツを有効化をクリックします。

    (4)その結果、[F1]キーにフォームを表示する機能を割り当てることができました。

    (5)その後、同じブックを開くとバージョンあるいはブックの保存場所により(?要確認)[保護ビュー][セキュリティの警告]の表示なしで起動することができます。

    (6)サーバー上、あるいはVPNのサーバー上であっても同様に操作することでファンクションキーに機能を割り付けできます。


    ■「マクロのセキュリティ」を変更することで、操作することでブックを起動するときに必要な許可をそのブックに付与したことになったと考えています。

    ■この状態は、≫他のブックを起動したときでも≪ 同じセキュリティレベルを維持するようです(個々のブックの設定で保管されるものと思い込んでいました)。

    ■「マクロのセキュリティ」の[警告を表示してすべてのマクロを無効にする]の設定により、ブックを開いたときに操作のステップが増えますが、そのステップにどんな意味があるかの考えが及びませんでした。


    以上でエラーが表示される事象は、回避することができるようです。


    皆様にはたくさんお付き合いいただき、たいへんありがとうございました。
    2021年3月3日 10:45
  • 問題解決のご返事を頂いた後でこんなことを書くのは全くの蛇足だとは思うのですが、やはり、念のため、注意喚起のために申し上げておくべきかと存じまして、ちょこっと記させて頂きます。

    小生は、本件の試行までは、最低レベルでエクセルブックのマクロを実行したことはありません。必ず、「警告を表示してすべてのマクロを無効にする」レベルで運用しております。それでも、最初のご返事に書きました通り、保護ビューが表示された後に、エラーが生じることが時々生じました。そのために、それの回避策として、一旦、ブックを閉じるという方策を採ることといたしました。

    highlnd1150さんも、当面は問題解決で一段落だと思いますが、小生と同じように、エラーが生じないとも限りません。是非、レ印を付けていただいた返信を含めて上から第14番目の返信に記載したコードを、おまじないだと思って記載しておかれることを強くお勧めいたします。このコードは、小生の環境では、最低セキュリティレベルで共有サーバー上から実行してもエラーは生じませんでした。

    本件は、なかなかはまって大変でしたが、原因をかなり鋭く究明でき(まだもう一つ、という感じもしますが…)、勉強になりました。ありがとうございました。minmin312さんもアドバイスをいただきありがとうございました。

    2021年3月3日 11:40
  • 回答をいただいてから時間が少し過ぎてしまいましたが、次のようにしたいと考えています。

    (1)利用するソフトやコーディングについては、知らなければならないことが多くあり、各人の考えのもとに使用しています。
     今回の件は、当然知っていなけれがならないことであったマクロのセキュリティの設定と、マクロを利用する方法の問題でした。
     したがって、今後マクロのセキュリティは[警告を表示してすべてのマクロを無効にする]にて利用する方向にて考えています。

    (2)一方、エラーを回避するとのコードですが(おまじない・・・とのことですが)、ロジカルに考えて本当に必要になるのなら利用したいと思います。現時点では、必要ありませんし、推奨されても困惑します。
     これは別な問題ですので、ここでは取り上げません。
     別な問題である理由
     ① 保護ビューとセキュリティの警告の設定(ソフト内の処理順序)により、ActiveProtectedViewWindow はいつも同じ値となるため、エクセルを閉じる動作を繰り返すコードとなっています。
     ② あるときは正常で、あるときはエラーになるのなら、知らない事象が存在するのでしょうから別な意味で厳密に対応すべきと考えます。

    いろいろありがとうございました。
    2021年3月5日 5:47
  • ちょっと気になることが記されているので、蛇足の蛇足を記させていただきます。
    ① 保護ビューとセキュリティの警告の設定(ソフト内の処理順序)により、ActiveProtectedViewWindow はいつも同じ値となるため、エクセルを閉じる動作を繰り返すコードとなっています。」と記されていますが、何か誤解があるのではないでしょうか?このコードをお試しになってみての話でしょうか?小生の試行では、「エクセルを閉じる動作を繰り返す」とはなっていません。当初のA案の動作からこのように記されているのであれば、コードが若干変わっておりますので、動作をご確認いただきたいと思います。
    ② あるときは正常で、あるときはエラーになるのなら、知らない事象が存在するのでしょうから別な意味で厳密に対応すべきと考えます。」については、その通りだと思います。ただ、「厳密に対応」とは、どんな対応でしょうか?ある時は正常であるときはエラーとなる直接の原因は、ある時は保護ビューが消えていてある時は保護ビューが残っている、という現象が起きるからです。そして、その現象がなぜ起きるのか、どんな条件が異なっているのか等、その原因を究明することを言っているのでしょうか?しかし、それはかなり難しいのではないかと思いますし、我々にとって必要最低限のことは、保護ビューが残ってしまっているときでもエラーが出ない様にすること、だと思います。ですから、小生は、あのコードを記しておくことをお勧めしました。
    あくまでもお勧めですので、highlnd1150さんが使われなくても、特段、非難したり、正しくないなどと言うつもりはありません。ただ、ご自分がお使いになるVBAコードであればともかく、人様に使ってもらうVBAコードであれば、エラーの発生をできる限り避けるのが、我々プログラム提供者の務めではないかな、と小生は考えているので、強くお勧めした次第です。
    本件に関する試行で、保護ビューが出た場合に、Worksheet_Open()に記したコードでエラーを引き起こすものとエラーを引き起こさないものがあることも知りました。OnKeyは必ずエラーを引き起こすコードですので、VBAのマクロのセキュリティ設定を上から2番目に変更してあっても、小生が経験しているような状況があれば、エラーが生じます。今までのところはエラーが起きていないのですから問題はなかったのですが、これからもエラーが起きないという保証は何もないですよ、ということです。しつこいですが、この点の注意喚起をさせて頂いて、返信を終えます。ありがとうございました。
    2021年3月5日 12:12