発掘する趣旨
この項目は
https://qiita.com/Q11Q/items/df5cb314635fb8d6bf14
で取り上げていたが、長くリンク先が不明だったところであるが、最近になって発見されたものである。
重要な変更 Command.comからcmd.exe
現在(Windows 98 Meの次OS以降)はCommand.comではなくCmd.exe
であるが、ほぼそのまま通じる。
したがって、Access95から移植するときはcommand.com
を cmd.exe
に変える必要がある。
なお、32bitでしか動かない場合は, %WIndir%\SysWOW64\Cmd.exe
となる。またSystem32起動(64bitなら64bit,
32bitなら32bit)の通常のCMDは%COMSPEC%
を使うとよい。また、解説のようなオプションは16bit時代のもので、32ビットになってからはない。レジストリで変えられる指摘があるが、変えないほうが良いであろう。
Access、いやOffice自体はファイルのコピーはMS-DOSを使うことを本当は意図していたのでは?
また、このサンプルは(おそらくはカレントでもなく開いてもいないしリンクもしていない)mdbファイルを別のドライブに複写している。通常だとFilessystemObjectを使うが、よく考えてみるとこれで十分である。ファイルの操作はDOSで行う。これがMicrsoroft Officeの設計思想だったといっていいと思う。これによりソフトウェア(アプリケーション)自体が軽量化される。OSまで一貫して作るMicrosoftならではの発想だろう。Shellの6についての解説もないが、これは6をデフォルトとしているためであると考えられる。これはDOS窓が最小化して起動され、フォーカスされないという意味になる。
引数の送り仮名が引き数
また2003年頃までは引数を引き数と記述していたことも分かった。
Microsoftは末尾のような警告をそういえばいつやめたのだろう
そのほかShell関数の特徴
非同期実行。つまりVBAの処理はShell関数で複写が終わらなくても次の処理に移る
同期する場合はWscript.shellを使用する。(iwshRuntimeLibraryを参照設定)
ただしWscriptshell.Runは返り値がない。
http://blog.s21g.com/articles/1202
Shell関数はExcelでもWordでもある。
なぜかShell関数の解説は複数存在する
Shell 関数 - Access
https://support.microsoft.com/ja-jp/office/shell-%E9%96%A2%E6%95%B0-ff2e4b1b-712d-4e34-aea6-6832eadd3c63
この項目だけ見るとAccess2007以降のように読めてしまうが、実際はAccess95から存在していた。
Docs Office VBA リファレンス 言語リファレンス リファレンス 関数 Shell
ちなみに、この電卓を起動するのは現在は誤り。
Sub RunWin10_64bitCalc()
' For Windows 10 64 bit
Dim Ret
With CreateObject("WScript.Shell")
Ret = Shell(.ExpandEnvironmentStrings("%WINDIR%") & "\SysWoW64\Calc.exe") '"\SysWoW64\Calc.exe"でも可、どちらも同じものが起動する。
End With
End Sub
また名前付き引数なので次の書き方もできる。
Sub RunWin10_64bitCalc2()
Dim Ret
With CreateObject("WScript.Shell")
'Ret = Shell("%WINDIR%" & "\SysWoW64\Calc.exe")
Ret = Shell(Pathname:=.ExpandEnvironmentStrings("%WINDIR%") & "\System32\Calc.exe", windowstyle:=vbNormalNoFocus)
End With
End Sub
なお、環境変数をそのまま用いても展開できないらしい。このため、基本はフルパスだが、このように With CreateObject("WScript.Shell")
を使う。.ExpandEnvironmentStrings
も長いが、`Program FIles'やCommonはスペースが入らない。また、環境変数を使ったあとにスペースが入ってもうまくいくときがある。ただし、Surfaceは環境変数が使えないらしい。欠陥商品なので無視する。使うほうが悪い。
[AC95] Shell関数を用いて DOS のコマンドを実行する方法
サポート期間が終了した「サポート技術情報」資料に関する免責事項
https://web.archive.org/web/20090524051255if_/http://support.microsoft.com/kb/404917/ja
対象製品
この記事は、以前は次の ID で公開されていました: JP404917
目次
- 概要
- 現象
- ■ 解説
- ■ プロシージャの作成
- ■ サンプルプロシージャ
- ■ 注 意
- ■ 解説
概要
Shell 関数を利用して、MS - DOS の DIR、COPY、DEL 等のコマンドを実行する方法を紹介します。現象
Shell 関数は、引き数 commandstring に拡張子が EXE、COM、BAT または PIF の実行形式のファイルを指定しなければなりません。Shell 関数を使用して MS-DOS の コマンドを実行するには、引き数 commandstring に「COMMAND.COM 」を指定します。 COMMAND.COM は、MS-DOS の内部コマンドを実行するためのパラメータを、2 つ持っています。 COMMAND / C : 指定されたコマンドを実行し、アプリケーションに戻ります。
制御がアプリケーションに戻らない場合は COMMAND.COM の実行
ファイルのショートカットメニューよりプロパティを選択し、
[プログラム] タブをポイントします。
[プログラム終了時にウィンドウを閉じる] チェックボックスが
チェックされているか確認して下さい。
COMMAND / K : 指定されたコマンドを実行しますが、アプリケーションには
戻らずに、DOS プロンプトの状態になります。DOS プロンプト
から戻るには、 MS-DOS の EXIT コマンドを実行します。
■ プロシージャの作成
- データベース ウィンドウで [挿入] メニューの [モジュール] をクリックするか、 データベース ウィンドウの<モジュール> タブをクリックし、<新規作成> を クリックします。
- [挿入] メニューの [プロシージャ] をクリックするか、ツールバーの <プロシージャ挿入>ボタンをクリックします。
- [新規プロシージャ] ダイアログ ボックスで [種類] で "Function プロシー ジャ"を選択します。[スコープ] で "Public プロシージャ" を選択しま す。[名前] でプロシージャ名 (ShellDOS_Exit) を入力します。
- 以下のサンプルプロシージャを入力します。
戻しています。以下の例では、C ドライブにある DB1.MDB ファイルを、D ドライブ の DB2.MDB ファイルにコピーします。
Function ShellDOS_Exit() As Integer
'For Microsoft Access 95 And Later
' 原文は行ラベル Function,EndFunctionは半角2つ分スペース有り
On Error GoTo ShellDOS_Exit_Err
Dim MyCommand As String
Dim TaskId As Long
'コマンドを MyCommand 引き数に格納します。
MyCommand = "COMMAND.COM /C COPY C:\DB1.MDB D:\DB2.MDB" ' Windows 95 - Windows 98 MEまで
MyCommand = "Cmd.exe /C Dir C:\ | Clip" ' この行は原文にない。起動させるとCのルートをイミディエイトウィンドウに表示する
TaskId = Shell(MyCommand, 6) '原文は6とのみあり、注釈はないが、定数vbMinimizedNoFocusのいみ。つまり最小化フォーカスなし
ShellDOS_Exit = True
ShellDOS_Exit_End:
Exit Function 'ここが真のEnd
ShellDOS_Exit_Err:
MsgBox Error$ 'この場合の$はStringを表し、文字列が返る。ただしNullを渡すとエラーになる。つかない場合はVariantになる。現在ではほとんど使われなくなったコード。 https://vbabeginner.net/vba%E9%96%A2%E6%95%B0%E3%81%AE%E3%83%89%E3%83%AB%E3%83%9E%E3%83%BC%E3%82%AF%E3%81%AE%E6%84%8F%E5%91%B3/
ShellDOS_Exit = False
GoTo ShellDOS_Exit_End 'エラーを処理して真のEndに飛ばす。
End Function
MS-DOS レベルで発生するエラー (COPY コマンドの構文が間違っている等) は、Access 95でエラートラップできません。Shell 関数を実行する前に、 MS-DOS のコマンドの構文が正しく記述されているかどうかを確認する必要があります。
この資料は以下の製品について記述したものです。
- Microsoft Access 95 Standard Edition