This is related to Calc Sheet Unique identifier?
I have been testing User defined attributes for Calc Cells.
At first setting the attributes for a cell seemed to work fine.
When the spreadsheet user defined attributes are set after the cell user defined attributes the cell user defined attributes get wiped.
Sorry for the long post but I want to communicate the issue clearly.
In these python examples I am using OOO Development Tools but the setting of the UDA (user defined attributes) is essentially all straight API calls.
Am I missing something here?
Example set cell UDA only
Python
from __future__ import annotations
from typing import cast, TYPE_CHECKING
from pathlib import Path
import uno
from com.sun.star.xml import AttributeData
from ooodev.loader import Lo
from ooodev.calc import CalcDoc
if TYPE_CHECKING:
from com.sun.star.xml import AttributeContainer
def main():
with Lo.Loader(connector=Lo.ConnectSocket()):
doc = CalcDoc.create_doc(visible=True)
sheet = doc.sheets[0]
cell = sheet[0, 0]
assert cell is not None
cell.value = "Hello World!"
container = cast("AttributeContainer", cell.component.UserDefinedAttributes)
if container.hasByName("attr1"):
container.removeByName("attr1")
ad = AttributeData() # onnly CDATA which is the default for Type seems to work
ad.Value = "25"
container.insertByName("attr1", ad)
cell.component.UserDefinedAttributes = container
obj = cast(AttributeData, container.getByName("attr1"))
assert obj.Value == "25"
fnm = Path().cwd() / "tmp" / "uda.ods"
doc.save_doc(fnm)
doc.close()
if __name__ == "__main__":
main()
XML
From saved document internal content.xml
<!-- other xml -->
<office:automatic-styles>
<!-- other xml -->
<style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default">
<style:table-cell-properties attr1="25"/>
</style:style>
</office:automatic-styles>
<!-- other xml -->
<table:table table:name="Sheet1" table:style-name="ta1">
<table:table-column table:style-name="co1" table:default-cell-style-name="ce1"/>
<table:table-row table:style-name="ro1">
<table:table-cell office:value-type="string" calcext:value-type="string">
<text:p>Hello World!</text:p>
</table:table-cell>
</table:table-row>
</table:table>
Example set Sheet UDA First (working)
Python
from __future__ import annotations
from typing import cast, TYPE_CHECKING
from pathlib import Path
import uno
from com.sun.star.xml import AttributeData
from ooodev.loader import Lo
from ooodev.calc import CalcDoc
if TYPE_CHECKING:
from com.sun.star.xml import AttributeContainer
def main():
with Lo.Loader(connector=Lo.ConnectSocket()):
doc = CalcDoc.create_doc(visible=True)
sheet = doc.sheets[0]
sheet_uda = sheet.component.UserDefinedAttributes
if sheet_uda.hasByName("sheet_attr"):
sheet_uda.removeByName("sheet_attr")
ad = AttributeData()
ad.Value = "Sheet Attribute"
sheet_uda.insertByName("sheet_attr", ad)
sheet.component.UserDefinedAttributes = sheet_uda
obj = cast(AttributeData, sheet_uda.getByName("sheet_attr"))
assert obj is not None
assert obj.Value == "Sheet Attribute"
cell = sheet[0, 0]
assert cell is not None
cell.value = "Hello World!"
container = cast("AttributeContainer", cell.component.UserDefinedAttributes)
if container.hasByName("attr1"):
container.removeByName("attr1")
ad = AttributeData() # onnly CDATA which is the default for Type seems to work
ad.Value = "25"
container.insertByName("attr1", ad)
cell.component.UserDefinedAttributes = container
obj = cast(AttributeData, container.getByName("attr1"))
assert obj is not None
assert obj.Value == "25"
fnm = Path().cwd() / "tmp" / "uda.ods"
doc.save_doc(fnm)
doc.close()
return
if __name__ == "__main__":
main()
XML
It is interesting that the sheet UDA are assigned to each cell but still this is working.
content.xml
<!-- other xml -->
<office:automatic-styles>
<!-- other xml -->
<style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default">
<style:table-cell-properties sheet_attr="Sheet Attribute" attr1="25"/>
</style:style>
<style:style style:name="ce2" style:family="table-cell" style:parent-style-name="Default">
<style:table-cell-properties sheet_attr="Sheet Attribute"/>
</style:style>
</office:automatic-styles>
<!-- other xml -->
<table:table table:name="Sheet1" table:style-name="ta1">
<table:table-column table:style-name="co1" table:number-columns-repeated="16384" table:default-cell-style-name="ce2"/>
<table:table-row table:style-name="ro1">
<table:table-cell table:style-name="ce1" office:value-type="string" calcext:value-type="string">
<text:p>Hello World!</text:p>
</table:table-cell>
<table:table-cell table:number-columns-repeated="16383"/>
</table:table-row>
<table:table-row table:style-name="ro1" table:number-rows-repeated="1048574">
<table:table-cell table:number-columns-repeated="16384"/>
</table:table-row>
<table:table-row table:style-name="ro1">
<table:table-cell table:number-columns-repeated="16384"/>
</table:table-row>
Example NOT working, Assign sheet UDA after Cell UDA
Assign UDA for 2 cells, assign sheet UDA, assign UDA to third cell and save document.
The result is only the third cell keeps it UDA. The first two cells get UDA wiped.
Python
from __future__ import annotations
from typing import cast, TYPE_CHECKING
from pathlib import Path
import uno
from com.sun.star.xml import AttributeData
from ooodev.loader import Lo
from ooodev.calc import CalcDoc
if TYPE_CHECKING:
from com.sun.star.xml import AttributeContainer
def main():
with Lo.Loader(connector=Lo.ConnectSocket()):
doc = CalcDoc.create_doc(visible=True)
sheet = doc.sheets[0]
cell = sheet[0, 0]
assert cell is not None
cell.value = "Hello World!"
container = cast("AttributeContainer", cell.component.UserDefinedAttributes)
if container.hasByName("attr1"):
container.removeByName("attr1")
ad = AttributeData() # onnly CDATA which is the default for Type seems to work
ad.Value = "25"
container.insertByName("attr1", ad)
cell.component.UserDefinedAttributes = container
obj = cast(AttributeData, container.getByName("attr1"))
assert obj is not None
assert obj.Value == "25"
cell = sheet[2, 2]
cell.value = "Nice Day!"
container = cast("AttributeContainer", cell.component.UserDefinedAttributes)
if container.hasByName("attr2"):
container.removeByName("attr2")
ad = AttributeData()
ad.Value = "This is It"
container.insertByName("attr2", ad)
cell.component.UserDefinedAttributes = container
obj = cast(AttributeData, container.getByName("attr2"))
assert obj is not None
assert obj.Value == "This is It"
sheet_uda = sheet.component.UserDefinedAttributes
if sheet_uda.hasByName("sheet_attr"):
sheet_uda.removeByName("sheet_attr")
ad = AttributeData()
ad.Value = "Sheet Attribute"
sheet_uda.insertByName("sheet_attr", ad)
sheet.component.UserDefinedAttributes = sheet_uda
obj = cast(AttributeData, sheet_uda.getByName("sheet_attr"))
assert obj is not None
assert obj.Value == "Sheet Attribute"
cell = sheet[4, 4]
cell.value = "Last Chance!"
container = cast("AttributeContainer", cell.component.UserDefinedAttributes)
if container.hasByName("attr3"):
container.removeByName("attr3")
ad = AttributeData()
ad.Value = "This should stick"
container.insertByName("attr3", ad)
cell.component.UserDefinedAttributes = container
obj = cast(AttributeData, container.getByName("attr3"))
assert obj is not None
assert obj.Value == "This should stick"
fnm = Path().cwd() / "tmp" / "uda.ods"
doc.save_doc(fnm)
doc.close()
if __name__ == "__main__":
main()
XML
The UDA for the first two cell (“A1”, “C3” ) have no UDA when the document is saved but the last cell (“E5”) has UDA value. The value is contained in ce2
of the styles section.
<!-- other xml -->
<office:automatic-styles>
<!-- other xml -->
<style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default">
<style:table-cell-properties sheet_attr="Sheet Attribute"/>
</style:style>
<style:style style:name="ce2" style:family="table-cell" style:parent-style-name="Default">
<style:table-cell-properties sheet_attr="Sheet Attribute" attr3="This should stick"/>
</style:style>
</office:automatic-styles>
<table:table table:name="Sheet1" table:style-name="ta1">
<table:table-column table:style-name="co1" table:number-columns-repeated="16384" table:default-cell-style-name="ce1"/>
<table:table-row table:style-name="ro1">
<table:table-cell office:value-type="string" calcext:value-type="string">
<text:p>Hello World!</text:p>
</table:table-cell>
<table:table-cell table:number-columns-repeated="16383"/>
</table:table-row>
<table:table-row table:style-name="ro1">
<table:table-cell table:number-columns-repeated="16384"/>
</table:table-row>
<table:table-row table:style-name="ro1">
<table:table-cell table:number-columns-repeated="2"/>
<table:table-cell office:value-type="string" calcext:value-type="string">
<text:p>Nice Day!</text:p>
</table:table-cell>
<table:table-cell table:number-columns-repeated="16381"/>
</table:table-row>
<table:table-row table:style-name="ro1">
<table:table-cell table:number-columns-repeated="16384"/>
</table:table-row>
<table:table-row table:style-name="ro1">
<table:table-cell table:number-columns-repeated="4"/>
<table:table-cell table:style-name="ce2" office:value-type="string" calcext:value-type="string">
<text:p>Last Chance!</text:p>
</table:table-cell>
<table:table-cell table:number-columns-repeated="16379"/>
</table:table-row>
<table:table-row table:style-name="ro1" table:number-rows-repeated="1048570">
<table:table-cell table:number-columns-repeated="16384"/>
</table:table-row>
<table:table-row table:style-name="ro1">
<table:table-cell table:number-columns-repeated="16384"/>
</table:table-row>
</table:table>