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

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

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

Q&A

解決済

3回答

3817閲覧

accessから別に開いているaccessを閉じたい

zelzel

総合スコア1

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

0グッド

1クリップ

投稿2021/06/28 10:56

編集2021/06/29 04:22

今開いているaccessから他に複数開いているaccessを一度に閉じたいのですが、どのような方法がありますでしょうか?

追記)
メインとなるaccessから他の複数のaccessを開いたり、閉じたりすることとして…
メインのaccessに下記コードを入力してみたところ、特定のaccessを閉じることができました。これを応用して複数指定したら、複数のaccessを閉じるれかも…と思いましたが、その特定のaccessが開いていないときに一度開いて閉じるみたいな動きになるため、現在閉じようとしているaccesが開いているのか判定する必要があるのかもしれません。

private sub コマンド1_Click
Dim ac As Object
Set ac= GetObject("●●●.accdb")
ac.DoCmd.Quit
Set ac = Nothing
End Sub

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2021/06/28 12:25

複数開いているAccessはどのようにして開かれているのですか?手動?プログラムで?
zelzel

2021/06/28 12:43

手動で複数開いてしまった場合に処理を実行するaccess以外の複数access一括終了させたいです。
sazi

2021/06/28 14:40

出来ないとは思いませんが、色々ルールを考えたりしないと駄目ですし、そうなってしまう手順を見直した方が良いのではないかと思います。
zelzel

2021/06/28 15:52 編集

複数のaccessを同時に使用することが多く、メインとなるaccessで他のaccessを開いたり、閉じたりコントロールできないかと思い、今回質問させて頂きました。 ありがとうございました。
sazi

2021/06/28 16:25

単にデータだけならメインのAccessにリンクテーブルしておけば、複数を開く必要はありませんけど、そういう事ではないんですよね?
zelzel

2021/06/28 22:04

そうなんです。データだけではなく、フォームやレポートも使用しています。
sazi

2021/06/29 03:12 編集

無条件に終了させるんなら、バッチでも組んでおけば良いと思いますが、編集中だったら確認メッセージとかいう話になるなら、個別に対応するしかないと思いますけど。
zelzel

2021/06/29 03:52

メインのaccessに下記コードを入力してみたところ、特定のaccessを閉じることができました。これを応用して複数指定したら、複数のaccessを閉じるれかも…と思いましたが、その特定のaccessが開いていないときに一度開いて閉じるみたいな動きになるため、現在閉じようとしているaccesが開いているのか判定する必要があるのかもしれません。 private sub コマンド1_Click Dim ac As Object Set ac= GetObject("●●●.accdb") ac.DoCmd.Quit Set ac = Nothing End Sub
sazi

2021/06/29 03:59

そういう話なら、起動するのをメイン側にしてあげれば(メイン側に起動用のメニューを作成するとか)良いのでは。
sazi

2021/06/29 04:00

なお、ここでのコメントにするより、質問を編集する方が他の回答者の目につきやすくなると思います。
zelzel

2021/06/29 04:19

アドバイスありがとうございます。質問を編集いたします。
guest

回答3

0

ベストアンサー

ネットにあったのをコピペしてみて書いてみました。

VBA

1Option Compare Database 2 3Option Explicit 4 5Private Declare PtrSafe Function EnumWindows Lib "user32.dll" _ 6 (ByVal lpEnumFunc As LongPtr, _ 7 ByVal lParam As LongPtr) As LongPtr 8Private Declare PtrSafe Function GetClassName Lib "user32.dll" _ 9 Alias "GetClassNameA" _ 10 (ByVal hwnd As LongPtr, _ 11 ByVal lpClassName As String, _ 12 ByVal nMaxCount As LongPtr) As LongPtr 13Private Declare PtrSafe Function SendMessage Lib "user32" _ 14 Alias "SendMessageA" _ 15 (ByVal hwnd As LongPtr, ByVal Msg As LongPtr, _ 16 ByVal wParam As LongPtr, lParam As Any) As LongPtr 17 18Private Const WM_CLOSE = &H10 19 20Private mMyhWnd As Long 21 22' コールバック関数 23Public Function EnumWindowsProc(ByVal hwnd As Long, _ 24 ByVal lParam As Long) As Long 25 26 Dim strClassBuff As String * 128 27 Dim strClass As String 28 Dim lngRtnCode As LongPtr 29 30 lngRtnCode = GetClassName(hwnd, strClassBuff, Len(strClassBuff)) 31 strClass = Left(strClassBuff, InStr(strClassBuff, vbNullChar) - 1) 32 If strClass = "OMain" Then 33 If hwnd <> mMyhWnd Then 34 SendMessage hwnd, WM_CLOSE, 0, 0 35 End If 36 End If 37EnumPass: 38 EnumWindowsProc = True 39End Function 40 41 42Sub CloseOtherAccess() 43 mMyhWnd = Application.hWndAccessApp 44 Dim lngRtnCode As LongPtr 45 lngRtnCode = EnumWindows(AddressOf EnumWindowsProc, ByVal 0&) 46End Sub 47

CloseOtherAccessを実行すると、自分以外のAccessにクローズのメッセージを送ります。

これだけじゃ、ダイアログが出て閉じない場合があると思いますが
ただ、それを無理やり閉じるのは、どうかと思います。

という訳で残ってるのがあるかを判定して、それに応じた処理をするのがいいのでしょうか。

ちなみに
一応動作確認はしましたが、LongPtrとLongの扱いの違いが良くわかってないので
その辺りが不適切だと思ってます…

(参考にしたHP)
VBA 【コピペで使える!】別プロセスの特定Excelを一括終了する方法

EnumWindowsを使って別プロセスのExcelを取得してみた

投稿2021/07/02 13:13

編集2021/07/06 01:36
xail2222

総合スコア1508

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

プロセスのKillで良ければ、こちらのソースで可能と思います。
p.s. "MSACCESS"の部分はOSのバージョンで文字列違う可能性あります。
プロセスの強制終了ですので、Closeとは違います。
(環境:Access2007/32bit確認済み)

VBA

1Option Explicit 2' 3Public Declare Function OpenProcess Lib "KERNEL32" ( _ 4 ByVal dwAccess As Long, _ 5 ByVal fInherit As Integer, _ 6 ByVal hObject As Long) As Long 7 8Public Declare Function TerminateProcess Lib "KERNEL32" ( _ 9 ByVal hProcess As Long, _ 10 ByVal uExitCode As Long) As Long 11 12Public Declare Function CloseHandle Lib "KERNEL32" ( _ 13 ByVal hObject As Long) As Long 14 15Public Declare Function GetWindowThreadProcessId Lib "user32.dll" ( _ 16 ByVal hwnd As Long, lpdwProcessId As Long) As Long 17 18Public Const SYNCHRONIZE = 1048576 19Public Const NORMAL_PRIORITY_CLASS = &H20& 20Public Const PROCESS_TERMINATE = &H1 21 22Sub Test_Sample_Miniature() 23 24 Dim objSet As Object 25 Dim obj As Object 26 Dim Locator As Object 27 Dim Server As Object 28 Dim lngProcessID As Long 29 Dim hProcess As Long 30 Dim MyAccessThreadID As Long 31 Dim MyAccessProcID As Long 32 Dim MyAccesshWndID As Long 33 34 'Get MyAccessProcID 35 MyAccesshWndID = Application.hWndAccessApp 36 MyAccessThreadID = GetWindowThreadProcessId(MyAccesshWndID, MyAccessProcID) 37 If MyAccessThreadID = 0 Then 38 MsgBox "Error Get ProcessID hWnd=" & MyAccesshWndID 39 Exit Sub 40 End If 41 42 'Get ALL Access ProccesID 43 Set Locator = CreateObject("WbemScripting.SWbemLocator") 44 Set Server = Locator.ConnectServer 45 Set objSet = Server.ExecQuery("Select * From Win32_Process") 46 47 'Kill Other Access ProccesID 48 For Each obj In objSet 49 If InStr(obj.Name, "MSACCESS") > 0 Then 50 ' 51 lngProcessID = obj.ProcessID 52 If MyAccessProcID <> lngProcessID Then 53 hProcess = OpenProcess(SYNCHRONIZE Or PROCESS_TERMINATE, True, lngProcessID) 54 Call TerminateProcess(hProcess, 0&) 55 Call CloseHandle(hProcess) 56 End If 57 ' 58 End If 59 Next 60 61 'Free Object 62 Set objSet = Nothing 63 Set obj = Nothing 64 Set Server = Nothing 65 Set Locator = Nothing 66End Sub

投稿2021/07/01 04:53

編集2021/07/01 05:27
tosi

総合スコア553

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zelzel

2021/07/01 08:47 編集

ご回答ありがとうございます。64bitではエラーが発生してしまいました。なんとか修正してみます。
tosi

2021/07/05 05:51 編集

強制終了でAccessのゴミファイルが残るので、xail2222様のSendMessageを使った方が良いです。 "Omain"は"OMain"とする必要があるかも知れません。
xail2222

2021/07/06 01:37

"OMain"の方が正しそうですね。修正しました
guest

0

一つの案として
タスク名の一覧から対象ファイルが開いているか確認して、見つかればタスクを終了する。

Private Sub コマンド1_Click()

Dim strTitle
Dim tgFilename As String
'閉じるファイル名
tgFilename = "Database1"
' ウィンドウタイトルから対象ファイルを閉じる。
Call GetProcessNames(tgFilename)

Stop

end sub

'https://www.tetsuyanbo.net/tetsuyanblog/24245 より
Public Function GetProcessNames(tgFilename As String)
' Wordアプリケーションオブジェクトを生成する
Dim objWordProcess As Object
Set objWordProcess = CreateObject("Word.Application")
' タスクリストから表示中のものだけ取得する
Dim objTask As Object
For Each objTask In objWordProcess.Tasks
Do
' 非表示のプロセスはスキップする
If objTask.Visible = False Then
Exit Do
End If
' プロセス名
Debug.Print objTask.Name
If objTask.Name Like "" & tgFilename & "" Then
MsgBox "起動しています。"
'タスクを終了する。
objTask.Close
End If
Loop While False
Next
' オブジェクトを破棄する
Set objWordProcess = Nothing
End Function

投稿2021/06/29 10:54

sinzou

総合スコア392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zelzel

2021/06/30 08:57

遅くなりまして申し訳ございません。ご回答ありがとうございます。1つのaccessに対しては正常に動作いたしました。複数のaccessに対してはどういった記述の追加が必要になりますでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問