VBSを実行したときに既にEXCELを開いている場合にはFor Each wb In Workbooksを使ってXLSTARTフォルダにあるファイルのVBAマクロを実行できます。しかし、EXCELを開いていない場合にはCreateObject("Excel.Application")でEXCELを開いてもXLSTARTフォルダにあるファイルそのものが見つかりません。VBSを使わず、プログラムファイルからEXCELを開く場合にはXLSTARTフォルダにあるファイルも問題もなく開きます。どうすればEXCELを開いていない場合でもVBSでEXCELのXLSTARTにあるマクロを実行できるでしょうか?
因みにXLSTARTのフォルダパスは不特定多数の環境(OSはWindows95-XP、EXCELは97-2007の組合せ)で特定されていないものとします。さらにツール、オプションの全般タブの「起動時に全てのファイルを開くフォルダ」にはXLSTARTが指定されているものとします。
No.4ベストアンサー
- 回答日時:
回答3の補足へのアドバイスというか私の勉強です。
あまり試していないのですが下のようなことができることがわかりました。
-----
Set WShell = CreateObject("WScript.Shell")
WShell.Run "C:\Test\Test.xls" 'Excelファイルを開く
WScript.Sleep 3000 '表示されるまで待つように調整
Set objExcel = GetObject("C:\Test\Test.xls")
objExcel.Application.Run "PERSONAL.XLS!CommonMacro1"
-----
お世話様でございます。
お蔭様で、頂いたプログラムについて下記のように一部修正を行い実現できるようになりました。
Set WShell = CreateObject("WScript.Shell")
WShell.Run "Excel.exe """ & "C:\Documents and Settings\ユーザID\デスクトップ\Test.xls" & """", 0 'Excelファイルを開く
WScript.Sleep 3000 '"表示されるまで待つように調整"
Set objExcel = GetObject("C:\Documents and Settings\ユーザID\デスクトップ\Test.xls")
objExcel.Application.Run "PERSONAL.XLS!Macro"
Set objExcel = Nothing
WScript.Sleep 3000についてはスマートに下記でやろうとしましたがだめでした。
With objExcel
While .Busy Or .ReadyState <> 4
Wend
End With
基本的にほゞ目的を達成できたのですが上記についてもう少しアドバイス頂けたらと思います。
No.7
- 回答日時:
回答6の補足へのアドバイスです。
書かれたコードはVBAでは正しいのかもしれませんが、WSH VBScriptの文法とは違いますので動きません。WSHなどで検索して文法を確認して下さい。
詳しくはないのですが、VBAとして見てもこのコードには疑問があります。
まず、Sleepの代わりとして何かのファイルをOpen/Closeするのは、OSのリソースを食いすぎるのでは。
もしやこのコードは別のプログラムのファイル作成か、ファイルの使用の終了を待つためのものでは。そう考えれば少しは理解できる気がします。しかし、そうだとすれば本件の目的には合いません。
また、エラーの際にすぐ次のループに入るのは他のプログラムの実行を妨げるのでは。少し待ってからOSに制御を渡し(VBAでしたらSleepしてDoEventsでしょうか。どちらか一方でもよさそうですが)、やり直すのがよいのでは。
また、一般論としては他のプログラムを永遠に待たないように限度を設けるのがよいのでは。
当初の質問の回答のネタは出尽くしたと思いますので、このQ&Aもそろそろ閉じた方がよろしいでしょう。
ご回答有難うございました。
WSHについてはVBAよりももっと知識が無いものですからお聞きしました。
おっしゃる通りにネタは出尽くしたようですので閉じさせていただきます。
No.6
- 回答日時:
回答5の補足へのアドバイスというか私の勉強です。
ファイル名に空白がある場合、二重引用符で囲む必要がありました。
更に試行して、二例を作りました。ダイアログの方で十分でシステムへの負担が少ないと思いますが、リトライする方も技術的に勉強になりました。まだ何か考え落ちがあるかもしれません。
-----
const ExcelFileName = "C:\test folder\test.xls"
const MB_OKCANCEL=1
const MB_ICONQUESTION=32
const MB_TOPMOST=&H40000
const IDOK=1
Set WShell = CreateObject("WScript.Shell")
WShell.Run("""" & ExcelFileName & """")
if WShell.PopUp("マクロを実行しますか?" & vbLf & vbLf & _
"Excelが開くのを待って応答して下さい。",0,"確認", _
MB_OKCANCEL+MB_ICONQUESTION+MB_TOPMOST)<>IDOK then
WScript.Quit 'ダイアログで時間かせぎした方が実用的かもしれません
end if
Set objExcel = GetObject(ExcelFileName)
WScript.Sleep 1000 '1秒くらいでよさそうです
objExcel.Application.Run "PERSONAL.XLS!CommonMacro1"
-----
const ExcelFileName = "C:\test folder\test.xls"
const WaitMSec = 500 '★待ち時間[msec]。なるべく長くすることをお奨めします
const LoopMax = 20 '★最大ループ回数
const MB_ICONEXCLAMATION=48
const MB_TOPMOST=&H40000
Set WShell = CreateObject("WScript.Shell")
WShell.Run("""" & ExcelFileName & """")
On Error Resume Next
LoopCount = 0
do
LoopCount = LoopCount + 1
WScript.Sleep WaitMSec
Set objExcel = Nothing
'実行中のExcelを探す
Set objExcel = GetObject( ,"Excel.Application")
FullName = objExcel.ActiveWorkBook.FullName
'LoopMax回ループするか目的のファイル名のExcelが開かれて見つかるまで
loop until (LoopCount=>LoopMax) or (FullName=ExcelFileName)
On Error Goto 0
if LoopCount=>LoopMax then
WShell.PopUp "別のExcelファイルが開かれているようです。" & vbLf & vbLf & _
"全て終了させてから再実行して下さい。", _
0,"エラー",MB_ICONEXCLAMATION+MB_TOPMOST
WScript.Quit
end if
WScript.Sleep 1000 '1秒固定で
objExcel.Application.Run "PERSONAL.XLS!CommonMacro1"
WScript.Echo LoopCount
-----
この回答への補足
WScript.Sleep Waitの部分をやめるための工夫です。
VBAで入出力をする場合には下記のようにOpen Path For Randam As #1
が使えるのですが、WSHではエラーになって使えないようです。
Ck = 0
do
Ck = Ck + 1
Err.Clear
On Error Resume Next
Open Path For Randam As #1
Close #1
On Error Goto 0
loop until Err.Number > 0
どのようにすればよいのでしょうか?
No.5
- 回答日時:
回答4のお礼へのアドバイスというか私の勉強です。
試行してみて、だいたい下のコードで私の環境では動くようになりました。ctr, ctr2は動作確認のためのカウンタです。
WindowsXPでは初回のGetObject前に多めに待たないと別のExcelが起動してしまったりします。Vistaでは1msでもOKでした。
GetObject成功後にも待ちが必要なことがあります。objExcel.Application.Readyのコードを入れてはみましたが全く効果が無いようです。ダイアログで時間かせぎした方が実用的かもしれません、というところです。
-----
ExcelFileName = "C:\Test\Test.xls"
Set WShell = CreateObject("WScript.Shell")
WShell.Run(ExcelFileName)
On Error Resume Next
ctr = 0
do
ctr = ctr + 1
WScript.Sleep 500
Err.Clear
Set objExcel = GetObject(ExcelFileName).Application
loop until Err.Number=0
On Error Goto 0
ctr2 = 0
do
ctr2 = ctr2 + 1
WScript.Sleep 500
loop until objExcel.Application.Ready=True 'これの効果は無いようです
if WShell.PopUp("マクロを実行しますか?",0,"確認",1+32)<>1 then
WScript.Quit 'ダイアログで時間かせぎした方が実用的かもしれません
end if
objExcel.Application.Run "PERSONAL.XLS!CommonMacro1"
WScript.Echo ctr & ", " & ctr2
-----
この回答への補足
毎度ご回答戴き有難うございます。
(1) WShell.Run(ExcelFileName)で動くと言うのがよく判りません。
私の使っているPC(WindowsXP、EXCEL2003)では以下にしないと動きません。
WShell.Run "Excel.exe """ & "C:\Documents and Settings\ユーザID\デスクトップ\Test.xls" & """", 0
(2)「ctr & ", " & ctr2」は「1,1」で最初からErr.Number=0、Application.Ready=Trueのようです。
しかし、「使用中のファイル」ダイヤログが表示され、「PERSONALは使用中のためロックされています」「[読み取り専用]で開くか、または読み取り専用で開き、ほかの人がファイルの使用を終了したときに通知を受け取るには[通知]を選択する」が出ます。
この表示をなくすには下記に修正してWaitの値をを3400以上にしないとなくなりません。
WShell.Run "Excel.exe """ & ExcelFileName & """", 0 'Excelファイルを開く
WScript.Sleep Wait
if WShell.PopUp("マクロを実行しますか?",0,"確認",1+32)<>1 then
WScript.Quit 'ダイアログで時間かせぎした方が実用的かもしれません
end if
これは経験値ですが、これを違うプログラムにして自動的に表示されないようにする方法があれば教えてください。
No.3
- 回答日時:
回答2の補足へのアドバイスです。
目的に合うかどうかわかりませんし、普通にExcelを開いたときと動作は異なりますが、AltStartupPath(存在すれば), StartupPath, Path下の順番で、いずれかのPERSONAL.XLSファイルを開くスクリプト例を書いてみました。必要とあらばファイル名が重複しない限りパス内のファイルの全てを検索して開くこともできます。
-----
Set Fs = CreateObject("Scripting.FileSystemObject")
Set objExcel = CreateObject("Excel.Application")
if (objExcel.AltStartupPath<>"") and _
(Fs.FileExists(objExcel.AltStartupPath & "\PERSONAL.XLS")) then
MacroFileName = objExcel.AltStartupPath & "\PERSONAL.XLS"
elseif Fs.FileExists(objExcel.StartupPath & "\PERSONAL.XLS") then
MacroFileName = objExcel.StartupPath & "\PERSONAL.XLS"
elseif Fs.FileExists(objExcel.Path & "\XLSTART\PERSONAL.XLS") then
MacroFileName = objExcel.Path & "\XLSTART\PERSONAL.XLS"
else
WScript.Echo "マクロファイルが見つかりませんでした。終了します。"
objExcel.Quit
WScript.Quit
end if
WScript.Echo "MacroFileName = " & MacroFileName
objExcel.Visible = True
objExcel.Workbooks.Open MacroFileName
objExcel.Workbooks.Open "C:\Test\MacroTest.xls"
objExcel.Application.Run "PERSONAL.XLS!CommonMacro1"
objExcel.Application.Run "BookMacro1"
-----
と書いていて思いついたのですが、QWERIO0918さんのやりたいことが不特定多数の環境でWSHを使って自動実行することであれば、VBSファイルと、必要なマクロが入ったXLSファイルを一緒に配布して使えば確実なのではないでしょうか。
そうすれば各PCのマクロファイルの位置やファイル名、マクロ名の違いを気にせずスクリプトを記述できます。
この回答への補足
回答番号:No.3補足です。
AltStartupPathは「起動時に全てのファイルを開くフォルダ」に入力したパスですので当てに出来ません。
つまり、全ユーザーに共通の起動(XLStart)フォルダ、例えばEXCEL2003であれば「C:\Program Files\Microsoft Office\Office11\XLSTART」はご回答頂いたパスのどこにも出てこない可能性がありますので"マクロファイルが見つかりませんでした。終了します。"となり得ます。
また、「必要なマクロが入ったXLSファイルを一緒に配布して使えば確実なのではないでしょうか。」については、全くその通りなのですがその特定XLSファイルはどうしても分離せざるを得ない状況下におかれています。
LotusNotesの式にはExecuteコマンドというものがあり、特定のエクセルファイルを起動するだけで自動的にXLSTARTにあるファイルも起動します。同じようにCreateObjectを使用しなくても自動的にXLSTARTのファイルも起動されるような別のコマンドというものはないのでしょうか?
No.2
- 回答日時:
回答1の補足へのアドバイスです。
Bookを開いたりBookのマクロを実行したりしているのは私の勉強のためですので無視して下さい。
Excelの何かの情報をWSHから参照できるかどうかはWSHの機能によるのではなく、Excelがそれを公開しているかどうかにかかっています。
「起動時に全てのファイルを開くフォルダ」は、たぶんExcelのApplicationオブジェクトのプロパティにあるだろうと思い、探しましたらありました。AltStartupPathプロパティです。
また、全ユーザーに共通の起動(XLStart)フォルダはPathプロパティの下だと思われます。
下のスクリプトはApplicationオブジェクトのPath関連のプロパティを表示します。
WindowsXP + Excel2002とVista + Excel2007で試しました。
-----
Set objExcel = CreateObject("Excel.Application")
s = "StartupPath = " & objExcel.StartupPath & vbCrLf
s = s & "AltStartupPath = " & objExcel.AltStartupPath & vbCrLf
s = s & "DefaultFilePath = " & objExcel.DefaultFilePath & vbCrLf
s = s & "LibraryPath = " & objExcel.LibraryPath & vbCrLf
s = s & "Path = " & objExcel.Path & vbCrLf
s = s & "UserLibraryPath = " & objExcel.UserLibraryPath
WScript.Echo s
objExcel.Quit
-----
この回答への補足
お世話様です。
返事が遅れて申し訳ありませんでした。
ご回答の内容は頂いたパスのどれかに入るはずということだと思います。
然しながら、私のやりたかったことは不特定多数のユーザーに対してXLSTARTがどこにあっても一度エクセルを開けば、同時にXLSTARTフォルダのファイルも開くだろうからFor Each wb In Workbooksを使ってXLSTARTフォルダのパスも判り、ここにある特定のファイルのVBAマクロを実行できるはずだと考えました。
しかし、以下のサイトで「CreateObject コマンドを使用した場合、Excel でアドイン(XLSTARTフォルダのファイル)が読み込まれない」ことが判りました。
http://support.microsoft.com/kb/213489/ja
回避策も載っていますが、元々パスを指定しないとできない内容なので事実上無理なことでした。
お教え頂いたAltStartupPathについては「起動時に全てのファイルを開くフォルダ」に入力したパスになるので元々入力していない場合には空白になってしまいます。
もっと、低次元の回避策を考える以外になさそうです。
No.1
- 回答日時:
Excelには詳しくないのですが興味があったので試してみました。
参考になりましたら。XLSTARTにあるマクロはPERSONAL.XLSを開けば実行できました。また、XLSTARTのパスはStartupPathプロパティを参照すればよさそうです。
フォルダ、ファイル、マクロをそれなりに作成し、下のOSとExcelの組み合わせで試しました。
Windows98 + Excel2000
WindowsXP + Excel2002
Vista + Excel2007(ただしXLSTARTのファイル名はPERSONAL.XLSBに書替え)
-----
Set objExcel = CreateObject("Excel.Application")
WScript.Echo objExcel.StartupPath
objExcel.Visible = True
objExcel.Workbooks.Open objExcel.StartupPath & "\PERSONAL.XLS"
objExcel.Workbooks.Open "C:\Test\MacroTest.xls"
objExcel.Application.Run "PERSONAL.XLS!CommonMacro1"
objExcel.Application.Run "BookMacro1"
-----
この回答への補足
objExcel.Workbooks.Open "C:\Test\MacroTest.xls"、objExcel.Application.Run "BookMacro1"を何のために追加しているのか良く意味か判りません。
以下で充分だと思います。
Dim objExcel
Set objExcel = CreateObject("Excel.Application")
WScript.Echo objExcel.Application.StartupPath
objExcel.Visible = True
objExcel.Workbooks.Open objExcel.StartupPath & "\PERSONAL.XLS"
objExcel.Application.Run "PERSONAL.XLS!マクロ"
ただ、StartupPathはログインユーザーの起動(XLStart)フォルダですので全ユーザーに共通の起動(XLStart)フォルダを指定していた場合にはファイルが見つからないことになってしまいます。
ツール、オプションの全般タブの「起動時に全てのファイルを開くフォルダ」で指定したパスが取得できるコマンドがWSHにあれば良いのですが?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excel起動時にエラーダイアログが表示される 3 2022/07/28 19:52
- Word(ワード) office 2021へ自分用のクイックアクセスとマクロをコピーしたい 2 2023/03/11 21:15
- Word(ワード) Word 2016のマクロを Word 2021のWordでキー動作させたい 3 2023/04/12 16:14
- Excel(エクセル) マクロの付いたExcelが開けません 3 2023/02/01 10:54
- Visual Basic(VBA) エクセルのマクロについて教えてください。 4 2023/07/03 09:11
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/02/07 09:58
- その他(プログラミング・Web制作) VBSでExcelファイル起動時、重複しても開くのを止めたい 1 2022/10/01 23:20
- Visual Basic(VBA) Excel-VBAでのファイルの開き方 4 2023/02/14 11:01
- XML エクセルのマクロについて教えてください。 3 2023/02/06 09:06
- Visual Basic(VBA) エクセルのマクロについて教えてください。 4 2023/07/04 17:58
このQ&Aを見た人はこんなQ&Aも見ています
-
あなたの「必」の書き順を教えてください
ふだん、どういう書き順で「必」を書いていますか? みなさんの色んな書き順を知りたいです。 画像のA~Eを使って教えてください。
-
ちょっと先の未来クイズ第6問
2025年1月2日と1月3日に行われる、第101回箱根駅伝(東京箱根間往復大学駅伝競走)で、上位3位に入賞するチームはどこでしょう?
-
【お題】逆襲の桃太郎
【大喜利】桃太郎が1回鬼退治に失敗したところから始まる新作昔話「リベンジオブ桃太郎」にはこんなシーンがある
-
【選手権お題その3】この画像で一言【大喜利】
とあるワンシーンを切り取った画像。この画像で一言、お願いします!
-
今から楽しみな予定はありますか?
いよいよ2025年が始まりました。皆さんには、今から楽しみにしている予定はありますか?
-
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
エクセルVBA 個人用マクロブックのSubをcall出来ない
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・【選手権お題その3】この画像で一言【大喜利】
- ・【お題】逆襲の桃太郎
- ・自分独自の健康法はある?
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・ちょっと先の未来クイズ第6問
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Access クエリ実行が急に非常に...
-
OLE又はDDEを使うVISUAL BESIC...
-
実行ファイルと実行モジュール...
-
Visual BASIC か...
-
VBAでEXEファイルを動かす方法...
-
VB6.0で作ったプロジェクトが起...
-
jarの開き方を教えてください。
-
exeファイルを作成できるプログ...
-
VBスクリプトのWshShell.Runに...
-
c言語でファイルのタイムスタン...
-
c/c++ ビルドしたにもかかわら...
-
JAVA .jarファイルに再圧縮する...
-
アイコンにD&Dしたファイル...
-
コマンドプロンプトで外のexeや...
-
VBSでファイル存在の有無チェック
-
WScript.Echo と msgbox
-
以下のように複数のファイルを...
-
JavaScriptでコマンドプ...
-
VC++での外部プログラムの実行
-
コンパイル ./aと./a.out の違い
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Access クエリ実行が急に非常に...
-
OLE又はDDEを使うVISUAL BESIC...
-
JavaScriptでコマンドプ...
-
jarの開き方を教えてください。
-
VC++から引数付きexeファイルの...
-
コマンドプロンプトで外のexeや...
-
パラメータが正しくありません...
-
c/c++ ビルドしたにもかかわら...
-
以下のように複数のファイルを...
-
64bit環境で32bitのodbc参照
-
VBAで他のプログラムが起動して...
-
コンポーネント`MSCOMM32.cox'...
-
JAVA .jarファイルに再圧縮する...
-
VBS形式ファイル:ダブルクリッ...
-
batからexeを起動した際の戻り...
-
batからexeを実行し戻り値を受...
-
VBAでEXEファイルを動かす方法...
-
JARファイルをEclipseを使って...
-
Visual BASIC か...
-
実行ファイルと実行モジュール...
おすすめ情報