次の方法で共有

Access2007のVBA言語、リソースメモリの使用量と開放方法について

Anonymous
2010-06-22T04:09:00+00:00

お世話になります。

<質問分類>

Access2007のVBA言語、リソースメモリの使用量と開放方法について

<私のテストで使用しているパソコンです>

OS 名 Microsoft Windows XP Professional

バージョン 5.1.2600 Service Pack 3 ビルド 2600

OS 製造元 Microsoft Corporation

システム名 POWEREDGE600SC

システム製造元 Dell Computer Corporation

システムモデル PowerEdge 600SC

システムの種類 X86-ベース PC

プロセッサ x86 Family 15 Model 2 Stepping 9 GenuineIntel ~2399 Mhz

BIOS バージョン/日付 Dell Computer Corporation A06, 2003/05/19

SMBIOS バージョン 2.3

Windows ディレクトリ C:\WINDOWS

システム ディレクトリ C:\WINDOWS\system32

ブート デバイス \Device\HarddiskVolume1

ロケール 日本

ハードウェア アブストラクション レイヤ バージョン = "5.1.2600.5512 (xpsp.080413-2111)"

ユーザー名 SYSB\FUDANO

タイム ゾーン 東京 (標準時)

合計物理メモリ 2,816.00 MB

利用可能な物理メモリ 1.93 GB

合計仮想メモリ 2.00 GB

利用可能な仮想メモリ 1.96 GB

ページ ファイルの空き容量 5.35 GB

ページ ファイル C:\pagefile.sys

相当古いマシンですが、問題なく正常に動作しております。Access2007は最新でWindows UPdate 済みです。

<概要>

Access2007で、伝票を発行するシステムを作成しました。ボタンを押して、伝票を印刷する。この様な使用方法では全く問題はないのですが、

ボタンを押して、自動で、1000枚程印刷すると、リソースメモリが不足して、Access2007の文字が消える。応答がなくなると言う状態になります。

調査しますと、『DoCmd.OpenReport レポート名, acViewNormal』のVBA命令を実行した後、メモリが開放されない事が判明しました。

<Windowsタスクマネージャでのメモリ使用量の確認結果です>

1)Access2007起動    30,184KB

2)印刷ボタン押下      38,676KB

3)1件目印刷                 40,000KB              

4)10件目印刷               65,000KB

5)50件目印刷             118,600KB

6)100件目印刷           205,794KB

7)200件目印刷           371,372KB

8)300件目印刷           428,508KB

このようにメモリ使用量が増大して、『DoCmd.Close』などで、メモリ開放を試みましたが無駄でした。このメモリを開放するには、Access2007を終了し

再度起動すると、メモリが開放されます。

何か、良い方法はないのでしょうか?

現在、印刷部分を別のプロセスにして、Access2007の起動、印刷、Access2007の終了を繰り返す方法を試験しております。非常に、効率が悪く、印刷用の

子プロセスのAccess2007で、レポート表示中に、システムの終了(右上Xボタン)で抜けられると、Private Sub Report_Unload(Cancel As Integer)の

イベントが発生するタイプのOSとしないOSなどが有り、親のプロセスに終了状態を通知出来ずに、私のプログラムでは、このプロセスが残ているような状態

と間違って判断してしまいます。改良を加え、この方法で、実用に耐えられるか検討しております。

<レポート表示中、右上の×印 システム終了押下時のイベント Report_Unloadイベント>

Windows2003Server  Report_Unloadイベントは発生しない

WindowsXP Professional   Report_Unloadイベントは発生する

<親プロセスから子プロセスを作成しレポートを印刷する方法>

Function MyOpenReport(ByRef strReportName As String, ByVal acFlag As Integer)

    Dim Access As Object

    Dim strPass As String

    Set Access = CreateObject("Access.Application")

    strPass = CurrentProject.path

    Access.OpenCurrentDatabase strPass & "" & "印刷DB01.accdb"

    If (acFlag = 0) Then

        '印刷する

        Access.Visible = False

On Error Resume Next

        Access.DoCmd.OpenReport strReportName, acFlag

        Access.CloseCurrentDatabase

        Access.Quit

        Err.Clear  'エラークリア

        'MSACCESS.EXEの消滅待ち処理

        DoEvents

        DoEvents

        DoEvents

        DoEvents

    Else

        'プレビュー印刷する

        Access.Visible = True

        Access.DoCmd.OpenReport strReportName, acFlag

        'MSACCESS.EXEの消滅待ち処理(レポートの終了×ボタン押下待ち)

On Error GoTo exitLoop

        While Access.Visible = True

            DoEvents

        Wend

exitLoop:

        Err.Clear  'エラークリア

        DoEvents

        DoEvents

        DoEvents

        DoEvents

    End If

End Function

現在は、親プロセスの『XXXX伝票印刷.accdb』より、印刷ボタンを押下し、イベントプロシージャの中から、

        If Me.印刷チェック.Value = True Then

                    'レポート表示を実行する

                    MyOpenReport レポート名, acViewPreview

                Else

                    'レポート印刷する

                    MyOpenReport レポート名, acViewNormal

                End If

と呼び出して使用しております。 使用する準備としては、子プロセス側の『印刷DB01.accdb』では、親プロセスのデータテーブルへ印刷で必要なテーブル

をリンクさせてあります。親プロセスにあったレポートは、子プロセスに移動してあります。

<Windowsタスクマネージャ メモリ使用量>

  1. Access2007起動直後   31,968KB
  2. 印刷ボタン押下       35,668KB

3) 010件印刷                 37,164KB

  1. 050件印刷                 37,676KB
  2. 135件印刷                 39,228KB
  3. 200件印刷         40,068KB

7) 300件印刷         41,524KB

メモリ効率は改善されるのですが、問題点として、先に書きました。親プロセスで、子プロセスの生成と消滅の管理くいちがいが出た場合の対応が

VBAだけで正確に処理することが課題となってます。(環境設定に左右されたくないのでVBAにこだわっております)

親プロセスと連携するように、データテーブルで「印刷使用中」、「印刷空き」などと持たせておりますが、子プロセスで、右上のX印、システム終了で抜け

られた場合が、VBAでは何もできない場合もあり、困りものです。

従って、もっと、単純で効率の良い方法を模索しているというしだいです。よろしくご教授お願い致します。

開発者テクノロジ | Visual Basic for Applications

ロックされた質問。 この質問は、Microsoft サポート コミュニティから移行されました。 役に立つかどうかに投票することはできますが、コメントの追加、質問への返信やフォローはできません。

0 件のコメント コメントはありません

質問作成者が受け入れた回答

Anonymous
2010-06-30T04:10:19+00:00

FUDAI さん、こんにちは。

MSDNでご購入されているとは知らず、通常の製品サポートをご案内してしまいました。

ごめんなさい。。。

会社で購入されているMSDNであれば、専用のサポートがあるようです。

MSDN Subscription

http://msdn.microsoft.com/ja-jp/subscriptions/dd179313.aspx

社内で契約内容を確認され、サポート契約があるようでしたら、そちらをお使いいただいたほうが良いかもしれませんね。

お手数かと思いますが、よろしくお願いします。


田中 美紀– Microsoft Support

この回答は役に立ちましたか?

0 件のコメント コメントはありません

4 件の追加の回答

並べ替え方法: 最も役に立つ
  1. Anonymous
    2010-06-30T03:28:54+00:00

    田中さん、こんにちは。

    ご回答ありがとうございます。最初、私も、マイクロソフト サポートラインにお伺いしましたがMSDNのIDでは、VBAは有料との事で、Accessのパッケージより高い

    かもしれない料金を私は支払いますと答えやっと技術部に電話をつないで頂き、要件を述べると、『今は混んでいるので1時間後にしてください』と言われ再度

    指定された時刻に電話します、とまた、「VBAは有料です料金を頂きます」らしき事とを言われ、何度同じ説明をさせるのかなぁと、私もへそを曲げ、「Access側に問題が

    ある場合は無料でしょう?」と一言いい「ますと、ご担当者もカチン思ったのか『コミユニティが有りますのでそちらにどうぞ』とのご回答で全く話が進みませんでした。

    もしかしたら、開発元のマイクロソフト社の英語バージョンのAccess2007では、問題は無いのかも知れません。日本語バージョンのAccess2007だけでは、ユーザーの

    声が小さいのかもしれませんね。

    私が直接Access2007を購入している分けではないので、困ったものです。「プログラムの作り方が悪いでしょ?」とお客様と、関係者一同に言われるだけで立場がないですね。

    Access2007を親プロセスと子プロセスに分離する方法で何とか切り抜けて、現在は、一安心です。そんなわけで、Access2007の調子が良くないと言えば惨めになるだけの私のようなAccess初心者プログラマーさんを応援したいと思い書きました。

    この回答は役に立ちましたか?

    0 件のコメント コメントはありません
  2. Anonymous
    2010-06-29T04:50:07+00:00

    FUDA1 さん、こんにちは。

    現象の再現するサンプルコードを記載いただきありがとうございました。

    ですが、こちらでも 「DoCmd.OpenReport レポート名, acViewNormal」のVBA命令の実行後にメモリを開放する方法について

    情報をお探ししてみましたが、有効な情報は見つかりませんでした。お役にたてずごめんなさい。

    ただ、こういった問題についての解決は、コミュニティサイトでは難しいかもしれませんね。

    製品サポートのご利用をご検討いただければと思います。

    マイクロソフト サポートオンライン

    http://support.microsoft.com/select/default.aspx?target=assistance


    田中 美紀– Microsoft Support

    この回答は役に立ちましたか?

    0 件のコメント コメントはありません
  3. Anonymous
    2010-06-23T04:26:59+00:00

    黒田さん、こんにちは。

    お世話になります。

    最も単純なDoCmd.OpenReportのメモリが開放されない現象が再現するサンプルコードを作成して見ました。

    Access2007を起動しまして、testdb.accdbを作成し、テーブル1、フォーム1、レポート1を任意に作成します。

    フォーム1にボタンを貼り付け、印刷ボタンとし、下記のイベントプロシージャを作成します。

    Option Compare Database

    Option Explicit

    Private Sub コマンド0_Click()

         DoCmd.OpenReport "レポート1", acViewNormal

    End Sub

    後は、フォーム1を開き、この印刷ボタンをひたすら押し続け印刷いたします。

    使用メモリ増加の確認は、Ctrl+Alt+Deleteを同時に押して、タスクマネージャを表示

    させ「プロセス」タブを選択し、MSACCESS.EXEの「メモリ使用量」を眺めます。

    (実際のテスト方法は、プリンタの電源を切り、プリンタスプールに出力しています)

    レポート1の内容が、「ああああ」のラベルしか無い簡単なものでも、10回以上印刷ボタンを

    ゆっくり押すと増加が確認できると思います。(今のOSは、Windows XP SP3です)

    「レポート1」は複雑であるほど、メモリ増加も激しいようです。

    Report_Unloadの問題ですが、システムの終了右上のXボタンを禁止する方法を見つけ

    ました。

    Option Compare Database

    Option Explicit

    Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, _

                                                 ByVal bRevert As Long) As Long

    Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Long, _

                                               ByVal uPosition As Long, _

                                               ByVal uFlags As Long) As Boolean

    Public Const MF_BYCOMMAND = &H0&

    Public Const SC_CLOSE = &HF060

    Private Sub Report_Load()

        Dim hwnd As Long

        Dim result As Long

        'システム終了 右上 X印を禁止する(表示されるが動作しない状態)

        hwnd = GetSystemMenu(Application.hWndAccessApp, 0)

        result = RemoveMenu(hwnd, SC_CLOSE, MF_BYCOMMAND)

    End Sub

    システムの終了右上のXボタンの見かけは同じですが、マウスでクリックしても

    Windowsは閉じなくなっています。見かけは悪いですが、実用的には使えると

    思います。X印に押せない雰囲気を出せれば良いのですが?

    この回答は役に立ちましたか?

    0 件のコメント コメントはありません
  4. Anonymous
    2010-06-23T03:10:24+00:00

    FUDA1 さん、こんにちは。

    Answersをご利用いただきまして、ありがとうございます。

    「『DoCmd.OpenReport レポート名, acViewNormal』のVBA命令を実行した後、メモリが開放されない」 ということですが、他のマシン (異なるOS) で実行なさった場合はどうなのかな、と気になりましたが、こちらも実際にどのようなコードを書かれたのか教えていただくと、「こんな方法はどうですか」 といったアドバイスが集まりやすいかもしれません。

    また、別のプロセスでの Report_Unloadイベント がOSによって動作が異なるということについてですが、もし仕様かどうか確認して回避策をお探しの場合は、製品サポートをご利用いただく方が早くて確実かもしれないです。

    マイクロソフト サポートオンライン

    http://support.microsoft.com/select/default.aspx?target=assistance

    お手数ですが、追加情報をお待ちしております。


    黒田まい – Microsoft Support

    この回答は役に立ちましたか?

    0 件のコメント コメントはありません