Skip to content

Commit

Permalink
Improved support for Formulas in Excel Cells.
Browse files Browse the repository at this point in the history
  • Loading branch information
andyward committed Feb 23, 2024
1 parent a566e29 commit d4d7eec
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 3 deletions.
28 changes: 28 additions & 0 deletions Tests/TableStorageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,34 @@ public void CanLoadModelConsecutively()
}
}

[TestMethod]
[DeploymentItem("TestFiles/FunctionsCobie.xlsx")]
public void CanLoadModelWithFunctions()
{
// Test when cells use Excel functions rather than primitive/literal values

ModelMapping mapping = GetCobieMapping();
//mapping.ClassMappings.RemoveAll(m => m.Class != "Type" && m.Class != "Contact");
var cobieModel = CobieModel.ImportFromTable(@"FunctionsCobie.xlsx", out var report, mapping);


var typeRow = cobieModel.Instances.OfType<CobieType>().Single();
Assert.IsTrue(string.IsNullOrWhiteSpace(report), "Errors loading cobie xlsx file: \r\n" + report);

Assert.AreEqual("JEG_CommunicationDevices_PublicAddressSpeakerCeilingRecessed_10899659", typeRow.Name);
Assert.AreEqual("andy.ward@xbim.net", typeRow.Created.CreatedBy.Email);
Assert.AreEqual("2019-09-04T17:20:40", typeRow.Created.CreatedOn.Value);

Assert.AreEqual("Pr_60_75 : Communications source products", typeRow.Categories.FirstOrDefault()?.Value);
Assert.AreEqual(24, typeRow.WarrantyDurationParts);
Assert.AreEqual(42.5, typeRow.ReplacementCost);
Assert.AreEqual(20, typeRow.ExpectedLife);
Assert.AreEqual(50, typeRow.NominalWidth);
Assert.AreEqual("Years", typeRow.DurationUnit.Value);


}

private static ModelMapping GetCobieMapping()
{
return CobieModel.GetMapping();
Expand Down
Binary file added Tests/TestFiles/FunctionsCobie.xlsx
Binary file not shown.
3 changes: 3 additions & 0 deletions Tests/Xbim.CobieExpress.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<None Update="TestFiles\2016-02-29-Dormitory-COBie.xlsx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TestFiles\FunctionsCobie.xlsx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="TestFiles\LakesideRestaurant.cobieZip">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
4 changes: 3 additions & 1 deletion Xbim.IO.Table/ReferenceContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,9 @@ public void LoadData(IRow row, bool skipReferences)
//if there is any enumeration on the path this needs to be treated as a list of values
if (HasEnumerationOnPath)
{
if (cell == null || cell.CellType != CellType.String || string.Equals(cell.StringCellValue, Mapping.DefaultValue, StringComparison.OrdinalIgnoreCase))
if (cell == null ||
(cell.CellType != CellType.String && cell.CellType != CellType.Formula) ||
string.Equals(cell.StringCellValue, Mapping.DefaultValue, StringComparison.OrdinalIgnoreCase))
return;

var strValue = cell.StringCellValue;
Expand Down
16 changes: 14 additions & 2 deletions Xbim.IO.Table/TableRestore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ internal object CreateSimpleValue(Type type, ICell cell)
case CellType.Numeric:
value = cell.NumericCellValue.ToString(CultureInfo.InvariantCulture);
break;
case CellType.Formula:
case CellType.String:
value = cell.StringCellValue;
break;
Expand All @@ -962,8 +963,11 @@ internal object CreateSimpleValue(Type type, ICell cell)
break;
case CellType.String:
if (!DateTime.TryParse(cell.StringCellValue, null, DateTimeStyles.RoundtripKind, out date))
{
Log.WriteLine("There is no suitable value for {0} in cell {1}{2}, sheet {3}. Unable to parse '{4}'", propType.Name, CellReference.ConvertNumToColString(cell.ColumnIndex), cell.RowIndex + 1, cell.Sheet.SheetName, cell.StringCellValue);
//set to default value according to specification
date = DateTime.Parse("1900-12-31T23:59:59", null, DateTimeStyles.RoundtripKind);
}
break;
default:
Log.WriteLine("There is no suitable value for {0} in cell {1}{2}, sheet {3}", propType.Name, CellReference.ConvertNumToColString(cell.ColumnIndex), cell.RowIndex + 1, cell.Sheet.SheetName);
Expand All @@ -976,16 +980,24 @@ internal object CreateSimpleValue(Type type, ICell cell)
{
switch (cell.CellType)
{
case CellType.Formula:
case CellType.Numeric:
return isExpress
? Activator.CreateInstance(propType, cell.NumericCellValue)
: cell.NumericCellValue;
case CellType.String:
double d;
if (double.TryParse(cell.StringCellValue, out d))
{
return isExpress
? Activator.CreateInstance(propType, d)
: d;
? Activator.CreateInstance(propType, d)
: d;
}
else
{
Log.WriteLine("There is no suitable value for {0} in cell {1}{2}, sheet {3}. Unable to parse '{4}'", propType.Name, CellReference.ConvertNumToColString(cell.ColumnIndex), cell.RowIndex + 1, cell.Sheet.SheetName, cell.StringCellValue);
}

break;
default:
Log.WriteLine("There is no suitable value for {0} in cell {1}{2}, sheet {3}", propType.Name, CellReference.ConvertNumToColString(cell.ColumnIndex), cell.RowIndex + 1, cell.Sheet.SheetName);
Expand Down

0 comments on commit d4d7eec

Please sign in to comment.