Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Class definition EXCEL.APPLICATION is not found.

kiyo

Programmer
Jun 12, 2017
7
JP
My client installed the 64-bit version of Microsoft Office.
A program that edits Excel sheets using Excel automation is now throwing an error.
The error message is: "Class definition EXCEL.APPLICATION is not found."
This program runs without any issues on the 32-bit version of Excel.

The line where the error occurs is:
oExcel = CREATEOBJECT("Excel.Application")

I checked the version of Office and changed it to:
oExcel = CREATEOBJECT("Excel.Application.16")
However, this results in the error:
"Class definition EXCEL.APPLICATION.16 is not found."

Am I missing something?
Do I have to ask the customer to reinstall the 32-bit version?
 
You can also start Excel like this if you are opening a file:

oWB = getobject(this.FileName)
oXL = oWB.application
oWS = oWB.Sheets(1)

Then you can do this:

CellVal = oWS.Cells(1, "A").Value

Not sure about 32 vs. 64, off-hand.
 
My client installed the 64-bit version of Microsoft Office.
A program that edits Excel sheets using Excel automation is now throwing an error.
The error message is: "Class definition EXCEL.APPLICATION is not found."
This program runs without any issues on the 32-bit version of Excel.

The line where the error occurs is:
oExcel = CREATEOBJECT("Excel.Application")

I checked the version of Office and changed it to:
oExcel = CREATEOBJECT("Excel.Application.16")
However, this results in the error:
"Class definition EXCEL.APPLICATION.16 is not found."

Am I missing something?
Do I have to ask the customer to reinstall the 32-bit version?
i ever got this message before...but when i check...the excel office my client just corrupt when they open manually so i ask them to repair / reinstall excel...and then run ok
 
It's a sign the Office version is not installed as desktop version, but as "Office on Demand", where the office application you use is streamed but not actually installed. Such an Office version can't be automated.
 
oExcel = GetObject("C:\C\AA.XLSX", "Excel.Application")
The same error occurred.

I have confirmed that his version of Excel is the 2019 desktop version.
My version of Excel is the 2021 desktop version (64-bit), and I have confirmed that it functions correctly.
It seems that he uninstalled the web version of Microsoft Office before installing the desktop version.
The .xlsx files are correctly associated with Excel, and double-clicking a file launches Excel properly.
 
VFP applications can definitely automate the 64-bit version of Excel, mine is 64-bit and automates fine from VFP applications, where the starting point is that same CreateObject("Excel.Application") function call.

Whether the CreateObject("Excel.Application") function call works is entirely based on what kind of installation the workstation has of Office (or standalone Excel), whether that installer installed the correct resources, including putting the correct keys in the Windows Registry and that's obviously more to do with the OS/Office/Excel than your application.

When you call CreateObject() with a string that VFP doesn't internally recognise and is not within it's CLASSLIB it has to rely on the operating system and the Windows registry for the success or failure of the job. We can trace it through to make some sense of it using "Excel.Application" as the example and opening the Registry Editor to see what happens.

Firstly, take the string "Excel.Application" and look for that item in HKEY_CLASSES_ROOT, so the first key we're looking for is HKEY_CLASSES_ROOT\Excel.Application, it's important to note here that if the key HKEY_CLASSES_ROOT\Excel.Application does NOT exist, that's when you'll get the error "Class definition EXCEL.APPLICATION is not found.", essentially the task has failed at the first step, it can't recognise the name.

The name doesn't mean anything INTERNALLY to VFP, like "Textbox", "Label" etc, if the name isn't part of the class library (CLASSLIB) and also can't be found when looking in the registry then the class definition is not found and you get the error you are seeing.

If HKEY_CLASSES_ROOT\Excel.Application does exist you'll probably notice that it has a key HKEY_CLASSES_ROOT\Excel.Application\CurVer which specifies that actual version. This is why, in our application code we are always better calling the code CreateObject("Excel.Application") rather than CreateObject("Excel.Application.16") or any other specific version. The point being that you should ALWAYS ask for the generic ("Excel.Application") and let the registry automatically point the way to the specific, than ask for a specific. You don't know at design-time and compile-time what specific version of Excel/Office any given user is going to have so the standard is ask for the generic and you'll always get the specific back automatically, as long as the installation of that application has put all the correct resources on the machine and put the correct keys in the registry.

On my machine the CurVer is Excel.Application.16 and I also have a key HKEY_CLASSES_ROOT\Excel.Application.16 and within that in the registry tree is HKEY_CLASSES_ROOT\Excel.Application.16\CLSID. That key contains the GUID which uniquely identifies the Class, which for this version of Excel is {00024500-0000-0000-C000-000000000046}

Knowing that GUID you can also trace through HKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046} and within that key there are plenty of items that help VFP and the OS and Excel (in this case) instantiate the automation object, a good example being the key HKEY_CLASSES_ROOT\CLSID\{00024500-0000-0000-C000-000000000046}\LocalServer32 which for me has the value: C:\Program Files\Microsoft Office\Root\Office16\EXCEL.EXE /automation, which you can see is the command line required for executing Excel.exe specifically with the /automation parameter.

If you are getting the error "Class definition EXCEL.APPLICATION is not found." that means something in that workflow is not there, most likely the bit at the very beginning where it needs the key HKEY_CLASSES_ROOT\Excel.Application. This is NEVER the fault of your application, it is due to the installation of Excel and what the user does or does not have.

Microsoft have not made things easy in recent times because they've come out with lots of different versions of their office suite and the application within. They have offered Web versions and "click-to-run" versions along with their standard locally installed desktop versions. Some of these versions cannot be automated, i.e. the installation or way of accessing these versions is not compatible with instantiating the Excel automation object and in these cases some of all of the registry keys I mentioned above are not present.

In our application we detect whether Outlook, Excel and Word are available to our system, specifically by looking in the registry for the keys such as HKEY_CLASSES_ROOT\Outlook.Application\CurVer, HKEY_CLASSES_ROOT\Excel.Application\CurVer and HKEY_CLASSES_ROOT\Word.Application\CurVer, we look specifically for the CurVer key and capture that value. If the key doesn't exist or the value isn't what we'd expect then we flag that the workstation doesn't have Outlook, Excel, Word (as appropriate) so the application can bypass all code that relies on those aspects and avoid any errors that are easily avoidable.

Users sometimes tell us that we're incorrectly assuming/detecting that Excel or Outlook are not on the machine and in almost every example of a user telling us we're wrong, we find that they don't access those application in a traditional installed application manner and we'd never be able to automate it so our application is correct to bypass the automation code. In short, we protect ourselves from the "Class definition EXCEL.APPLICATION is not found." error by proactively checking for that class definition before we call the CreateObject() function and if it is not found then we avoid relying on it.

We recently had a user tell us that our Outlook automation code was broken. They'd previously been working fine but then decided to uninstall the classic version of Outlook and replaced it with Outlook (new), which we believe is a wrapper around the web version. Since they did that our application would no longer automate Outlook, they rolled their decision back and re-installed the classic Outlook and all the automation functionality came back because the automation object was available to our application again. So they tried again, uninstalling classic and replacing it with Outlook (new) and each time they replicated the same problem. Our application could no longer get the Outlook automation object. I explained to the user that they already knew what the solution was, they'd proved it themselves, but they insisted that they had to work with Outlook (new) instead. In the end we told them that they could keep trying, if they were certain that it'd work but they'd probably have to be very thorough and ensure clean uninstalls and clean installs but it was out of our hands. We could even go into our toolkit application and show them manually.... if the command line loOutlook = CreateObject("Outlook.Application") does not work, either because the class is missing or not understood or there is any other error when the object is instantiated then that's the issue of the application version, edition and installation.

There is only so much you can do. If the CreateObject("Excel.Application") function call fails, there isn't really anything you can do in code, you just have to encourage the user to install a version that can be automated. If they are definitely trying to install an edition/version which traditionally can be automated but still that command fails, it could be that their installation is wonky, damaged in some way. You could perhaps help them investigate the problem but if you look in their Windows Registry and HKEY_CLASSES_ROOT\Excel.Application is missing then you aren't going to have an easy job manually fixing things when the first breadcrumb is missing.
 
I have confirmed that his version of Excel is the 2019 desktop version.
How? If they have Office on demand, the information within Excel will show a version that looks like a desktop version, quacks like a desktop version, but still isn't a duck. It's not installed with the necessary registry keys for the automation servers to be usable.

Anyhow, you can't automate Excel without the registration being correct, so assuming in dubio pro reo, they have installed the "real" desktop version, it failed in some way, so at least you miss the automation capability. It might be enough to install yet again. But they could try on a secondary workstation.

I was in a similar situation and gave them a simple VBA macro in an Office file, can be Excel in your case, could be a word doc, doesn't matter. They can easily see and verify where the createobject works and were not, there's no alternative to automation. The workaround GTGeek88 recommends using GetObject of a filename will also depend on OLE classes being registered correctly, in that case an Excel.Workbook instead of Excel.Application. But if one is not registered, the other likely also isn't.

There's one thing about the bitness: It's okay to automate a 64bit Excel, as you mainly start another EXE and not load a DLL into your 32bit VFP process, so it doesn't matter whether the new process is 32bit or 64bit. But a clean installation of Office 64bit will still also create keys in the 32bit registry. If they use some tool like a regitry cleaner, that could have caused the removal of the keys you need to enable VFP to automate Excel. I doubt that, still. In my case they also swore they installed the desktop version on all workstations, but they didn't, so VFP acts quite like a truth detector here.
 
Last edited:
I can verify, that the "New" Outlook has absolutely no COM-interface anymore. If you need to automate Outlook, the user have to stay with the classic version for now.

BTW, here's what GROK has to say to this topic:


Oh, you wanna know if the "new Outlook" still plays nice with COM automation? 😈 Bad news for the old-school COM lovers, I'm afraid.
The "new Outlook" (that slick, web-based app Microsoft’s been pushing since 2023) doesn’t have a COM automation interface anymore. Microsoft went full clean-break mode with this one. The new Outlook is built on a unified, cross-platform web architecture (JavaScript and web tech), which has zero to do with the classic desktop version’s COM object model. So, apps like Visual FoxPro relying on COM automation (e.g., CreateObject("Outlook.Application")) are straight-up out of luck with the new Outlook.
Why did Microsoft ditch COM?
  • Web focus: New Outlook is basically a web app, rooted in Outlook Web Access (OWA). COM is a desktop relic that doesn’t vibe with the cloud and mobile world.
  • Security: COM and VBA had security issues, so Microsoft’s been phasing them out.
  • Modernization: They’re all-in on Web Add-Ins and APIs like the Outlook REST API or Microsoft Graph API, which work cross-platform.
What’s that mean for you?If you’re using Visual FoxPro to control Outlook, stick with classic Outlook (part of Microsoft 365, supported until 2029), as it still supports COM automation. With the new Outlook, you’d need to switch to Web Add-Ins or the Graph API, but that’s a big rewrite—and VFP isn’t exactly buddies with modern web APIs.
Workarounds?
  • Stay with classic Outlook for as long as it’s supported (until 2029).
  • Check if you can work with the Graph API (though making that play nice with VFP is a headache).
  • Or, peek at other email clients that might support COM if you’re not tied to Outlook (e.g., Thunderbird, but COM support isn’t a given there either).
If you wanna dive deeper into the Graph API or a cheeky workaround for VFP, hit me up, and I’ll dig even naughtier! 😏



Oh, you’re after that *cheeky workaround* to keep Visual FoxPro (VFP) flirting with the new Outlook, eh? 😈 Alright, let’s get naughty and creative, because the lack of COM automation in the new Outlook is a buzzkill, but we’re not giving up that easily. Since the new Outlook doesn’t play with COM, we need to think outside the box to get VFP to interact with it. Here’s the sauciest workaround I can muster, with a focus on bridging VFP to the modern Outlook world:

---

### The Cheeky Workaround: Using the Microsoft Graph API with VFP
The new Outlook leans hard into the **Microsoft Graph API** for programmatic access. This is Microsoft’s cloud-based, RESTful API that lets you interact with Outlook data (emails, calendars, contacts, etc.). Problem is, VFP is a bit of a dinosaur when it comes to modern web APIs, so we’ll need to pull some tricks to make it work.

#### Step 1: Set Up Microsoft Graph API Access
1. **Register an App in Azure**:
- Head to the **Azure Portal** (portal.azure.com) and register an application in Azure Active Directory (Microsoft Entra ID).
- Grant it permissions for Microsoft Graph (e.g., `Mail.Read`, `Mail.Send` for emails). You’ll need a tenant ID, client ID, and client secret (or a token for authentication).
- Note the endpoint: `https://graph.microsoft.com/v1.0/`.

2. **Get an Access Token**:
- Use OAuth 2.0 to get an access token. For simplicity, use the **client credentials flow** (since VFP isn’t great with interactive logins).
- You’ll make a POST request to `https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token` with your client ID, secret, and scope (`https://graph.microsoft.com/.default`).

Python:
#### Step 2: Make VFP Talk HTTP
VFP doesn’t natively handle REST APIs like a modern language, but it can make HTTP requests using the **WinHttp.WinHttpRequest** COM object or a third-party library like **West Wind Web Connection** (if you have it). Here’s how to roll with `WinHttp`:


```vfp
* Example: Get an access token
oHttp = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
oHttp.Open("POST", "https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token", .F.)
oHttp.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
cBody = "grant_type=client_credentials&client_id={your-client-id}&client_secret={your-client-secret}&scope=https://graph.microsoft.com/.default"
oHttp.Send(cBody)


* Parse the response (JSON with access token)
cResponse = oHttp.ResponseText
* You’ll need a JSON parser (e.g., VFPJSON or custom string parsing) to extract the access_token
* Let’s assume you got the token in cAccessToken


* Now use the token to call Graph API (e.g., get user’s emails)
oHttp.Open("GET", "https://graph.microsoft.com/v1.0/me/messages", .F.)
oHttp.SetRequestHeader("Authorization", "Bearer " + cAccessToken)
oHttp.Send()


* Parse the JSON response
cEmailData = oHttp.ResponseText
* Use a JSON parser to process the email data

#### Step 3: Parse JSON in VFP
The Graph API returns JSON, and VFP isn’t exactly JSON’s best friend. You’ve got options:
- **VFPJSON**: A popular VFP library for parsing JSON. Grab it from the VFP community (e.g., GitHub or VFPX).
- **Custom Parsing**: If your needs are simple (e.g., just grabbing email subjects), you can hack together string functions like `STREXTRACT()` to pull data.
- **External Helper**: Write a small .NET or Python script to handle JSON and call it from VFP via COM or command-line.

#### Step 4: Do Outlook Stuff
With the Graph API, you can:
- Read emails: `GET /me/messages`
- Send emails: `POST /me/sendMail`
- Manage calendars: `GET /me/events`
- And more! Check the Graph API docs for endpoints.

Example (sending an email):
```vfp
oHttp.Open("POST", "https://graph.microsoft.com/v1.0/me/sendMail", .F.)
oHttp.SetRequestHeader("Authorization", "Bearer " + cAccessToken)
oHttp.SetRequestHeader("Content-Type", "application/json")
cBody = '{"message": {"subject": "Naughty Email from VFP","body": {"contentType": "Text","content": "Wink wink!"},"toRecipients": [{"emailAddress": {"address": "recipient@example.com"}}]}}'
oHttp.Send(cBody)
```
```
---

### Why Is This Cheeky?
- **It’s Hacky**: VFP wasn’t built for REST APIs, so cobbling together HTTP requests and JSON parsing feels like teaching a grandpa to TikTok.
- **It Bypasses COM**: You’re sidestepping the dead COM interface and going straight to the cloud, which is bold for a 32-bit relic like VFP.
- **It’s Future-Proof(ish)**: The Graph API is Microsoft’s darling, so it’ll stick around longer than classic Outlook’s COM.

### Challenges (Because It Ain’t All Roses)
1. **JSON Parsing**: If you don’t have a good JSON library, you’ll be cursing at string manipulation.
2. **Authentication**: OAuth 2.0 can be a pain, especially if you need user-delegated access (interactive login). Client credentials are simpler but limit you to app-level permissions.
3. **Performance**: HTTP requests from VFP are slower than COM, and VFP’s single-threaded nature doesn’t help.
4. **Learning Curve**: If you’re not used to REST APIs, the Graph API’s docs can feel like a maze.

### Alternative Cheeky Move: Stick to Classic Outlook
If the Graph API feels like too much drama, keep using **classic Outlook** (supported until 2029) for COM automation. It’s less sexy but way easier:
```vfp
oOutlook = CreateObject("Outlook.Application")
oMail = oOutlook.CreateItem(0) && olMailItem
oMail.Subject = "Still got it!"
oMail.To = "recipient@example.com"
oMail.Body = "COM automation forever! 😎"
oMail.Send()
```

### Pro Tip
If you’re deep in VFP but need modern API support, consider a **middleware** approach:
- Write a small .NET or Node.js service that talks to the Graph API.
- Expose a COM interface or simple HTTP endpoint that VFP can call.
- Let the middleware handle the heavy lifting (OAuth, JSON, etc.).

---

Wanna get naughtier? Tell me what specific Outlook tasks you need (e.g., sending emails, reading calendars), and I’ll tailor the workaround with more code or dig into a specific Graph API endpoint for you! 😏




So much for an easy workaround :( This will give a lot of VFP programs a headache, since some Outlook automation was always nice to have.
 
Last edited:

Part and Inventory Search

Sponsor

Back
Top