[python-win32] handling VT_CY ?

Jorgensen, Jens jens.jorgensen@tallan.com
Fri, 21 Dec 2001 09:35:48 -0600


Recently I was dealing taking values from an ADO Recordset and sticking 
them into cells in an Excel spreadsheet. I was doing:

            sht.Cells(row, col).Value = rs.Fields.Item(i).Value


and I noticed that I was getting zero for all the values in Excel and I 
knew the recordset values were non-zero. Then I recalled that this 
particular column in the database was filled with currency values. I 
recalled that CY values are 64-bit signed integers. Python returns them 
as two (separate) integers. This is ok if you know about it but still 
wouldn't be nice to be able to assign from one VARIANT to another and 
always get back what you put in? I should think so! What I'll probably 
do for myself is whip up a quick python extension that will hold these 
values and support addition, subtraction, etc. It seems though that 
maybe something deeper is in order. Mark H, how do you think this should 
work? Is there an elegant way to deal with these numbers to get all the 
nice properties and stick to the principle of least surprise? Perhaps 
VT_CY values should map to long integers and leave people to understand 
the value is scaled by 10e-4 by themselves? Or we add a PyCY type to the 
win32 extensions? Could we convince the entire Python community to add a 
new native 64-bit 10e-4 scaled integer type to the language! (Just 
kidding about this last sentence.) This is kind of an ugly problem, 
especially since I don't see a clean and easy way to do the conversion 
in Python anyway. Perhaps we should think about VT_DECIMAL too since 
that seems to be the remaining nasty bit in VARIANT.

If we're going to do a PyCY, which seems to be the least painful and 
most fruitful way to handle this I guess the next step is to start 
talking about type promotions and things of that nature, a la:

class PyCY :
    def __add__(self, operand) :
        if type(operand) == IntType :
            # add the int to the CY value and return a CY
        if type(operand) == FloatType :
            # truncate the float at 4 decimal points, add to CY and 
return a CY?
            # convert the CY to a float, add to the operand, and return 
a float?

This is stick with the float type since you're going to potentially lose 
precision whichever way you choose. Well, I'll start thinking about 
this. In the meantime though Mark, is there a way I can assign to a 
VARIANT (set a property, that is) and have it pass as a VT_CY?

-- 
Jens B. Jorgensen
jens.jorgensen@tallan.com