简体   繁体   中英

Using non-localized formulae in Excel automation

I've been playing around with basic Excel automation using the COM interface, mainly utilizing IDispatch::Invoke .

My test involved adding a formula in a freshly created Excel document. Using a devised wrapper library, it looks like this:

sheet.getObject( "Range", "A1" ).set( "Value", 23 );
sheet.getObject( "Range", "A2" ).set( "Value", 42 );
sheet.getObject( "Range", "A3" ).set( "Formula", "=SUMME(A1:A2)" ); // WTF?

Notice: I'm using the (german) localized formula name SUMME here, instead of the identifier SUM as expected. When doing the same with the macro recorder in Excel, the generated VBA code contains SUM . Using SUM in my C++ code, I end up with a #NAME? error in Excel.

Microsoft's documentation for the Range.FormulaLocal Property says the following:

Returns or sets the formula for the object, using A1-style references in the language of the user .

(emphasis was made by me).

So I hoped that using Formula instead of FormulaLocal I could get around these localization woes, but apparently this is not the case.

Is there any way I can use non localized formulae? I'd guess there's some well hidden setting.

Adding an answer to document what I've found out:

Workaround for Formula

To set the Formula property, there's ultimatively a call to IDispatch::Invoke , which was implemented as

object->Invoke(
    dispid,
    IID_NULL,
    LOCALE_USER_DEFAULT,  // <-- "locale context"
    DISPATCH_PROPERTYPUT,
    &dispparams,
    NULL,
    &excepinfo,
    &argerr ) );

Changing LOCALE_USER_DEFAULT to LOCALE_NEUTRAL has the effect that the properties Formula and FormulaLocal start to behave differently. In my german localized Excel installation the two calls

sheet.getObject( "Range", "A3" ).set( "FormulaLocal", "=SUMME(A1:A2)" );
sheet.getObject( "Range", "B3" ).set( "Formula", "=SUM(A1:A2)" );

do the same thing now.

Currently, this is not a real solution to my problem, as I usually expect things not working as documented to break silently behind my back . Proof: NumberFormat and NumberFormatLocal still do the same thing (!), that means I'm required to use the localized date format codes (eg "JJJJ-MM-TT" for ISO 8601) with both properties.

Workaround for NumberFormat

To build the format string: Use the Application.International Property .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM