DetailPage-MSS-KB

Microsoft small business knowledge base

Article ID: 225029 - Last Review: January 24, 2007 - Revision: 4.5

This article was previously published under Q225029

SUMMARY

This article demonstrates how to determine the version of Microsoft Excel that wrote a given workbook.

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 Beginning of File (BOF) record. This record contains useful attributes of the workbook, as well as the version. The following Microsoft Visual C++ code demonstrates how to open a file, read it, and return the version number based on the BOF:
  1. Create a new Win32 Console Application in Microsoft Developer Studio, and name it XlVer.
  2. Add a C++ Source File (.cpp) to the project and add the following code to the source file:
       #include <windows.h>
       #include <stdio.h>
    
       int XLVersionThatWroteFile(char *filename) {
          // Translate filename to Unicode
          WCHAR wcFilename[1024];
          int i = mbstowcs(wcFilename, filename, strlen(filename));
          wcFilename[i] = 0;
    
          // Open the document as an OLE compound document
          IStorage *pStorage;
          HRESULT hr;
          hr = ::StgOpenStorage(wcFilename, NULL,
                     STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage);
    
          if(FAILED(hr)) return 0;
          // 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)) {
             pStorage->Release();
             return 0;
          }
    
          // Get rupBuild & rupYear
          short rupBuild, rupYear;
          LARGE_INTEGER off;
          ULARGE_INTEGER newPos;
          off.QuadPart = 8;
          pStream->Seek(off, STREAM_SEEK_SET, &newPos);
          DWORD bytesRead;
          pStream->Read(&rupBuild, 2, &bytesRead);
          pStream->Read(&rupYear, 2, &bytesRead);
    
          // Let go of the IStorage pointer
          pStorage->Release();
    
          // Excel 8.0's rupyear = 1996
          if(rupYear == 1996) return 8;
          // Excel 9.0 comes after Excel 8.0...
          if(rupYear > 1996) return 9;
          // Excel 5.0's rupyear < 1994
          if(
             (rupYear < 1994) ||
             // Excel 5.0 & 7.0 have rupYear=1994 for some versions...
             (rupBuild == 2412) || (rupBuild == 3218) || (rupBuild == 3321)
          ) return 5;
          // All that's left is Excel 7.0
          return 7;
    
       }
    
       void main(int argc, char **argv) {
          if(argc != 2) {
             printf("Usage: XLVER filename.xls");
          }
          else {
             printf("Excel version = %d", XLVersionThatWroteFile(argv[1]));
          }
       }
    					
  3. Compile, and then find an .xls file on your machine and run the program as follows:

    XlVer.exe myfile.x

REFERENCES

For additional information, please see the following article in the Microsoft Knowledge Base:

178605 How To Determine the Version of a Microsoft Excel Workbook  (http://support.microsoft.com/kb/178605/EN-US/ )

APPLIES TO
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Excel 5.0 Standard Edition
  • Microsoft Excel 95 Standard Edition
Keywords: 
kbhowto KB225029
Share
Additional support options
Ask The Microsoft Small Business Support Community
Contact Microsoft Small Business Support
Find Microsoft Small Business Support Certified Partner
Find a Microsoft Store For In-Person Small Business Support