文書番号: 319998 - 最終更新日: 2011年7月27日 - リビジョン: 5.0

[BUG] ActiveX データ オブジェクト (ADO) を使用して、開いている Excel ワークシートを照会するときにメモリ リークが発生します。

お知らせお使いのオペレーティング システムには適用しない情報が含まれている場合があります。

目次

すべて展開する | すべて折りたたむ

現象

場合は、ActiveX データ オブジェクト (ADO) を取得レコード セットは Excel で開いている Excel ワークシートから、メモリ リークが発生します。Excel プロセスで。クエリを繰り返す最終的に外を実行するを可能性があります。メモリ エラーの発生や原因 Excel 応答を停止します。

解決方法

ADO クエリで使用されるメモリを解放できません。閉じるし、ADO オブジェクトを解放します。メモリを解放する唯一の方法です。Excel を終了します。

可能な場合は、Excel ワークシートでだけを照会、Excel で開いたファイルではありません。

場合は、ワークシートを開いておく必要があります。動的再計算ワークシートの値の継続的なを許可するなど、単位) 使用、問題を回避するには、次の方法のいずれか。

方法 1

  • Jet OLE DB プロバイダーへの SELECT INTO 構文を使用します。Excel のデータを新規のワークシートにエクスポートします。SELECT INTO 構文を使用してエクスポートする詳細についてはデータは、Knowledge Base の資料を参照するのには、次の資料番号をクリックしてください。
    295646? (http://support.microsoft.com/kb/295646/ ) ADO で excel データ ソースからデータを転送するには、方法

方法 2

  • 使用して、 SaveCopyAs メソッドは、 ブック オブジェクト Excel オブジェクト モデルをプログラムで保存するには新しい名前の下にある Excel ファイルを開きます。[ファイルのコピーを問い合わせることができます、以前、ADO アプリケーションから、新しい名前を付けてを保存します。

状況

マイクロソフトはこれで記載されているマイクロソフト製品のバグであることを確認して、この資料の冒頭。

詳細

現象の再現手順

  1. 作成または Excel ワークシートの行と列の検索ADO を使用して問い合わせることができますのデータです。Excel を使用して、インポートするなど、[得意先] テーブルからサンプル データベースの Northwind へのアクセスします。
  2. Visual Basic 6.0 で、標準 EXE プロジェクトを作成します。でデフォルトで、Form1 が作成されます。ADO への参照を設定します。
  3. プロジェクトにモジュールを追加し、次を入力宣言のアプリケーション プログラミング インターフェイス (API) 呼び出し可能にします。パフォーマンス モニターのカウンターを使用して、メモリの使用量をチェックするのには
    Option Explicit
    
    'Performance monitor functions for Visual Basic from PDH.DLL
    Declare Function PdhVbOpenQuery Lib "pdh.dll" _
        (ByRef QueryHandle As Long) As Long
    Declare Function PdhCloseQuery Lib "pdh.dll" _
        (ByVal QueryHandle As Long) As Long
    Declare Function PdhVbAddCounter Lib "pdh.dll" _
        (ByVal QueryHandle As Long, ByVal CounterPath As String, _
        ByRef CounterHandle As Long) As Long
    Declare Function PdhRemoveCounter Lib "pdh.dll" _
        (ByVal CounterHandle As Long) As Long
    Declare Function PdhCollectQueryData Lib "pdh.dll" _
        (ByVal QueryHandle As Long) As Long
    Declare Function PdhVbGetDoubleCounterValue Lib "pdh.dll" _
        (ByVal CounterHandle As Long, ByRef CounterStatus As Long) As Double
    Declare Function PdhVbIsGoodStatus Lib "pdh.dll" _
        (ByVal StatusValue As Long) As Long
    Declare Function PdhVbGetOneCounterPath Lib "pdh.dll" _
        (ByVal PathString As String, ByVal PathLength As Long, _
        ByVal DetailLevel As Long, ByVal CaptionString As String) As Long
    Declare Function PdhVbCreateCounterPathList Lib "pdh.dll" _
        (ByVal DetailLevel As Long, ByVal CaptionString As String) As Long
    Declare Function PdhVbGetCounterPathFromList Lib "pdh.dll" _
        (ByVal Index As Long, ByVal Buffer As String, _
        ByVal BufferLength As Long) As Long
    Declare Function PdhVbGetCounterPathElements Lib "pdh.dll" _
        (ByVal PathString As String, ByVal MachineName As String, _
        ByVal ObjectName As String, ByVal InstanceName As String, _
        ByVal ParentInstance As String, ByVal CounterName As String, _
        ByVal BufferSize As Long) As Long
    					
  4. Form1 にコマンド ボタンを追加し、挿入をClick イベントに次のコードします。このコードは繰り返し Excel ファイルを照会します。メモリ使用量が表示されますはデバッグ (イミディ エイト) ウィンドウとします。
        Dim cn As ADODB.Connection
        Dim rs As ADODB.Recordset
        Dim i As Integer
        Dim max As Integer
        Dim r As Long
        Dim hPDHQuery As Long            'Handle to performance monitor query
        Dim hPDHCounter As Long          'Handle to performance monitor counter
        Dim strCounterPath               'Path to performance monitor counter
        Dim lngCounterStatus As Long     'Status of counter when checked
        Dim dblPrivateBytes As Double    'Value of counter when checked
        Set cn = New ADODB.Connection
    'Jet connection string.
        cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
            "Data Source=" & App.Path & "\test.xls;" & _
            "Extended Properties=Excel 8.0"
        'Initialize PDH query object.
        r = PdhVbOpenQuery(hPDHQuery)
        'Initialize counter.
    'Edit the value of the "strCounterPath" variable.
        strCounterPath = "\\<computername>\Process(Excel)\Private Bytes"
        r = PdhVbAddCounter(hPDHQuery, strCounterPath, hPDHCounter)
        'Gather data.
        r = PdhCollectQueryData(hPDHQuery)
        'Get counter value and process data.
        dblPrivateBytes = PdhVbGetDoubleCounterValue(hPDHCounter, _
            lngCounterStatus)
        If PdhVbIsGoodStatus(lngCounterStatus) Then
            Debug.Print "Memory used by Excel: " & CLng(dblPrivateBytes)
        Else
            Debug.Print "Invalid data."
        End If
    'Edit the value of the "max" variable.
        max = 100
        ReDim alngPrivateBytes(max)
        For i = 1 To max
            Set rs = New ADODB.Recordset
            rs.CursorLocation = adUseClient
    'Edit the query to reflect the name of the worksheet.
            rs.Open "SELECT * FROM [Customers$]", cn
            Do Until rs.EOF
                rs.MoveNext
            Loop
            rs.Close
            Set rs = Nothing
            r = PdhCollectQueryData(hPDHQuery)
            'Get counter value and process data.
            dblPrivateBytes = PdhVbGetDoubleCounterValue(hPDHCounter, _
                lngCounterStatus)
            'Process data.
            If lngCounterStatus = 0 Then
                Debug.Print "Memory used by Excel: " & CLng(dblPrivateBytes)
                alngPrivateBytes(i) = CLng(dblPrivateBytes)
            Else
                Debug.Print "Invalid data."
                alngPrivateBytes(0) = 0
            End If
        Next
        cn.Close
        Set cn = Nothing
        Debug.Print "Total increase for " & max & " iterations: " & _
            (CStr(alngPrivateBytes(max) - alngPrivateBytes(0)))
        Debug.Print "Average increase per iteration: " & _
            (CStr((alngPrivateBytes(max) - alngPrivateBytes(0))) / max)
        'Clean up.
        r = PdhRemoveCounter(hPDHCounter)
        r = PdhCloseQuery(hPDHQuery)
    					
  5. コードは次のように変更します。

    • 場所を反映するために、Jet 接続文字列を編集します。Excel テスト ファイルの。
      注: コメントには、次のように: ' Jet 接続文字列。
    • 使用すると、"strCounterPath"変数の値を編集します。ローカル ワークステーションの名前。
      注: コメントには、次のように: ' の値を編集、"strCounterPath"変数です。
    • ワークシート内の名前を反映するように、クエリを編集します。テスト データのファイルです。
      注: コメントには、次のように: ' 名前を反映するように、クエリを編集します。示すフラグ。
    • 目的の「最大」変数の値をを編集します。繰り返し回数。
      注: コメントには、次のように: '、「最大」の値を編集します。変数です。
  6. Excel アプリケーションを実行し、テストを Excel を開きますファイルです。
  7. Visual Basic アプリケーションを実行します。いるので、点灯、Excel プロセスでも使用されるメモリの増加、ADO オブジェクトが閉じられ、解放しました。

関連情報

詳細については、Knowledge Base の資料を参照するのには、次の資料番号をクリックしてください。
257819? (http://support.microsoft.com/kb/257819/ ) Visual Basic または VBA からのデータを Excel で ADO を使用するには、方法
詳細についてはVisual Basic からパフォーマンス カウンターの使用については、Knowledge Base の資料を参照するのには、次の資料番号をクリックしてください。
296526? (http://support.microsoft.com/kb/296526/ ) 情報: PDH Api の Visual Basic を使用してパフォーマンス データを収集します。
追加Excel エクスポート オプションの情報を表示するのには、以下の記事番号をクリックします。記事は、マイクロソフト サポート技術。
247412? (http://support.microsoft.com/kb/247412/EN-US/ ) 情報: Visual Basic から Excel にデータを転送する方法
246335? (http://support.microsoft.com/kb/246335/ ) Excel オートメーションを使用する ADO レコード セットからデータを転送するには、方法

この資料は以下の製品について記述したものです。
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Excel 2002 Standard Edition
キーワード:?
kbado kbmemory kbperformance kbprogramming kbbug kbiisam kbjet kbnofix kbprovider kbmt KB319998 KbMtja
機械翻訳機械翻訳
重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。
英語版 KB:319998? (http://support.microsoft.com/kb/319998/en-us/ )
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"