Iniciar sessão com a Microsoft
Iniciar sessão ou criar uma conta.
Olá,
Selecione uma conta diferente.
Tem várias contas
Selecione a conta com a qual pretende iniciar sessão.

Sintomas

Quando tenta utilizar o GetObject (Microsoft Visual Basic) ou GetActiveObject (Microsoft Visual C++) para automatizar uma aplicação do Microsoft Office, obtém uma das seguintes mensagens de erro, apesar de a aplicação do Office estar em execução:

Mensagem de erro 1

Erro de tempo de execução "429":
O componente ActiveX não consegue criar o objeto

Mensagem de erro 2

Erro: 0x800401e3 "Operação indisponível"

Causa

Embora a aplicação do Office esteja em execução, pode não estar registada na Tabela de Objetos em Execução (ROT). Uma instância em execução de uma aplicação do Office tem de ser registada na ROT antes de poder ser anexada ao com GetObject (Visual Basic) ou GetActiveObject (Visual C++).

Quando uma aplicação do Office é iniciada, não regista imediatamente os objetos em execução. Isto otimiza o processo de arranque da aplicação. Em vez de se registar no arranque, uma aplicação do Office regista os objetos em execução na ROT assim que perder o foco. Por conseguinte, se tentar utilizar GetObject ou GetActiveObject para anexar a uma instância em execução de uma aplicação do Office antes de a aplicação perder o foco, poderá receber um dos erros acima.

Resolução

Com o código, pode alterar o foco da aplicação do Office para a sua própria aplicação (ou para outra aplicação) para permitir que se registe na ROT. Além disso, se o seu código estiver a iniciar o ficheiro exe da aplicação do Office, poderá ter de aguardar que a aplicação do Office termine o carregamento antes de tentar anexar à instância em execução. Um exemplo de código é fornecido como solução na secção "Mais Informações".

Estado

Este comportamento é por predefinição.

Mais Informações

Na maioria das situações, os programadores que pretendem automatizar uma aplicação do Office têm de utilizar CreateObject (Visual Basic) ou CoCreateInstance (Visual C++) para iniciar uma nova instância da aplicação do Office.

No entanto, existem casos em que pode preferir automatizar uma aplicação do Office que já está em execução: por exemplo, se o utilizador tiver iniciado anteriormente a aplicação do Office. Em alternativa, se tiver iniciado o executável da aplicação do Office com código para poder especificar parâmetros de linha de comandos para a aplicação. Para automatizar a aplicação do Office em execução, tem de utilizar GetObject ou GetActiveObject.

Passos para reproduzir o comportamento

  1. Inicie o Microsoft Visual Basic e crie um novo projeto EXE Standard. O Formulário1 é criado por predefinição.

  2. Adicione um controlo CommandButton a Form1.

  3. Adicione o seguinte código ao módulo de código do formulário.

    Private Sub Command1_Click()
        Dim oExcel As Object
        ' Launch a new instance of Microsoft Excel:
        Shell "C:\Program Files\Microsoft Office\Office\Excel.EXE", _
           vbMinimizedNoFocus
        ' An error 429 occurs on the following line:
        Set oExcel = GetObject(, "Excel.Application")
        MsgBox oExcel.Name
        Set oExcel = Nothing
    End Sub
    
  4. Certifique-se de que a localização do Excel.exe está correta no exemplo de código.

  5. Saia do Microsoft Excel se já estiver em execução.

  6. Prima F5 para executar o projeto e clique em Comando1.

Solução

Para contornar o problema, pode:

  • Concentre-se na aplicação do Office ao alterar o segundo argumento da função Shell para vbMinimizedFocus, vbMaximizedFocus ou vbNormalFocus.

  • Dê o foco ao seu formulário do Visual Basic.

  • Tente GetObject enquanto contabiliza o tempo de carregamento da aplicação do Office.

O seguinte código revisto ilustra esta solução.

Private Declare Sub Sleep Lib "kernel32" _
    (ByVal dwMilliseconds As Long)

Private Sub Command1_Click()
    Dim intSection As Integer
    Dim intTries As Integer
    Dim oExcel As Object

    ' Enable error handler for this procedure:
    On Error GoTo ErrorHandler

    ' Launch Microsoft Excel, giving it focus:
    Shell "C:\Program Files\Microsoft Office\Office\Excel.EXE", _
        vbMinimizedFocus 'other options for starting with
        'focus: vbMaximizedFocus and vbNormalFocus

    ' Move focus back to this form. (This ensures the Office
    '  application registers itself in the ROT, allowing
    '  GetObject to find it.)
    Me.SetFocus

    ' Attempt to use GetObject to reference the running
    '  Office application:
    intSection = 1 'attempting GetObject...
    Set oExcel = GetObject(, "Excel.Application")
    intSection = 0 'resume normal error handling

    ' Now you can automate Microsoft Excel:
    MsgBox oExcel.Name & ": able to GetObject after " & _
        intTries + 1 & " tries.", vbMsgBoxSetForeground

    ' Finished with automation so release your reference:
    Set oExcel = Nothing

    ' Exit procedure:
    Exit Sub

ErrorHandler:
    If intSection = 1 Then 'GetObject may have failed because the
    'Shell function is asynchronous; enough time has not elapsed
    'for GetObject to find the running Office application. Wait
    'wait 1/2 seconds and retry the GetObject. If you try 20 times
    'and GetObject still fails, assume some other reason
    'for GetObject failing and exit the procedure.
        intTries = intTries + 1
        If intTries < 20 Then
            Sleep 500 ' wait 1/2 seconds
            Resume 'resume code at the GetObject line
        Else
            MsgBox "GetObject still failing. Process ended.", _
                vbMsgBoxSetForeground
        End If
    Else 'intSection = 0 so use normal error handling:
        MsgBox Error$
    End If
End Sub

Solução para C++

Se estiver a programar em C++, o seguinte exemplo de código demonstra uma solução semelhante à apresentada no exemplo do Visual Basic acima. Tenha em atenção que SetForegroundWindow é utilizado para afastar o foco do Excel, permitindo-lhe registar os objetos em execução.

//Store the handle of the currently active window...
HWND hwndCurrent = ::GetForegroundWindow();

//Launch Excel and wait until it is waiting for
//user input...
STARTUPINFO Start;
PROCESS_INFORMATION ProcInfo;
ZeroMemory(&Start,sizeof(STARTUPINFO));
Start.cb=sizeof(Start);
Start.dwFlags = STARTF_USESHOWWINDOW;
Start.wShowWindow = SW_SHOWMINIMIZED;

//Change the path to Excel as needed...
LPSTR pszExcelPath = 
      "c:\\program files\\microsoft office\\office\\excel.exe";

::CreateProcess(NULL, pszExcelPath, 0, 0, 1,
       NORMAL_PRIORITY_CLASS, 0, NULL, &Start, &ProcInfo);


if((::WaitForInputIdle(ProcInfo.hProcess, 10000))==WAIT_TIMEOUT)
{
    ::MessageBox(NULL, "Timed out waiting for Excel.", NULL,  
                 MB_OK);
}

//Restore the active window to the foreground...
//  NOTE: If you comment out this line, the code will fail!
::SetForegroundWindow(hwndCurrent);

//Initialize COM library...
::CoInitialize(NULL);

//Attach to the running instance...
CLSID clsid;
CLSIDFromProgID(L"Excel.Application", &clsid);  
IUnknown *pUnk = NULL;
IDispatch *pDisp = NULL;

for(int i=1;i<=5;i++) //try attaching for up to 5 attempts
{
   HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
   if(SUCCEEDED(hr)) 
   {
       hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pDisp);
       break;
   }
   ::Sleep(1000);
}

if (!pDisp) {
    ::MessageBox(NULL, "Failed to find instance!!", "Error", 
                 MB_ICONHAND);
}
else {
    ::MessageBox(NULL, "Got instance of Excel!", "Success", MB_OK);
}

//Release the no-longer-needed IUnknown...
if (pUnk) 
    pUnk->Release();

//... Add your automation code for Excel here ...

//Release pDisp when no longer needed...
if (pDisp)
    pDisp->Release();

//Cleanup COM...
CoUninitialize();

Referências

Para obter mais informações, clique nos seguintes números de artigo para ver o artigo:

Como encontrar o caminho de instalação de uma aplicação do Office

Precisa de mais ajuda?

Quer mais opções?

Explore os benefícios da subscrição, navegue em cursos de formação, saiba como proteger o seu dispositivo e muito mais.

As comunidades ajudam-no a colocar e a responder perguntas, a dar feedback e a ouvir especialistas com conhecimentos abrangentes.

Estas informações foram úteis?

Quão satisfeito está com a qualidade do idioma?
O que afetou a sua experiência?
Ao selecionar submeter, o seu feedback será utilizado para melhorar os produtos e serviços da Microsoft. O seu administrador de TI poderá recolher estes dados. Declaração de Privacidade.

Obrigado pelo seu feedback!

×