VBからのACCESSの起動に関して

このQ&Aのポイント
  • VB2008よりACCESSを更新したり、ACCESSのレポートを使用したりするプログラムを作成しています。
  • 複数のACCESSに複数のレポートを作成しているため、複数のプログラムからACCESSを起動させるとエラーが発生します。
  • 1つのACCESSファイルを複数のVBプログラムからアクセスすることはできないのか、または既に開いているか確認して処理をスキップする方法があるのか知りたいです。
回答を見る
  • ベストアンサー

VBからのACCESSの起動に関して

開発環境:Visual Basic 2008/ACCESS 2000 VB2008よりACCESSを更新したり、ACCESSのレポートを使用したりする プログラムを作成しています。 その際に、1つのACCESSに複数のレポートを作成している事から、複数のプログラム からACCESSを起動させようとするとエラーとなってしまいます。 ACCESSをそれぞれ分けてしまえば問題ないですが、、、、 そもそも1つのACCESSファイルを複数からアクセス(複数のVBプログラム)するという事が 不可能なのでしょうか? あるいは、下記の記述にあるように、データベースを開こうとするかエラーである為、 開いているか確認の記述をし、既に開いているようだったら、その処理をとばすような事 をすれば問題ないのでしょうか??? 教えて頂きたいと思います。 よろしくお願いします。 《記述内容》 Dim ac As Object ac = CreateObject("Access.Application") With ac 'アプリケーションを表示する ac.Visible = True 'データベースを開く ac.OpenCurrentDatabase("C:\sample.mdb") '名前を指定してレポートを開く ac.DoCmd.OpenReport("R_一覧表", 2) 'acViewPreview 'レポートの最大化 .DoCmd.Maximize() 'オブジェクトの解放 System.Runtime.InteropServices.Marshal.ReleaseComObject(ac) End With ac = Nothing

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.3

ミューテックスはセマフォやイベントと同じく マルチスレッド/マルチプロセスにおける同期を とるためのオブジェクトです。 ミューテックスはこれを獲得できるスレッドは 唯一つで、あるスレッドがミューテックスを獲得 している間は他のスレッドがこれを獲得することが できません。APIでのサンプルを示します。 '関数の定義 Module Module1   Public Declare Function CreateMutex Lib "kernel32" _     Alias "CreateMutexA" _     (ByVal セキュリティ記述子 As Integer, _      ByVal 初期所有状態 As Integer, _      ByVal 名前 As String) _      As Integer   Public Declare Function WaitForSingleObject Lib "kernel32" _     (ByVal ハンドル As Integer, _      ByVal 待機時間 As Integer) _      As Integer   Public Declare Function CloseHandle Lib "kernel32" _     (ByVal ハンドル As Integer) _      As Integer   Public Declare Function ReleaseMutex Lib "kernel32" _     (ByVal ハンドル As Integer) _      As Integer '使用例 Public Class Form1   Private ミューテックス As Integer = 0   Private 獲得中 As Boolean = False   Private Sub Form1_Load(~     '最初にミューテックスを作っておく     ミューテックス = CreateMutex(0, 0, "hoge")   End Sub   Private Sub Button1_Click(~     If WaitForSingleObject(ミューテックス, 0) = 0 Then       '獲得できた時の処理       獲得中 = True       == 中略 ==       '処理終了後、ミューテックスを解放する       ReleaseMutex(ミューテックス)       獲得中 = False     Else        '獲得できなかった時の処理     End If   End Sub   Private Sub Form1_FormClosed(~     '獲得中なら解放する     If 獲得中 Then       ReleaseMutex(ミューテックス)       獲得中 = False     End If     'ミューテックスを閉じる     CloseHandle(ミューテックス)   End Sub (1)CreateMutex(0, 0, "hoge") ミューテックスを作ります。セキュリティ記述子はこのハンドルを 子プロセスに継承しないのでNULL(=0)を指定します。 初期所有状態は非所有状態にするので、FALSE(=0)を指定します。 ミューテックスの名前は各プロセスで同じものを付けます。 ここではミューテックスを作っただけで獲得はしていません。 (2)WaitForSingleObject(ミューテックス, 0) ミューテックスの獲得を試みます。獲得できるまでの待機時間が0 なので、獲得できない場合は直ぐに制御が戻ります。戻り値は 獲得できれば0、できない時は258が返ります。 因みに待機時間はミリ秒単位で、-1を指定すると獲得できるまで 制御が戻りません。 (3)ReleaseMutex(ミューテックス) 獲得したミューテックスを解放します。 これをやらないでCloseHandleだけするとミューテックスは捕まった ままで、プロセスが終了するまでミューテックスを解放できなくなり ます。 (4)CloseHandle(ミューテックス) 使用済みのミューテックスを閉じます。

asamix_000
質問者

お礼

nda23様、返答が遅くなりまして申し訳ありません。 教えて頂いたミューテックスでなんとか実現する事ができました! ありがとうございました。

その他の回答 (2)

  • MARU4812
  • ベストアンサー率43% (196/452)
回答No.2

> ミューテックスというのはどのような事でしょうか? そんな発言をする人が使うべきではないと思うけど、 API 直じゃなくてクラスになってるからまぁいいか レベルの情報投下。 http://msdn.microsoft.com/ja-jp/library/system.threading.mutex(v=vs.90).aspx API 直で使うなら貴方はプログラムすべきではないです。

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

AccessのVBAはマルチスレッドに対応できないので、 複数のプロセスが同時にVBAを走らせると、障害が 発生します。 資源の競合を避けるには名前付きミューテックスを 用いるのが一般的です。 特定のファイルを排他モードで開くというのもあり ます。いずれも競争に勝った唯一のプロセスだけが 実行権を得ると言う理屈です。

asamix_000
質問者

お礼

nda23様、ご回答ありがとうございます。 やはりACCESSを同時に開くというのは難しいのですね、、、 教えて頂いた名前付きミューテックスというのはどのような事でしょうか? 使用方法等が記載されたHP等ありましたら教えて頂ければと思います。 お願いする事ばかりで申し訳ありませんが、よろしくお願いします。

関連するQ&A

  • ACCESSレポートの起動のさせて方に関して

    VB2008の環境からACCESSのレポートを起動させたいと考えて います。 いろいろ検索しました結果、以下のような記述をしてみましたが、正しく起動 してくれません。。。 どのように記述するのが正しいのでしょうか??? 教えて下さい。 環境 : VB2008/ACCESS2000 《記述内容》 ※ Microsoft Access 9.0 Object Libraryを追加 Dim accApp As Access.Application 'Access の新しいインスタンスを作成 accApp = CreateObject("Access.Application") 'データベースを Access ウィンドウで開く accApp.OpenCurrentDatabase("c:\sample1.mdb") '印刷 accApp.DoCmd.OpenReport("R_sanple") '現在開いているデータベースを閉じる accApp.CloseCurrentDatabase() 'インスタンス破棄 accApp = Nothing

  • VB6からアクセスのレポートをプレビューするには?

    おはようございます。またまた躓いたのでお助け下さい<(_ _)>VB6で、アクセス2000にパーツ名を読み書きしています。アクセスの方でレポートを作ってあるのですが、印刷はいけそうなのですが、これを印刷前にプレビューしたいのですが、 Set accApp = CreateObject("Access.Application") accApp.OpenCurrentDatabase "C:\part-name.mdb" accApp.DoCmd.OpenReport "パーツ情報", acViewNormal 印刷について参考にさせていただいたソースです。DoCmd.OpenReport が印刷ですよね?ここを変更するのでしょうか?よろしくお願いします<(_ _)>

  • VB6.0でパスワードのかかったAccsessを開く

    VB6.0を使って簡単なプログラムを作成しているのですが、 アクセスのレポートをプログラムから使用したいため下の関数を作りました。ところが、今扱いたいDBがパスワードがかかっているため、毎回パスワードを聞かれてしまいます。どうにかパスワードをプログラムから引き渡せないでしょうか? Public Function usrAccessRpt(strRptName As String, intMode As Integer) As Integer On Local Error GoTo usrAccessRpt_Err Dim AccessAp As New Access.Application 'データベースファイルのOPEN AccessAp.OpenCurrentDatabase App.Path & "\db1.mdb", False 'レポート出力 If intMode = acViewNormal Then AccessAp.DoCmd.OpenReport strRptName, acViewNormal AccessAp.CloseCurrentDatabase Else AccessAp.DoCmd.Maximize AccessAp.DoCmd.OpenReport strRptName, acViewPreview AccessAp.Visible = True End If Exit Function usrAccessRpt_Err: usrAccessRpt = 1 End Function

  • VBからACCESSのレポートをプレビューで表示

    お世話になっております。 VBからのMDBの帳票印刷の事で悩んでおります。 データベースとしてMDBを使用しているので、MDBのレポートのプレビュー を表示しようとしました所、下記のコードで実現することができました。 Dim oleAccess As Access.Application Set oleAccess = GetObject(App.Path & "\data.mdb") Call oleAccess.DoCmd.OpenReport(ReportName, acPreview) oleAccess.DoCmd.Maximize oleAccess.Visible = True 開発環境では問題なくプレビューの表示ができたのですが、 このプログラムを、ACCESSの入っていない環境で、ACCESSランタイムをインストール して実行すると、印刷時に「エラー429 ActiveXコンポーネントはオブジェクトを作成 できません」とのエラーが出て、印刷だけができません(その他の動作は正常です)。 エラー内容から、ACCESSオブジェクトの作成に失敗していると思うのですが、 Access.Application型を使わずに、ACCESSのプレビュー・印刷をする方法は無いのでし ょうか?(たとえば、DAO.DataBase型でMDBを開いて印刷する方法など・・・) 以前にも同じような質問をさせて頂いたのですが、私の力不足のため、再度ご質問させて頂きます。 どんな事でもいいので、アドバイスを頂ければ幸いです。 よろしくお願い致します。

  • Access2000のプロセスが残る

    Access2000のプロセスが残る こんにちわ、いつもお世話になってます。 実行環境:WindowsXP Pro、Access2000、アプリ1(VB.NET作成) 開発環境:Windows7、Access2007、VB2008、アプリ1(VB.NET作成) VB.NET作成アプリはSQLサーバに情報を登録し 登録された情報をもとに印刷用テーブルを作成し Accessのマクロを起動させるプログラムです。 AccessはリンクテーブルでSQLサーバと接続され、 印刷用のレポートがあり、マクロはレポートを起動するものです。 プログラムは以下のような記述をしています。 ============================================ Dim oAcs As Access.Application oAcs = New Access.Application oAcs.OpenCurrentDatabase("C:\Print.mdb") oAcs.DoCmd.SetWarnings(False) oAcs.DoCmd.RunCommand(10) ' ウィンドウの最大化 oAcs.DoCmd.OpenForm("印刷") '印刷マクロ起動 oAcs.DoCmd.Maximize() ' 画面の最大化 oAcs.Visible = True AppActivate("Microsoft Access") oAcs.DoCmd.RunCommand(10) ' ウィンドウの最大化 ============================================ レポート表示後の印刷は自動ではないため Accessを起動したら起動しっぱなしになってます。 解放処理をしていないのでプロセスが残るのは既知です。 開発環境にてアプリ1を実行させAccessでレポートを表示させます。 Accessを終了してもプロセスが残りますがアプリ1を終了させると Accessのプロセスは終了します。 実行環境にて上記の同様の動作を行うと アプリ1を終了させてもプロセスが残ってしまう場合があります。 VB.NETで作成された同様のアプリからのAccess起動にも関わらず プロセスが残ってしまうのはAccessのバージョンとかが関係してるんでしょうか? 情報提供をお待ちしてます。

  • VBからACCESSのレポート出力

    すみません。どうしてもわからないので、質問させて頂きます。 VB6.0 + ACCESS2000 で開発をしています。 インターフェイスはVB,DBはACCESSなのですが、帳票の出力も、 ACCESSで行いたいと思っております。 この時、クライアントにACCEESSが入っていない事も想定して、 ACCESSランタイムも用意しました。 デバッグマシン(OFFICEは入っていません)にランタイム(VB,ACCESS)を インストールして、実行ファイルを実行すると、印刷の部分で、「エラー429 Activeコンポーネントはオブジェクトを作成できません」とのエラーが出て、印刷ができません。 印刷以外は問題なく動いています。 開発マシンは、Win2000、デバッグマシンはWinXPで、ACCESSランタイムはOFFICE XP Developerで作成しました。 下記にソースコードも記載させて頂きます。 もちろん、開発ではきちんと動作しています。 Dim oleAccess As Access.Application Set oleAccess = GetObject(App.Path & "\data\data.mdb") Call oleAccess.DoCmd.OpenReport(ReportName, acPreview) oleAccess.DoCmd.Maximize oleAccess.Visible = True 当初は、「oleAccess.OpenCurrentDatabase」でDBを開いていたのですが、 ACCESSランタイム環境では、GetObjectの方が良いということを聞いたので、 上記の様になっています。 エラーが起きている行は、どうやら「GetObject」の行のようです(oleAccess.OpenCurrentDatabaseの場合でもエラー)。 ACCESSランタイムを使う事が初めてなので、手探りでやっているため、 的外れな所もあるかと思います。 何かアドバイスを頂ければ幸いでございます。 よろしくお願い致します。

  • VBでAccessの最適化

    VB6+Access2003でプログラムを作成しています。 Accessの最適化の方法について教えてください。 AccessのオプションにDBを閉じるときに最適化するというのがありますが そちらで最適化されるようにしておくほうがよいののでしょうか? VBで最適化するようにプログラミングしたほうがよいのでしょうか? (プログラム内で何度もAccessをOpen/Closeしています)

  • access2000で作成したVisual Basicがaccess2007で使えないのはなぜ?

    教えてください。 access2000で作成したVisual Basicがaccess2007で使えないのです。 フォームにボタンを設定し、(1)(2)ボタンをクリックすればイベントを行う機能にしました。 (1)検索  DoCmd.OpenReport "レポート名", acViewPreview, "フィールド名" (2)印刷  DoCmd.OpenReport "レポート名", acViewNormal, "フィールド名" もちろんセキュリティオプションでコンテンツを有効にしています。 なぜか、関連付けされていないオブジェクトにフォームが入っています。 2000ではできるのに、なぜか2007ではできません。 どうしてでしょうか。教えていください。

  • VB.NETとACCESSについて

    VB.NETを使ってACCESSデータベースに入っているレポート(印刷プレビュー)を呼び出して印刷したいのですが、どうしたらいいかわかりません。VB.NETでデータベースに接続してSQLのinsert文でデータを追加することはできます。その後、VB.NETでデータベースに入っているものを印刷するにはどうしたらいいのでしょうか?ACCESSでレポートは作ってあります。どなたか教えていただけないでしょうか?

  • Access&VB

    2つほど質問があるのですが、 1.VBからDAOでパスワードがかかっているACCESSに接続する場合に引数はどのように設定したらよいのでしょうか? 2.ACCESSでクエリーを作成し、そのクエリーの結果をエクセルにエクスポートするという処理をやります。 このときクエリーはパラメータを要求します。どこかのタイミングでパラメータをわたせないでしょうか? 具体的にはこんな感じです。 Dim objDb As Object Dim appAccess As Object Set appAccess = CreateObject("Access.Application") appAccess.OpenCurrentDatabase "パス名\Memo.mdb" appAccess.DoCmd.TransferSpreadsheet 1, 8,"クエリー名","パス名.xls", False,"" もしくは、 appAccess.DoCmd.RunMacro "マクロ名" (マクロの中身は「TransferSpreadsheet」) 分りにくい説明ですが、よろしくお願いします。