質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.58%

エクセルVBAにて、A.xlsxが既に開いている状態でB.xlsmを開こうとした時に、別ウインドウでB.xlsmを開きたい

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 3,480

yuYU_YUyu

score 13

 前提・実現したいこと

エクセルVBAにて、下記を実現したい。
A.xlsxが既に開いている状態で、B.xlsmを開こうとした時に、別ウインドウでB.xlsmを開きたい。

 発生している問題・エラーメッセージ

別ウインドウでB.xlsmを開くことができない。
詳細は下の「試したこと」を参照下さい。
エラーメッセージは無し。

 該当のソースコード

Private Sub Workbook_Open()
    Dim filePath As String
    Dim APP As Object

    filePath = ThisWorkbook.FullName
    ThisWorkbook.Close

    Set APP = CreateObject("Excel.Application")
    APP.Visible = True
    APP.Workbooks.Open filePath
    Set APP = Nothing
End Sub

 試したこと

A.xlsxを開いた状態で、上記コードをThisWorkbookモジュールに記述したB.xlsmを実行すると、
ThisWorkbook.Close
にてファイルが閉じてしまうため、
Set APP = CreateObject("Excel.Application")
を含む以降のコード(実現したいことが記述されたコード)が実行されない。

 補足情報(FW/ツールのバージョンなど)

Windows 10 Home  Build 17134
Microsoft Excel 2010  Ver: 14.0.7212.5000(32bit)
Microsoft Visual Basic for Applications 7.0
Version 1643
VBA: Retail 7.0.1643
Forms3: 14.0.7153.5001

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

質問文に書いてある通りに解釈すると(不足している部分は想像で補って)、

A.xlsxが既に開いている状態で、
ユーザーがB.xlsmを開こうとしたとき、
別ウィンドウ(別インスタンスのExcelアプリケーション)で開く。
A.xlsxが開いていない状態なら、普通に開く。

Excel2013以降なら何もしなくても別ウィンドウで開くのですが、
Excel2010はMDIなので一つのExcelアプリケーションウィンドウ内に
複数のブックウィンドウが開くことになるので、それを強制的に
別ウィンドウで開きたいということでしょうか。

とりあえず下記のコードで上記のことは実現できます。

B.xlsmのThisWorkbookモジュール

Private Sub Workbook_Open()
    Const ABook = "C:\test\A.xlsx"
    Const BBook = "C:\test\B.xlsm"

    'A.xlsxが開いていない場合は何もしない
    If Not IsBookOpened(ABook) Then Exit Sub

    'A.xlsxが既に開いている場合は別インスタンスのExcelでB.xlmsを開く
    Dim APP As Excel.Application
    Set APP = CreateObject("Excel.Application")
    APP.Visible = True
    APP.EnableEvents = False 'これがないと無限ループに陥る
    APP.Workbooks.Open BBook
    APP.EnableEvents = True
    Set APP = Nothing

    'ブックを閉じる
    ThisWorkbook.Close
End Sub

'指定のブックが開いているかチェックする関数
Function IsBookOpened(a_sFilePath) As Boolean
    On Error Resume Next

    '// 保存済みのブックか判定
    Open a_sFilePath For Append As #1
    Close #1

    If Err.Number > 0 Then
        '// 既に開かれている場合
        IsBookOpened = True
    Else
        '// 開かれていない場合
        IsBookOpened = False
    End If
End Function

ThisWorkbook.Closeしてしまうとそれ以降のコードは実行されないので、
最後にThisWorkbook.Closeするようにする。
これだけだと、開いたときに Workbook_Open が実行されるので、
永遠にB.xlsmが開かれ続けることになる(検証実験中にそうなって焦った(;^ω^)。
APP.EnableEvents = FalseWorkbook_Open が発生しないようにする必要あり。

ただし、これだと読み取り専用モードで開きます(しばらくすると解除できますが。)
また、へたすると無限ループに陥るなどの危険性のある方法なのでお勧めしません。

下記に紹介してあるようなユーザー操作で開く方法にするか、

Excelを別ウィンドウで複数同時に操作する(Windows編) (1/2):Tech TIPS - @IT

Excel2013以降にバージョンアップすることを推奨します。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/10 19:18

    説明不足な部分を補って解釈頂き、また丁寧にご回答下さいましてありがとうございました。
    行いたいことが実現できました。

    hatena19 さんがおっしゃるように、
    閉じる前に開くとどうしても 読み取り専用 として開いてしまうため、
    閉じてから開く方法がないものかと考えておりました。
    が、しばらくすると編集可能となる、ということで行いたいことが実現しました。
    上記エクセルの特性を完全に忘れておりました。

    > Excel2013以降なら何もしなくても別ウィンドウで開くのですが
    エクセルのバージョンにより、SDI,MDIの特性があることは承知しておりましたが、
    こちらの環境ではエクセル2010を使用することが義務付けられております。

    また、ご提示頂きましたリンク先の解決策(エクセルを予め別ウインドウで開いて
    そこにドラッグする方法やレジストリを変更する方法)についても、
    承知はしておりましたが、ユーザに強制することができない状況です。

    このような状況下でどうしたものかと考えたのですが、行き詰まってしまい、
    質問させて頂いた次第です。


    この度はどうもありがとうございました。

    キャンセル

0

情報が曖昧です。
A.xlsxとの関連性は?
提示コードが登録されているのはB.xlsm?
ThisWorkbook=B.xlsm?
提示コードは単に自分自身を開きなおしているように思えるがその認識で正しいですか?
質問タイトルの「別ウィンドウで開きたい」という件はどこにかかっているのですか?

ThisWorkbook.Closeにてファイルが閉じてしまうため

原因がわかっているなら閉じなければ?と思いますが…。
ただ前述したように自身を開きなおしているだけのように思えるコードなので、もう少し登場人物を整理していただけるとよりよい回答が得られるかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/10 19:03

    説明が不足しており申し訳ありません。
    hatena19 さんがご理解、ご提示下さった内容が実現したかったことです。

    > A.xlsxとの関連性は?
    何らかのエクセルファイル(.xls, .xlsx, .xlsm, .xlsb,,,)が
    開かれている状態で B.xlsm を開く場合は、
    既に開かれているエクセルファイルのウインドウとは
    別のウインドウ内で B.xlsm を開きたい、
    エクセルファイルが何も開かれていない状態で
    B.xlsm を開く場合は、そのまま普通に開く
    というのが実現したい動作です。

    > 提示コードが登録されているのはB.xlsm?
    A2. おっしゃる通りです。

    > 原因がわかっているなら閉じなければ?と思いますが…。
    B.xlsm を開くと、エクセル2010を使用しているため、
    既存のエクセル(A.xlsx)と同一のウインドウで開かれてしまいます。
    よって、一度閉じて、再度開くときに別ウインドウで開く、
    という回りくどいことをしようとしておりました。


    初めて質問を本サイトでさせて頂いたのですが、
    なかなか説明が上手くできませんでした。

    次回以降、もう少し説明を詳細にしたいと思います。
    ありがとうございました。

    キャンセル

0

A.xlsxではなく、A.xlsmではありませんか?

コードを見ると自分自身を開いて閉じてと意味不明なことをしていますが、質問文通りのことを実現するならこうなりますね。
※A.xlsmとB.xlsmが同じフォルダにあると仮定

Private Sub Workbook_Open()
    Dim filePath As String
    Dim APP As Object

    filePath = ThisWorkbook.Path & "\B.xlsx"

    Set APP = CreateObject("Excel.Application")
    APP.Visible = True
    APP.Workbooks.Open filePath
    Set APP = Nothing

    ThisWorkbook.Close False
End Sub

ただ、Openイベントの中でCloseすると思わぬエラーにつながるので、一旦Open時のイベントが全て処理されてから閉じるように、OnTimeで遅延させたほうが良いかもしれません。

Private Sub Workbook_Open()
略
    Application.OnTime [Now() + "00:00:01"], "ThisClose"
End Sub

Sub ThisClose()
    ThisWorkbook.Close False
End Sub


このような書き方をしてしまうと(マクロのセキュリティ設定が最低の時)A.xlsmが編集出来なくなるのでご注意下さい。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/09 14:58

    質問の意味を正確に捉えていなかったようです。
    私の回答は無視して下さい。

    キャンセル

  • 2018/10/10 19:22

    情報不足な質問に対してご回答下さいましてありがとうございました。
    行いたかったことは、ttyp03 さんと hatena19 さんへの回答に記載をさせて頂きました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • VBAに関する質問
  • エクセルVBAにて、A.xlsxが既に開いている状態でB.xlsmを開こうとした時に、別ウインドウでB.xlsmを開きたい