プロが教えるわが家の防犯対策術!

エクセルVBAで現在ユーザーが使っているパソコンに個人用マクロブックが存在するかどうかを取得する方法を考えました。

まず、開いているBOOKを総当りして、エクセル2003までなら PERSONAL.XLS、2007からは"PERSONAL.XLSM がひらいているかどうかを調べる方法。

Sub test1()
Dim wb As Workbook
For Each wb In Workbooks
If wb.Name Like "PERSONAL.XLS*" Then
MsgBox "個人用マクロブックがあります。"
Exit Sub
End If
Next
MsgBox "個人用マクロブックはありません。"
End Sub

最初から個人用マクロブックがあるものとして変数に入れ、エラーになったら無いと判断する方法。

Sub test2()
Dim wb As Workbook
Dim v As String
v = IIf(Val(Application.Version) > 11, "PERSONAL.XLSM", "PERSONAL.XLS")
On Error Resume Next
Set wb = Workbooks(v)
On Error GoTo 0
MsgBox "個人用マクロブックが" & IIf(wb Is Nothing, "ありません。", "あります。")
End Sub

でも、自分の端末はまだ2000で、しかも個人用マクロブックがあるので、ちゃんと判定できているのかどうか自信がありません。
これで正しいのでしょうか?
また、test1とtest2ではどちらをつかえばいいのでしょうか?
あるいは、もっと簡単なやりかたはないのでしょうか?

A 回答 (6件)

横からすみません。


6545075 で問題のコードを回答したmerlionXXです。
たしかにemaxemaxさんのご指摘の通り、個人用マクロブックが開いているとわたしのコードでは該当のBOOKは閉じますがエクセル自体は終了しませんね。
(Workbooks.Count が1ではないので当然ですが)

それに対応するコードならすでにemaxemaxさんは解決されているとおもいますが、参考のため二つあげておきます。

1.emaxemaxさんがTest1で判定に使った方法にWendy02さまのアドバイスを入れた方法

Sub TEST01()
  Dim wb As Workbook
  ActiveWorkbook.Save
  For Each wb In Workbooks
   If wb.Name <> ActiveWorkbook.Name And Not StrConv(wb.Name, vbUpperCase) Like "PERSONAL.XLS*" Then
    ActiveWorkbook.Close (False)
    Exit Sub
   End If
  Next wb
  Application.Quit
End Sub

2.keithinさまがアドバイスしたApplication.StartupPath プロパティを利用する方法

Sub TEST02()
  Dim i As Integer
  i = IIf(Dir(Application.StartupPath & "\PERSONAL.XLS*") Like "PERSONAL.XLS*", 2, 1)
  ActiveWorkbook.Save
  If Workbooks.Count = i Then
    Application.Quit
  Else
    ActiveWorkbook.Close (False)
  End If
End Sub

いかがでしょう?
    • good
    • 0
この回答へのお礼

ありがとうございます。
両方とも完璧に動きました。

お礼日時:2011/02/25 16:39

なるほど。

少しご説明不足でしたね。


>PERSONAL.XLSは編集のためロックされています

そのダイアログには,実際には
「読み取り専用」
「通知」
「キャンセル」
の3つの選択肢ボタンが付いています。

「読み取り専用」と「通知」を選んだエクセルでは,PERSONALが開いています。ユーザーがキャンセルを選んだときには,PERSONALは開いていません。
この動作はひとつのエクセルを重ねて起動した場合でも,複数の(異なるバージョンの)エクセルを同時に使っていても同じです。
    • good
    • 0
この回答へのお礼

何度もありがとうございました。

> ユーザーがキャンセルを選んだときには,PERSONALは開いていません。

確認できました。
とても勉強になりました。

お礼日時:2011/02/25 21:23

>どういうケースなのでしょうか?



ANo.2で回答済みですが,一例としては
>たとえば2つ以上のエクセルを同時起動して使っているようなユーザーでは,ひとつのExcelでしかPERSONALは開いていません。

つまり1つのエクセルでPESONALが開いています。別のエクセルではPERSONALは開いていません。


ちなみに
>Thisworkbookが開いているとき,…あるとは思いませんでした。

もしこれが,当該のマクロを「個人用マクロブックに登録して運用する」という運用を前提に置いてのご質問だとすると,「自分がPERSONAL」ですから何を調べるまでもありません。
しかし一応念のため,回答している一連のマクロはPERSONALを含めてどのブックに持たせてあっても正常に動作します。



>たとえば PersonalCheck.xls とかPERSONALDATA.XLSとかが開いてても閉じられてしまいませんか?

そういったブック名を使用している恐れがあるとお考えでしたら,簡単なバリエーションで

…(left(w.name, 9),…) <> "PERSONAL."
でも
…(left(w.name, 12),…) <> "PERSONAL.XLS"
でも構いません。

この回答への補足

> 当該のマクロを「個人用マクロブックに登録して運用する」という運用を前提に置いてのご質問だとすると

いえいえ、あくまで現在開いているActiveなBOOKに書いてあることが前提です。

補足日時:2011/02/25 16:42
    • good
    • 0
この回答へのお礼

ご丁寧にありがとうございます。
なんどもすみません、ふたつのエクセルを同時起動とは、たとえばエクセル2000と2007のダブルブートのようなことでしょうか?
私はエクセル2000しかないのですが、ためしに2000を立ち上げBOOKを開いた状態で、再度エクセルを起動させて見ました。
すると、
「PERSONAL.XLSは編集のためロックされています。」
というメッセージは出ましたがまたエクセルが立ち上がりました。

両方のエクセルで

Sub TEST()
Dim wb As Workbook
For Each wb In Workbooks
MsgBox wb.Name
Next wb
End Sub

を走らせて見たところ、それぞれのエクセルで開いたBOOKの名前しか表示されませんでしたが、PERSONAL.XLSは両方に出てきました。

> そういったブック名を使用している恐れがあるとお考えでしたら,簡単なバリエーションで

あ、そうですね、私は頭が悪いですねえ。

お礼日時:2011/02/25 16:34

なるほど。



まず,
>If Dir(Application.StartupPath & "\PERSONAL.XLS*") Like …

これでバージョンを問わず,とりあえず標準のXLSTARTフォルダに個人用マクロブックがあるか無いかを確認できますね。



で,実際にやりたかったことについていえば
「自分ブック(若しくはActiveworkbook)は絶対に開いている」
「個人用マクロブックは開いているかどうかに関わらず」
「(自分でもPERSONALでもない)第三のブックが開いていたら自分.close,開いていなければQuit」
という事ですから

dim w as workbook
activeworkbook.save
for each w in workbooks
 if w.name <> activeworkbook.name and strconv(left(w.name, 8), vbuppercase) <> "PERSONAL" then
  activeworkbook.close false
  exit sub
 end if
next
application.quit

ぐらいでしょうか。
    • good
    • 0
この回答へのお礼

ありがとうございます。

> 「個人用マクロブックは開いているかどうかに関わらず」

Thisworkbookが開いているとき、個人用マクロブックが開いてないということがあるとは思いませんでした。
どういうケースなのでしょうか?

> strconv(left(w.name, 8), vbuppercase) <> "PERSONAL" 

とすると、たとえば PersonalCheck.xls とかPERSONALDATA.XLSとかが開いてても閉じられてしまいませんか?

お礼日時:2011/02/25 14:05

古いエクセルを使っていたパソコンに2007以降を追加/アップグレードインストールしていた場合など,2007以降でもPERSONAL.XLSが残存しますので,test1の方が安全です。





なお
>現在ユーザーが使っているパソコンに個人用マクロブックが存在するかどうか

どこまでゲンミツに(または何を目的に)そういう事をしたいのかにもよるのでしょうけど,たとえば2つ以上のエクセルを同時起動して使っているようなユーザーでは,ひとつのExcelでしかPERSONALは開いていません。
簡便な方法としてはapplication.startuppath(およびAltStartupPath)に通常はPERSONALはありますので,そちらを念のため調べてみるような手もありです。
またApplication.path内のXLSTART内にある事も可能です。

この回答への補足

> (または何を目的に)そういう事をしたいのかにもよるのでしょうけど

実は、http://okwave.jp/qa/q6545075.html でのベストアンサーで
もし、開いているBOOKが一つだけの場合はBOOKもエクセルも両方とも終了させる。
複数のBOOKがひらいていれば、ボタンを押したBOOKだけを終了させる。(エクセルは終了しない)
のコードが自分では上手くいかなかったのです。
原因は多分個人用マクロブックがあるせいだと気がつき、個人用マクロブックがあってもなくとも大丈夫なコードを考えようと思ったんです。

補足日時:2011/02/24 21:49
    • good
    • 0
この回答へのお礼

Application.StartupPathプロパティですか、初めて知りました。
ありがとうございます。
ということは、

Sub test04()
If Dir(Application.StartupPath & "\PERSONAL.XLS*") Like "PERSONAL.XLS*" Then
MsgBox "個人用マクロブックがあります。"
Else
MsgBox "個人用マクロブックはありません。"
End If
End Sub

でバージョンを問わずOKってことですね?

お礼日時:2011/02/24 21:33

Test1でよいのですが、大文字・小文字は合わせないといけませんね。



Sub test1()
  Dim wb As Workbook
    For Each wb In Workbooks
      '*↓ここ
      If StrConv(wb.Name, vbUpperCase) Like "PERSONAL.XLS*" Then
        MsgBox "個人用マクロブックがあります。"
        Exit Sub
      End If
    Next
  MsgBox "個人用マクロブックはありません。"
End Sub

もっと簡単なやり方?
簡単だと言えるかはわかりません。Perosnal.xls は、必ず、Sheet ひとつがありますから、以下のようにすれば出来ると思います。

Sub Test3()
Dim ret As Variant
 If Val(Application.Version) > 11 Then
  ret = Workbooks("PERSONAL.XLSM").Worksheets(1).Cells(1, 1).Value
 Else
  ret = Workbooks("PERSONAL.XLS").Worksheets(1).Cells(1, 1).Value
 End If
 MsgBox IIf(IsError(ret), "個人用マクロブックはありません。", "個人用マクロブックはあります。")
End Sub
    • good
    • 0
この回答へのお礼

ありがとうございます。
とても勉強になります。

お礼日時:2011/02/24 21:25

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