fix various problems with vba Names & Names objects
a) Name.Value attribute was read only b) Name.[Get|Set]Value not working property c) Name.ReferToR1C1xxx attributes not returning r1c1 related addresses d) Names.Add just not working( should return a reference to the new Name ) e) Names.Add not handling multi-area addresses, not constructing the Content for the names correctly Change-Id: I6f3c1cf029d5e4003c5900a4e9525f5a0d9a8ed6
This commit is contained in:
parent
3c2d0acc87
commit
566f52506e
@ -36,7 +36,7 @@ interface XName
|
|||||||
[attribute] string Name;
|
[attribute] string Name;
|
||||||
[attribute] string NameLocal;
|
[attribute] string NameLocal;
|
||||||
[attribute] boolean Visible;
|
[attribute] boolean Visible;
|
||||||
[attribute, readonly] string Value;
|
[attribute] string Value;
|
||||||
[attribute, readonly] string RefersTo;
|
[attribute, readonly] string RefersTo;
|
||||||
[attribute, readonly] string RefersToLocal;
|
[attribute, readonly] string RefersToLocal;
|
||||||
[attribute, readonly] string RefersToR1C1;
|
[attribute, readonly] string RefersToR1C1;
|
||||||
|
@ -48,7 +48,7 @@ class ScRangeData;
|
|||||||
class ScTokenArray;
|
class ScTokenArray;
|
||||||
class ScNamedRangesObj;
|
class ScNamedRangesObj;
|
||||||
|
|
||||||
class ScNamedRangeObj : public ::cppu::WeakImplHelper6<
|
class SC_DLLPUBLIC ScNamedRangeObj : public ::cppu::WeakImplHelper6<
|
||||||
::com::sun::star::sheet::XNamedRange,
|
::com::sun::star::sheet::XNamedRange,
|
||||||
::com::sun::star::sheet::XFormulaTokens,
|
::com::sun::star::sheet::XFormulaTokens,
|
||||||
::com::sun::star::sheet::XCellRangeReferrer,
|
::com::sun::star::sheet::XCellRangeReferrer,
|
||||||
@ -64,6 +64,7 @@ private:
|
|||||||
com::sun::star::uno::Reference< com::sun::star::container::XNamed > mxSheet;
|
com::sun::star::uno::Reference< com::sun::star::container::XNamed > mxSheet;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class ScVbaName;
|
||||||
ScRangeData* GetRangeData_Impl();
|
ScRangeData* GetRangeData_Impl();
|
||||||
void Modify_Impl( const String* pNewName,
|
void Modify_Impl( const String* pNewName,
|
||||||
const ScTokenArray* pNewTokens, const String* pNewContent,
|
const ScTokenArray* pNewTokens, const String* pNewContent,
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
#include <vcl/msgbox.hxx>
|
#include <vcl/msgbox.hxx>
|
||||||
#include "tabvwsh.hxx"
|
#include "tabvwsh.hxx"
|
||||||
#include "viewdata.hxx"
|
#include "viewdata.hxx"
|
||||||
|
#include "nameuno.hxx"
|
||||||
|
#include "compiler.hxx"
|
||||||
|
#include "tokenarray.hxx"
|
||||||
|
|
||||||
using namespace ::ooo::vba;
|
using namespace ::ooo::vba;
|
||||||
using namespace ::com::sun::star;
|
using namespace ::com::sun::star;
|
||||||
@ -92,81 +95,64 @@ ScVbaName::setVisible( sal_Bool /*bVisible*/ ) throw (css::uno::RuntimeException
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OUString ScVbaName::getContent( const formula::FormulaGrammar::Grammar eGrammar, bool bPrependEquals )
|
||||||
|
{
|
||||||
|
ScNamedRangeObj* pNamedRange = dynamic_cast< ScNamedRangeObj* >( mxNamedRange.get() );
|
||||||
|
OUString aContent;
|
||||||
|
if ( pNamedRange )
|
||||||
|
{
|
||||||
|
ScRangeData* pData = pNamedRange->GetRangeData_Impl();
|
||||||
|
if (pData)
|
||||||
|
pData->GetSymbol( aContent, eGrammar );
|
||||||
|
}
|
||||||
|
if ( bPrependEquals )
|
||||||
|
{
|
||||||
|
if (aContent.indexOf('=') != 0)
|
||||||
|
aContent = OUString::createFromAscii("=") + aContent;
|
||||||
|
}
|
||||||
|
return aContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScVbaName::setContent( const OUString& rContent, const formula::FormulaGrammar::Grammar eGrammar, bool bRemoveEquals )
|
||||||
|
{
|
||||||
|
OUString sContent( rContent );
|
||||||
|
if ( bRemoveEquals )
|
||||||
|
{
|
||||||
|
if (sContent.indexOf('=') == 0)
|
||||||
|
sContent = sContent.copy(1);
|
||||||
|
}
|
||||||
|
ScNamedRangeObj* pNamedRange = dynamic_cast< ScNamedRangeObj* >( mxNamedRange.get() );
|
||||||
|
|
||||||
|
// We should be able to do the below by just setting calling SetCode on pNamedRange
|
||||||
|
// right?
|
||||||
|
if ( pNamedRange && pNamedRange->pDocShell )
|
||||||
|
{
|
||||||
|
|
||||||
|
ScDocument* pDoc = pNamedRange->pDocShell->GetDocument();
|
||||||
|
ScRangeData* pOldData = pNamedRange->GetRangeData_Impl();
|
||||||
|
if (pOldData)
|
||||||
|
{
|
||||||
|
// Shorter way of doing this ?
|
||||||
|
ScCompiler aComp( pDoc, pOldData->GetPos() );
|
||||||
|
aComp.SetGrammar( eGrammar );
|
||||||
|
ScTokenArray aArray(*aComp.CompileString( sContent ) );
|
||||||
|
pOldData->SetCode( aArray );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OUString
|
OUString
|
||||||
ScVbaName::getValue() throw (css::uno::RuntimeException)
|
ScVbaName::getValue() throw (css::uno::RuntimeException)
|
||||||
{
|
{
|
||||||
OUString sValue = mxNamedRange->getContent();
|
rtl::OUString sResult = getContent( formula::FormulaGrammar::GRAM_NATIVE_XL_A1, true );
|
||||||
OUString sSheetName = getWorkSheet()->getName();
|
|
||||||
OUString sSegmentation = OUString::createFromAscii( ";" );
|
|
||||||
OUString sNewSegmentation = OUString::createFromAscii( "," );
|
|
||||||
OUString sResult;
|
|
||||||
sal_Int32 nFrom = 0;
|
|
||||||
sal_Int32 nTo = 0;
|
|
||||||
nTo = sValue.indexOf( sSegmentation, nFrom );
|
|
||||||
while ( nTo != -1 )
|
|
||||||
{
|
|
||||||
OUString sTmpValue = sValue.copy( nFrom, nTo - nFrom );
|
|
||||||
if ( sTmpValue.toChar() == '$' )
|
|
||||||
{
|
|
||||||
OUString sTmp = sTmpValue.copy( 1 );
|
|
||||||
sTmp = sTmp.replaceAt(0, OUString(sSheetName + OUString::createFromAscii(".")).getLength(), sSheetName + OUString::createFromAscii("!"));
|
|
||||||
sResult += sTmp;
|
|
||||||
sResult += sNewSegmentation;
|
|
||||||
}
|
|
||||||
nFrom = nTo + 1;
|
|
||||||
nTo = sValue.indexOf( sSegmentation, nFrom );
|
|
||||||
}
|
|
||||||
OUString sTmpValue = sValue.copy( nFrom );
|
|
||||||
if ( sTmpValue.toChar() == '$' )
|
|
||||||
{
|
|
||||||
OUString sTmp = sTmpValue.copy(1);
|
|
||||||
sTmp = sTmp.replaceAt(0, OUString(sSheetName + OUString::createFromAscii(".")).getLength(), sSheetName + OUString::createFromAscii("!"));
|
|
||||||
sResult += sTmp;
|
|
||||||
}
|
|
||||||
if (sResult.indexOf('=') != 0)
|
|
||||||
{
|
|
||||||
sResult = OUString::createFromAscii("=") + sResult;
|
|
||||||
}
|
|
||||||
return sResult;
|
return sResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ScVbaName::setValue( const OUString & rValue ) throw (css::uno::RuntimeException)
|
ScVbaName::setValue( const OUString & rValue ) throw (css::uno::RuntimeException)
|
||||||
{
|
{
|
||||||
OUString sSheetName = getWorkSheet()->getName();
|
setContent( rValue, formula::FormulaGrammar::GRAM_NATIVE_XL_A1, true );
|
||||||
OUString sValue = rValue;
|
|
||||||
OUString sSegmentation = OUString::createFromAscii( "," );
|
|
||||||
OUString sNewSegmentation = OUString::createFromAscii( ";" );
|
|
||||||
OUString sResult;
|
|
||||||
sal_Int32 nFrom = 0;
|
|
||||||
sal_Int32 nTo = 0;
|
|
||||||
if (sValue.indexOf('=') == 0)
|
|
||||||
{
|
|
||||||
OUString sTmp = sValue.copy(1);
|
|
||||||
sValue = sTmp;
|
|
||||||
}
|
|
||||||
nTo = sValue.indexOf( sSegmentation, nFrom );
|
|
||||||
while ( nTo != -1 )
|
|
||||||
{
|
|
||||||
OUString sTmpValue = sValue.copy( nFrom, nTo - nFrom );
|
|
||||||
sTmpValue = sTmpValue.replaceAt(0, OUString(sSheetName + OUString::createFromAscii("!")).getLength(), sSheetName + OUString::createFromAscii("."));
|
|
||||||
if (sTmpValue.copy(0, sSheetName.getLength()).equals(sSheetName))
|
|
||||||
{
|
|
||||||
sTmpValue = OUString::createFromAscii("$") + sTmpValue;
|
|
||||||
}
|
|
||||||
sTmpValue += sNewSegmentation;
|
|
||||||
sResult += sTmpValue;
|
|
||||||
nFrom = nTo + 1;
|
|
||||||
nTo = sValue.indexOf( sSegmentation, nFrom );
|
|
||||||
}
|
|
||||||
OUString sTmpValue = sValue.copy( nFrom );
|
|
||||||
sTmpValue = sTmpValue.replaceAt(0, OUString(sSheetName + OUString::createFromAscii("!")).getLength(), sSheetName + OUString::createFromAscii("."));
|
|
||||||
if (sTmpValue.copy(0, sSheetName.getLength()).equals(sSheetName))
|
|
||||||
{
|
|
||||||
sTmpValue = OUString::createFromAscii("$") + sTmpValue;
|
|
||||||
}
|
|
||||||
sResult += sTmpValue;
|
|
||||||
mxNamedRange->setContent(sResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OUString
|
OUString
|
||||||
@ -196,19 +182,20 @@ ScVbaName::setRefersToLocal( const OUString & rRefersTo ) throw (css::uno::Runti
|
|||||||
OUString
|
OUString
|
||||||
ScVbaName::getRefersToR1C1() throw (css::uno::RuntimeException)
|
ScVbaName::getRefersToR1C1() throw (css::uno::RuntimeException)
|
||||||
{
|
{
|
||||||
return getRefersTo();
|
rtl::OUString sResult = getContent( formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1, true );
|
||||||
|
return sResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ScVbaName::setRefersToR1C1( const OUString & rRefersTo ) throw (css::uno::RuntimeException)
|
ScVbaName::setRefersToR1C1( const OUString & rRefersTo ) throw (css::uno::RuntimeException)
|
||||||
{
|
{
|
||||||
setRefersTo( rRefersTo );
|
setContent( rRefersTo, formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
OUString
|
OUString
|
||||||
ScVbaName::getRefersToR1C1Local() throw (css::uno::RuntimeException)
|
ScVbaName::getRefersToR1C1Local() throw (css::uno::RuntimeException)
|
||||||
{
|
{
|
||||||
return getRefersTo();
|
return getRefersToR1C1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <com/sun/star/sheet/XNamedRanges.hpp>
|
#include <com/sun/star/sheet/XNamedRanges.hpp>
|
||||||
|
|
||||||
#include <vbahelper/vbahelperinterface.hxx>
|
#include <vbahelper/vbahelperinterface.hxx>
|
||||||
|
#include <formula/grammar.hxx>
|
||||||
class ScDocument;
|
class ScDocument;
|
||||||
|
|
||||||
typedef InheritedHelperInterfaceImpl1< ov::excel::XName > NameImpl_BASE;
|
typedef InheritedHelperInterfaceImpl1< ov::excel::XName > NameImpl_BASE;
|
||||||
@ -34,7 +34,8 @@ class ScVbaName : public NameImpl_BASE
|
|||||||
css::uno::Reference< css::frame::XModel > mxModel;
|
css::uno::Reference< css::frame::XModel > mxModel;
|
||||||
css::uno::Reference< css::sheet::XNamedRange > mxNamedRange;
|
css::uno::Reference< css::sheet::XNamedRange > mxNamedRange;
|
||||||
css::uno::Reference< css::sheet::XNamedRanges > mxNames;
|
css::uno::Reference< css::sheet::XNamedRanges > mxNames;
|
||||||
|
OUString getContent( const formula::FormulaGrammar::Grammar eGrammar, bool prependEquals = true );
|
||||||
|
void setContent( const OUString& sContent, const formula::FormulaGrammar::Grammar eGrammar, bool removeEquals = true );
|
||||||
protected:
|
protected:
|
||||||
virtual css::uno::Reference< css::frame::XModel > getModel() { return mxModel; }
|
virtual css::uno::Reference< css::frame::XModel > getModel() { return mxModel; }
|
||||||
virtual css::uno::Reference< ov::excel::XWorksheet > getWorkSheet() throw (css::uno::RuntimeException);
|
virtual css::uno::Reference< ov::excel::XWorksheet > getWorkSheet() throw (css::uno::RuntimeException);
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
#include <vcl/msgbox.hxx>
|
#include <vcl/msgbox.hxx>
|
||||||
#include "tabvwsh.hxx"
|
#include "tabvwsh.hxx"
|
||||||
#include "viewdata.hxx"
|
#include "viewdata.hxx"
|
||||||
|
#include "compiler.hxx"
|
||||||
|
#include "tokenarray.hxx"
|
||||||
|
#include "cellsuno.hxx"
|
||||||
|
|
||||||
using namespace ::ooo::vba;
|
using namespace ::ooo::vba;
|
||||||
using namespace ::com::sun::star;
|
using namespace ::com::sun::star;
|
||||||
@ -117,36 +120,109 @@ ScVbaNames::Add( const css::uno::Any& Name ,
|
|||||||
uno::Reference< uno::XInterface >() );
|
uno::Reference< uno::XInterface >() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uno::Reference< table::XCellRange > xUnoRange;
|
||||||
if ( RefersTo.hasValue() || RefersToR1C1.hasValue() || RefersToR1C1Local.hasValue() )
|
if ( RefersTo.hasValue() || RefersToR1C1.hasValue() || RefersToR1C1Local.hasValue() )
|
||||||
{
|
{
|
||||||
|
OUString sFormula;
|
||||||
|
|
||||||
|
formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_NATIVE_XL_A1;
|
||||||
if ( RefersTo.hasValue() )
|
if ( RefersTo.hasValue() )
|
||||||
RefersTo >>= xRange;
|
{
|
||||||
|
if ( RefersTo.getValueTypeClass() == uno::TypeClass_STRING )
|
||||||
|
RefersTo >>= sFormula;
|
||||||
|
else
|
||||||
|
RefersTo >>= xRange;
|
||||||
|
}
|
||||||
if ( RefersToR1C1.hasValue() )
|
if ( RefersToR1C1.hasValue() )
|
||||||
RefersToR1C1 >>= xRange;
|
{
|
||||||
|
if ( RefersToR1C1.getValueTypeClass() == uno::TypeClass_STRING )
|
||||||
|
{
|
||||||
|
RefersToR1C1 >>= sFormula;
|
||||||
|
eGram = formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
RefersToR1C1 >>= xRange;
|
||||||
|
}
|
||||||
if ( RefersToR1C1Local.hasValue() )
|
if ( RefersToR1C1Local.hasValue() )
|
||||||
RefersToR1C1Local >>= xRange;
|
{
|
||||||
|
if ( RefersToR1C1Local.getValueTypeClass() == uno::TypeClass_STRING )
|
||||||
|
{
|
||||||
|
RefersToR1C1Local >>= sFormula;
|
||||||
|
eGram = formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
RefersToR1C1Local >>= xRange;
|
||||||
|
}
|
||||||
|
if ( !xRange.is() && !sFormula.isEmpty() )
|
||||||
|
{
|
||||||
|
ScAddress aBlank;
|
||||||
|
ScCompiler aComp( getScDocument(), aBlank );
|
||||||
|
aComp.SetGrammar( eGram );
|
||||||
|
ScTokenArray* pTokens = aComp.CompileString( sFormula );
|
||||||
|
if ( pTokens )
|
||||||
|
{
|
||||||
|
ScRange aRange;
|
||||||
|
ScDocShell* pDocSh = excel::getDocShell(getModel());
|
||||||
|
if ( pTokens->IsValidReference( aRange ) )
|
||||||
|
xUnoRange = new ScCellRangeObj( pDocSh, aRange );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// assume it's an address try strip the '=' if it's there
|
||||||
|
// and try and create a range ( must be a better way )
|
||||||
|
if ( sFormula.startsWith("=") )
|
||||||
|
sFormula = sFormula.copy(1);
|
||||||
|
ScRangeList aCellRanges;
|
||||||
|
sal_uInt16 nFlags = 0;
|
||||||
|
|
||||||
|
formula::FormulaGrammar::AddressConvention eConv = ( eGram == formula::FormulaGrammar::GRAM_NATIVE_XL_A1 ) ? formula::FormulaGrammar::CONV_XL_A1 : formula::FormulaGrammar::CONV_XL_R1C1;
|
||||||
|
if ( ScVbaRange::getCellRangesForAddress( nFlags, sFormula, pDocSh, aCellRanges, eConv , ',' ) )
|
||||||
|
{
|
||||||
|
if ( aCellRanges.size() == 1 )
|
||||||
|
xUnoRange = new ScCellRangeObj( pDocSh, *aCellRanges.front() );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) );
|
||||||
|
xRange = new ScVbaRange( mxParent, mxContext, xRanges );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( xRange.is() )
|
if ( xRange.is() || xUnoRange.is() )
|
||||||
{
|
{
|
||||||
ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() );
|
if ( !xRange.is() )
|
||||||
uno::Reference< table::XCellRange > thisRange ;
|
xRange = new ScVbaRange( mxParent, mxContext, xUnoRange );
|
||||||
uno::Any xAny = pRange->getCellRange() ;
|
|
||||||
if ( xAny.hasValue() )
|
uno::Reference< excel::XRange > xArea( xRange->Areas( uno::makeAny( 1 ) ), uno::UNO_QUERY );
|
||||||
xAny >>= thisRange;
|
uno::Any xAny = xArea->getCellRange() ;
|
||||||
uno::Reference< sheet::XCellRangeAddressable > thisRangeAdd( thisRange, ::uno::UNO_QUERY_THROW);
|
|
||||||
|
uno::Reference< sheet::XCellRangeAddressable > thisRangeAdd( xAny, ::uno::UNO_QUERY_THROW);
|
||||||
|
|
||||||
table::CellRangeAddress aAddr = thisRangeAdd->getRangeAddress();
|
table::CellRangeAddress aAddr = thisRangeAdd->getRangeAddress();
|
||||||
ScAddress aPos( static_cast< SCCOL >( aAddr.StartColumn ) , static_cast< SCROW >( aAddr.StartRow ) , static_cast< SCTAB >(aAddr.Sheet ) );
|
ScAddress aPos( static_cast< SCCOL >( aAddr.StartColumn ) , static_cast< SCROW >( aAddr.StartRow ) , static_cast< SCTAB >(aAddr.Sheet ) );
|
||||||
uno::Any xAny2 ;
|
uno::Any xAny2 ;
|
||||||
String sRangeAdd = xRange->Address( xAny2, xAny2 , xAny2 , xAny2, xAny2 );
|
|
||||||
if ( mxNames.is() )
|
if ( mxNames.is() )
|
||||||
{
|
{
|
||||||
RangeType nType = RT_NAME;
|
RangeType nType = RT_NAME;
|
||||||
table::CellAddress aCellAddr( aAddr.Sheet , aAddr.StartColumn , aAddr.StartRow );
|
table::CellAddress aCellAddr( aAddr.Sheet , aAddr.StartColumn , aAddr.StartRow );
|
||||||
if ( mxNames->hasByName( sName ) )
|
if ( mxNames->hasByName( sName ) )
|
||||||
mxNames->removeByName(sName);
|
mxNames->removeByName(sName);
|
||||||
OUString sTmp = "$" + xRange->getWorksheet()->getName() + "." + sRangeAdd;
|
OUString sTmp = "$";
|
||||||
|
uno::Reference< ov::XCollection > xCol( xRange->Areas( uno::Any() ), uno::UNO_QUERY );
|
||||||
|
for ( sal_Int32 nArea = 1; nArea <= xCol->getCount(); ++nArea )
|
||||||
|
{
|
||||||
|
xArea.set( xRange->Areas( uno::makeAny( nArea ) ), uno::UNO_QUERY_THROW );
|
||||||
|
|
||||||
|
String sRangeAdd = xArea->Address( xAny2, xAny2 , xAny2 , xAny2, xAny2 );
|
||||||
|
if ( nArea > 1 )
|
||||||
|
sTmp += ",";
|
||||||
|
sTmp = sTmp + "'" + xRange->getWorksheet()->getName() + "'." + sRangeAdd;
|
||||||
|
}
|
||||||
mxNames->addNewByName( sName , sTmp , aCellAddr , (sal_Int32)nType);
|
mxNames->addNewByName( sName , sTmp , aCellAddr , (sal_Int32)nType);
|
||||||
|
return Item( uno::makeAny( sName ), uno::Any() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return css::uno::Any();
|
return css::uno::Any();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user