HOWTO: Determine Which Version of Excel Wrote a Workbook

ID: Q225029


The information in this article applies to:


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:


  3. 
       #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]));
          }
       } 
  4. Compile, and then find an .xls file on your machine and run the program as follows:


    C:\>XlVer.exe myfile.xls



REFERENCES

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

Q178605 HOWTO: Determine the Version of a Microsoft Excel Workbook

Additional query words:


Keywords          : kbole kbExcel kbVC kbGrpDSO kbOffice2000 
Version           : WINDOWS:5.0,7.0,97
Platform          : WINDOWS 
Issue type        : kbhowto 

Last Reviewed: June 1, 1999