DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG·
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=39234>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND·
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=39234

           Summary: POIFS saved file causes VBA "File not found" error and
                    corrupts XLS
           Product: POI
           Version: 2.5
          Platform: Other
        OS/Version: Windows XP
            Status: NEW
          Severity: critical
          Priority: P2
         Component: POIFS
        AssignedTo: poi-dev@jakarta.apache.org
        ReportedBy: [EMAIL PROTECTED]


There have been several reports of this problem and although several indicate 
that the issue is resolved, it is not completely resolved.  These comments 
refer to 2.5.1.  However since the same code appears in 3.0 (devel) the same 
issue applies.  Earlier reports include: 36515, 17935, 15232.

The steps to reproduce the problem are simple:

1)      Create a new workbook
2)      Open the VBA editor and add a module called “modABC” 
        (note the case) and you don’t have to enter anything into the module
3)      Save the workbook and close Excel
4)      Read it in using POIFS and write it out again
5)      Open the new/updated workbook

When you open the workbook, the chances are that you will be greeted by a 
message saying “File not found”.  If this doesn’t occur on opening the 
workbook try editing the new module – or saving the workbook - then you will 
see the message.

The problem is that this module is 6 characters long and starts with a 
lowercase letter.  The error will also occur for modules with a wide range of 
names and arises because there is an error in the way POIFS saves the property 
table.

The rules for saving the table are documented on the POI web site and appear 
to be correct but there is an additional wrinkle and the implementation is not 
quite right.  The error is caused by the sorting of the property names in the 
comparator implementation in DirectoryProperty.java.

When a VBA macro is added to a document, Excel adds a new module with a 
default name starting with “Module1”.  Excel adds a new storage to the .xls 
document with a defined structure:

_VBA_PROJECT_CUR
----PROJECT
----PROJECTwm
----VBA
--------dir
--------Module1
--------Sheet1
--------ThisWorkbook
--------_VBA_PROJECT

The rules are that entries with shorter names should appear in a directory 
before entries with longer name and that entries with names that are the same 
length should be sorted alphabetically.  The implementation in 
DirectoryProperty.java get this right.  Unfortunately, the unstated rule is 
that Excel expects that the names will be sorted without case sensitivity.  As 
the comparator implementation in DirectoryProperty.java uses String.compareTo
() this only works providing the module, form and class names start with an 
upper case character.  Applying the example used in the steps to reproduce the 
error, the current implementation generated the following name order that 
Excel regards as invalid:

_VBA_PROJECT_CUR
----PROJECT
----PROJECTwm
----VBA
--------dir
--------Sheet1
--------ThisWorkbook
--------modABC
--------_VBA_PROJECT

Part of the fix is to change the comparator implementation to use 
String.compareToIgnoreCase().  This ensures that the names are in the right 
order.  However, it makes the _VBA_PROJECT entry appear first in the list and 
it MUST appear last.

The code below is the change I have made and that seems to work for me.  Maybe 
there is a more generic implementation of this fix that meets a wider set of 
rules.  If so, please let me know. 

Bill Seddon

        public int compare(Object o1, Object o2)
        {
            String VBA_PROJECT = "_VBA_PROJECT";
            String name1  = (( Property ) o1).getName();
            String name2  = (( Property ) o2).getName();
            int    result = name1.length() - name2.length();

            if (result == 0)
            {
                if (name1.compareTo(VBA_PROJECT) == 0)
                        result = 1; 
                else if (name2.compareTo(VBA_PROJECT) == 0)
                        result = -1;
                else
                        // result = name1.compareTo(name2);
                        result = name1.compareToIgnoreCase(name2);
            }
            return result;
        }

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
Mailing List:    http://jakarta.apache.org/site/mail2.html#poi
The Apache Jakarta POI Project: http://jakarta.apache.org/poi/

Reply via email to