Erro: A fuga de memória ocorre quando consulta uma folha de cálculo Excel aberta utilizando o ActiveX Data Objects (ADO)

Traduções de Artigos Traduções de Artigos
Artigo: 319998 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sintomas

Ao obter um Microsoft ActiveX Data Objects (ADO) o conjunto de registos de uma folha de cálculo do Excel que esteja aberto no Excel, uma fuga de memória ocorre no processo do Excel. Consultas repetidas eventualmente poderão causar Excel ficar sem memória e aumentar um erro ou fazer com que o Excel deixe de responder.

Resolução

A memória utilizada pelas consultas de ADO não pode ser reclamada fechando e libertar os objectos ADO. A única forma de libertar a memória é sair do Excel.

Se possível, consulta a folha de cálculo do Excel apenas enquanto o ficheiro não estiver aberto no Excel.

Se a folha de cálculo deve permanecer aberta (por exemplo, para permitir dinâmico novo cálculo de valores de folha de cálculo de uma forma contínua) utilize um dos seguintes métodos para contornar o comportamento:

Método 1

  • Utilize a sintaxe SELECT INTO o fornecedor de OLE DB do Jet para exportar os dados do Excel para uma nova folha de cálculo.Para obter informações adicionais sobre como utilizar a sintaxe SELECT INTO para exportar dados, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
    295646Como transferir dados de origem de dados ADO para o Excel com o ADO

Método 2

  • Utilize o método SaveCopyAs do objecto de livro no modelo de objecto do Excel para guardar programaticamente o ficheiro de Excel aberto com um novo nome. Em seguida, pode consultar a cópia do ficheiro que guardou anteriormente com um novo nome da aplicação do ADO.

Ponto Da Situação

A Microsoft confirmou que este erro ocorre nos produtos da Microsoft listados no início deste artigo.

Mais Informação

Passos para reproduzir o comportamento

  1. Crie ou localize uma folha de cálculo Excel com linhas e colunas de dados que podem ser consultados utilizando ADO. Por exemplo, pode utilizar o Excel para importar a tabela clientes de exemplo Adamastor Access base de dados.
  2. No Visual Basic 6.0, crie um projecto EXE padrão. Por predefinição, é criado o Form1. Defina uma referência ao ADO.
  3. Adicionar um módulo ao projecto e introduza as declarações seguintes para chamadas de API que permitem-lhe verificar a utilização da memória utilizando contadores do Monitor de desempenho de programação de aplicações:
    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. Adicionar um botão de comando ao Form1 e, em seguida, insira o seguinte código no evento clicar. Este código repetidamente consulta um ficheiro do Excel e apresenta a utilização da memória na janela de depuração (imediata).
        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. Efectue as seguintes alterações no código:

    • Edite a cadeia de ligação do Jet para reflectir a localização do ficheiro de teste do Excel.
      NOTA: É comentado da seguinte forma: ' Jet cadeia de ligação.
    • Edite o valor da variável "strCounterPath" para utilizar o nome de estação de trabalho local.
      NOTA: É comentado da seguinte forma: ' Editar o valor da variável "strCounterPath".
    • Edita a consulta para reflectir o nome da folha de cálculo no ficheiro com os dados de teste.
      NOTA: É comentado da seguinte forma: ' Editar a consulta para reflectir o nome da folha de cálculo.
    • Edite o valor da variável "máximo" para o número pretendido de repetições.
      NOTA: É comentado da seguinte forma: ' Editar o valor da variável "máximo".
  6. Executar a aplicação Excel e abra o teste Excel ficheiro.
  7. Execute a aplicação do Visual Basic. Tenha em atenção que existe um aumento constante na memória que é utilizada pelo processo do Excel, mesmo que tenham sido fechados e disponibilizados objectos ADO.

Referências

Para obter informações adicionais, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
257819Como utilizar ADO com dados do Excel a partir do Visual Basic ou VBA
Para obter informações adicionais sobre a utilização de contadores de desempenho a partir do Visual Basic, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
296526INFO: Recolher dados de desempenho com PDH APIs do Visual Basic
Para obter informações adicionais sobre opções de exportação do Excel, clique os números de artigo existente abaixo para visualizar os artigos na base de dados de conhecimento da Microsoft:
247412INFO: Métodos para transferir dados para o Excel a partir do Visual Basic
246335Como transferir dados a partir de um conjunto de registos ADO para o Excel com a automatização

Propriedades

Artigo: 319998 - Última revisão: 12 de fevereiro de 2007 - Revisão: 3.3
A informação contida neste artigo aplica-se a:
  • Microsoft Excel 2000 Standard Edition
  • Microsoft OLE DB Provider for Jet 4.0
  • Microsoft Excel 97 Standard Edition
  • Microsoft Excel 2002 Standard Edition
Palavras-chave: 
kbmt kbado kbmemory kbperformance kbprogramming kbbug kbiisam kbjet kbnofix kbprovider KB319998 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 319998

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com