1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vbawsfunction.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/table/XCell.hpp>
32 #include <com/sun/star/table/XColumnRowRange.hpp>
33 #include <com/sun/star/beans/XIntrospection.hpp>
34 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
35 #include <com/sun/star/sheet/XFunctionAccess.hpp>
36 #include <com/sun/star/sheet/XCellRangesQuery.hpp>
37 #include <com/sun/star/sheet/CellFlags.hpp>
38 #include <com/sun/star/reflection/XIdlMethod.hpp>
39 #include <com/sun/star/beans/MethodConcept.hpp>
40 #include <comphelper/processfactory.hxx>
41 #include <cppuhelper/queryinterface.hxx>
42 #include <comphelper/anytostring.hxx>
44 #include "vbawsfunction.hxx"
45 #include "compiler.hxx"
47 using namespace com::sun::star
;
48 using namespace ooo::vba
;
50 ScVbaWSFunction::ScVbaWSFunction( const uno::Reference
< XHelperInterface
>& xParent
, const css::uno::Reference
< css::uno::XComponentContext
>& xContext
): ScVbaWSFunction_BASE( xParent
, xContext
)
55 uno::Reference
< beans::XIntrospectionAccess
>
56 ScVbaWSFunction::getIntrospection(void) throw(uno::RuntimeException
)
58 return uno::Reference
<beans::XIntrospectionAccess
>();
62 ScVbaWSFunction::invoke(const rtl::OUString
& FunctionName
, const uno::Sequence
< uno::Any
>& Params
, uno::Sequence
< sal_Int16
>& /*OutParamIndex*/, uno::Sequence
< uno::Any
>& /*OutParam*/) throw(lang::IllegalArgumentException
, script::CannotConvertException
, reflection::InvocationTargetException
, uno::RuntimeException
)
64 uno::Reference
< lang::XMultiComponentFactory
> xSMgr( mxContext
->getServiceManager(), uno::UNO_QUERY_THROW
);
65 uno::Reference
< sheet::XFunctionAccess
> xFunctionAccess(
66 xSMgr
->createInstanceWithContext(::rtl::OUString::createFromAscii(
67 "com.sun.star.sheet.FunctionAccess"), mxContext
),
68 ::uno::UNO_QUERY_THROW
);
69 uno::Sequence
< uno::Any
> aParamTemp
;
70 sal_Int32 nParamCount
= Params
.getLength();
71 aParamTemp
.realloc(nParamCount
);
72 const uno::Any
* aArray
= Params
.getConstArray();
73 uno::Any
* aArrayTemp
= aParamTemp
.getArray();
75 for (int i
=0; i
< Params
.getLength();i
++)
77 aArrayTemp
[i
]= aArray
[i
];
78 uno::Reference
<excel::XRange
> myRange( aArray
[ i
], uno::UNO_QUERY
);
81 aArrayTemp
[i
] = myRange
->getCellRange();
84 else if ( aArray
[ i
].getValueType().getTypeClass() == uno::TypeClass_BOOLEAN
)
86 sal_Bool
bValue( sal_False
);
87 aArray
[ i
] >>= bValue
;
89 aArrayTemp
[ i
] <<= double( 1.0 );
91 aArrayTemp
[ i
] <<= double( 0.0 );
94 else if ( aArray
[ i
].getValueType().getTypeClass() == uno::TypeClass_SEQUENCE
)
96 // the sheet.FunctionAccess service doesn't deal with Sequences, only Sequences of Sequence
97 uno::Type aType
= aArray
[ i
].getValueType();
98 if ( aType
.equals( getCppuType( (uno::Sequence
<sal_Int16
>*)0 ) ) )
100 uno::Sequence
< uno::Sequence
< sal_Int16
> > aTmp(1);
101 aArray
[ i
] >>= aTmp
[ 0 ];
102 aArrayTemp
[i
] <<= aTmp
;
104 else if ( aType
.equals( getCppuType( (uno::Sequence
<sal_Int32
>*)0 ) ) )
106 uno::Sequence
< uno::Sequence
< sal_Int32
> > aTmp(1);
107 aArray
[ i
] >>= aTmp
[ 0 ];
108 aArrayTemp
[i
] <<= aTmp
;
110 else if ( aType
.equals( getCppuType( (uno::Sequence
<double>*)0 ) ) )
112 uno::Sequence
< uno::Sequence
< double > > aTmp(1);
113 aArray
[ i
] >>= aTmp
[ 0 ];
114 aArrayTemp
[i
] <<= aTmp
;
116 else if ( aType
.equals( getCppuType( (uno::Sequence
<rtl::OUString
>*)0 ) ) )
118 uno::Sequence
< uno::Sequence
< rtl::OUString
> > aTmp(1);
119 aArray
[ i
] >>= aTmp
[ 0 ];
120 aArrayTemp
[i
] <<= aTmp
;
122 else if ( aType
.equals( getCppuType( (uno::Sequence
<uno::Any
>*)0 ) ) )
124 uno::Sequence
< uno::Sequence
<uno::Any
> > aTmp(1);
125 aArray
[ i
] >>= aTmp
[ 0 ];
126 aArrayTemp
[i
] <<= aTmp
;
131 for ( int count
=0; count
< aParamTemp
.getLength(); ++count
)
132 OSL_TRACE("Param[%d] is %s",
133 count
, rtl::OUStringToOString( comphelper::anyToString( aParamTemp
[count
] ), RTL_TEXTENCODING_UTF8
).getStr() );
135 uno::Any aRet
= xFunctionAccess
->callFunction(FunctionName
,aParamTemp
);
137 // MATCH function should alwayse return a double value, but currently if the first argument is XCellRange, MATCH function returns an array instead of a double value. Don't know why?
138 // To fix this issue in safe, current solution is to convert this array to a double value just for MATCH function.
139 String
aUpper( FunctionName
);
140 ScCompiler
aCompiler( NULL
, ScAddress() );
141 OpCode eOp
= aCompiler
.GetEnglishOpCode( aUpper
.ToUpperAscii() );
142 if( eOp
== ocMatch
|| eOp
== ocIsError
)
147 uno::Sequence
< uno::Sequence
< uno::Any
> > aSequence
;
148 if( !( ( aRet
>>= aSequence
) && ( aSequence
.getLength() > 0 ) &&
149 ( aSequence
[0].getLength() > 0 ) && ( aSequence
[0][0] >>= fVal
) ) )
150 throw uno::RuntimeException();
157 ScVbaWSFunction::setValue(const rtl::OUString
& /*PropertyName*/, const uno::Any
& /*Value*/) throw(beans::UnknownPropertyException
, script::CannotConvertException
, reflection::InvocationTargetException
, uno::RuntimeException
)
159 throw beans::UnknownPropertyException();
163 ScVbaWSFunction::getValue(const rtl::OUString
& /*PropertyName*/) throw(beans::UnknownPropertyException
, uno::RuntimeException
)
165 throw beans::UnknownPropertyException();
169 ScVbaWSFunction::hasMethod(const rtl::OUString
& Name
) throw(uno::RuntimeException
)
171 sal_Bool bIsFound
= sal_False
;
174 // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized.
175 // but the function name used in WorksheetFunction is a programmatic name (seems English).
176 // So m_xNameAccess->hasByName( Name ) may fail to find name when a function name has a localized name.
177 ScCompiler
aCompiler( NULL
, ScAddress() );
178 if( aCompiler
.IsEnglishSymbol( Name
) )
181 catch( uno::Exception
& /*e*/ )
183 // failed to find name
189 ScVbaWSFunction::hasProperty(const rtl::OUString
& /*Name*/) throw(uno::RuntimeException
)
194 ::rtl::OUString SAL_CALL
195 ScVbaWSFunction::getExactName( const ::rtl::OUString
& aApproximateName
) throw (css::uno::RuntimeException
)
197 rtl::OUString sName
= aApproximateName
.toAsciiUpperCase();
198 if ( !hasMethod( sName
) )
199 return rtl::OUString();
204 ScVbaWSFunction::getServiceImplName()
206 static rtl::OUString
sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWSFunction") );
210 uno::Sequence
< rtl::OUString
>
211 ScVbaWSFunction::getServiceNames()
213 static uno::Sequence
< rtl::OUString
> aServiceNames
;
214 if ( aServiceNames
.getLength() == 0 )
216 aServiceNames
.realloc( 1 );
217 aServiceNames
[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.WorksheetFunction" ) );
219 return aServiceNames
;