HOWTO: Determine the Version of a Microsoft Excel Workbook
ID: Q178605
 
  |  
 
 
The information in this article applies to: 
- 
Microsoft Visual C++, 32-bit Editions, versions  5.0, 6.0
 
- 
Microsoft Excel  97 for Windows
 
- 
Microsoft Excel for Windows 95, versions  7.0, 7.0a
 
- 
Microsoft Excel for Windows, versions  5.0, 5.0a, 5.0c
  
 
 SUMMARY
This article demonstrates how to determine the version of a Microsoft Excel
Workbook (.xls).
 
 MORE INFORMATION
Microsoft Excel saves data using structured storage. In particular, it
creates a data stream called "Workbook" (previously just "Book") where
it saves the contents starting with a BOF (beginning of file) record. This
record contains useful attributes of the workbook, as well as the version.
The following Microsoft Visual C++ code demonstrates how to open the file,
read it, and return the version number based on the BOF.
 - Create a new "Win32 Console Application" in Microsoft Developer Studio.
 
 
 - Add a C++ Source File (.cpp) to the project and add the following code
   to the source file:
 
 
 
#include <windows.h>
#include <iostream.h>   // My additions
// BOF record from Microsoft Excel
typedef struct _xlbof
{
   char bofMarker; // Should be 0x09
   char vers;  // Version indicator for biff2, biff3, and biff4
               // = 0x00 -> Biff2
               // = 0x02 -> Biff3
               // = 0x04 -> Biff4
               // = 0x08 -> Biff5/Biff7/Biff8
   char skip[2]; // Unspecified
   short int vers2;  // Version number
                     // 0x0500 -> Biff5/Biff7
                     // 0x0600 -> Biff8
   short int dt;     // Substream type (not used in this example)
   short int rupBuild;  // Internal build identifier
   short int rupYear;   // Internal Build year
} XLBOF;
//* XLVersionFromFile() ******************************************
//* Returns
//*        n for BiffN
//*   i.e. 8 for Biff8 (Microsoft Excel 97)
//*
//*        Negative if an error occurs
//****************************************************************
int XLVersionFromFile(char *filename) {
   // Translate filename to Unicode
   WCHAR wcFilename[1024];
   int i = mbstowcs(wcFilename, filename, strlen(filename));
   wcFilename[i] = 0;
   IStorage *pStorage;
   HRESULT hr;
   XLBOF xlbof;
   // Open the document as an OLE compound document
   hr = ::StgOpenStorage(wcFilename, NULL,
              STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage);
   if(!FAILED(hr)) {
      // Open the data-stream where Microsoft Excel stores the data
      IStream *pStream;
      hr = pStorage->OpenStream(L"Workbook", NULL,
              STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);
      // If "Workbook" does not exist, try "Book"
      if(FAILED(hr)) {
         hr = pStorage->OpenStream(L"Book", NULL,
              STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);
      }
      if(!FAILED(hr)) {
         // Read the relevant BOF information
         DWORD dwCount; // bytes read
         pStream->Read(&xlbof, sizeof(XLBOF), &dwCount);
         // Let go of the IStream pointer
         pStream->Release();
      }
      else return -2;
      // Let go of the IStorage pointer
      pStorage->Release();
    }
    else return -1;
    // Determine which version to return
    if(xlbof.vers != 0x08) return (xlbof.vers + 4) / 2;
    else {
       switch(xlbof.vers2) {
         case 0x0500:  // Either Biff5 or Biff7
            // Biff7's rupYear is at least 1994
            if(xlbof.rupYear < 1994) return 5;
            // Check for specific builds of Microsoft Excel 5
            switch(xlbof.rupBuild) {
               case 2412: // XL5a
               case 3218: // XL5c
               case 3321: // NT XL5
                  return 5;
               default:
                  return 7;
            }
       case 0x0600:  return 8;
       }
    }
    // Version not recognized. Perhaps there is a newer version.
    return -3;
}
void main()
{
   int iretVal = 0;
   iretVal = XLVersionFromFile("C:\\Test.xls");
                               //Adapt the filename to your example
   cout << "The Excel Version is " << iretVal << "\n\n\r";
   return;
} 
 - In the main()function, you may need to modify the path and filename of
   the Microsoft Excel workbook in the following line of code:
 
 
 
 iretVal = XLVersionFromFile("C:\\Test.xls"); 
  
 REFERENCES
Microsoft Visual C++ Help, version 5.0; search on "structured storage"
 
 
Microsoft Developers Network (MSDN); search on "structured storage",
"Microsoft Excel file format", "BOF", "beginning of file"
 
 
Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2); search on
"Microsoft Excel file format", "BOF", "beginning of file"
 
Additional query words: 
excel97 excel8 xl5en32  
Keywords          : kbole kbExcel kbVC500 kbVC600 kbSDKExcel kbExcel97 kbDSupport  
Version           : WINDOWS:5.0,5.0a,5.0c,7.0,7.0a; winnt:5.0,6.0
 
Platform          : WINDOWS winnt  
Issue type        : kbhowto  
 |