Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix enum loading bug #364

Merged
merged 2 commits into from
Sep 29, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions Excel_UI/Addin/AddIn_Formulas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
using BH.UI.Excel.Components;
using BH.oM.Versioning;

using BH.Engine.Serialiser;

namespace BH.UI.Excel
{
public partial class AddIn : IExcelAddIn
Expand Down Expand Up @@ -134,6 +136,8 @@ public static void RestoreFormulas()
if (choice is IObject)
IAddObject(choice);
}

UpdateEnumValues(valueList.MultiChoiceCaller.SelectedItem.ToJson());
}
}
}
Expand All @@ -143,6 +147,93 @@ public static void RestoreFormulas()
/**** Private Methods ****/
/*******************************************/

private static void UpdateEnumValues(string collectionName)
{
//Update enum values in case they have changed since the last serialisation
var enumType = BH.Engine.Serialiser.Convert.FromJson(collectionName) as Type; //To strip out the 'BHoM_Version'
if (!enumType.IsEnum)
return; //This method is only for enum dropdowns, not datasets, etc.

var nameOfEnum = enumType.Namespace + "." + enumType.Name;
var enumChoices = System.Enum.GetValues(enumType);

// Get the data sheet
Worksheet choicesSheet = AddIn.Sheet("BHoM_ChoicesHidden", true, true);
if (choicesSheet == null)
return;

// Try to find the list of choices in the spreadsheet
int i = 0;
while (i++ < 1000) // Just for safety
{
try
{
string name = choicesSheet.Cells[i, 1].Value as string;
if (string.IsNullOrEmpty(name))
{
// Need to add the choices here - this should not be needed on loading a sheet, but as a safety net
choicesSheet.Cells[i, 1].Value = collectionName;
for (int j = 0; j < enumChoices.Length; j++)
choicesSheet.Cells[i, j + 2].Value = enumChoices.GetValue(j).ToString();
break;
}
else
{
var sheetEnumName = BH.Engine.Serialiser.Convert.FromJson(name) as Type;
var sheetNameObject = sheetEnumName.Namespace + "." + sheetEnumName.Name;
if (sheetNameObject == nameOfEnum)
break;
}
}
catch
{
break;
}
}

// Obtain the range
Range range = choicesSheet.Range[choicesSheet.Cells[i, 2], choicesSheet.Cells[i, enumChoices.Length + 1]];

//Update the enum values - this is in case an enum value that previously existed has been renamed, so not just checking for null elements
for(int x = 0; x < enumChoices.Length; x++)
range[1, (x + 1)] = enumChoices.GetValue(x).ToString();

var rangeValidationFormula = $"=BHoM_ChoicesHidden!{range.Address}";
var rangeStart = $"=BHoM_ChoicesHidden!$B${i}:";

//Update all existing validation items to use the new range
Workbook workbook = ActiveWorkbook();
if (workbook != null)
{
foreach (Worksheet sheet in workbook.Sheets.OfType<Worksheet>().Where(x => x.Visible == XlSheetVisibility.xlSheetVisible))
{
foreach(Range cell in sheet.UsedRange)
{
Validation validation = cell.Validation;
if(validation != null)
{
try
{
string f1 = validation.Formula1;
string f2 = validation.Formula2;
if(f1.StartsWith(rangeStart) || f2.StartsWith(rangeStart))
{
validation.Delete();
validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertWarning, XlFormatConditionOperator.xlBetween, rangeValidationFormula, Type.Missing);
validation.InCellDropdown = true;
validation.IgnoreBlank = true;
}
}
catch
{
//If the validation isn't null, but a property is, that indicates the cell did not have validation in the first place, so no need to do anything with the catch, just ignore the cell
}
}
}
}
}
}

private static void SaveCallerToHiddenSheet(CallerFormula caller)
{
// Get the hidden worksheet
Expand Down