When running procedures that use Excel, I typically turn some application settings off at the start of the procedure, and then turn them on again at the end of the procedure.
Code for turning application settings off and on:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XLTimeTracker
{
class API
{
public static void TurnAppSettingsOff()
{
AddinModule.CurrentInstance.ExcelApp.EnableEvents = false;
AddinModule.CurrentInstance.ExcelApp.ScreenUpdating = false;
}
public static void TurnAppSettingsOn()
{
if (AddinModule.CurrentInstance.ExcelApp == null) return;
AddinModule.CurrentInstance.ExcelApp.EnableEvents = true;
AddinModule.CurrentInstance.ExcelApp.ScreenUpdating = true;
}
}
}
I call this procedures in the following manner:
API.TurnAppSettingsOff();
// my code
API.TurnAppSettingsOn();
This works well.
But say that I only want to turn on the app settings that were on before I ran API.TurnAppSettingsOff()
. What would be a good way to code this?
Some thoughts:
Boolean screenUpdating = AddinModule.CurrentInstance.ExcelApp.ScreenUpdating;
I would like the end result to be correct even if a function that turns appsettings off and on also calls another function that turns app settings off and on.
I don't know if it is best to set all settings using one command such as API.TurnAppSettingsOff()
or if it would be wiser to user API.TurnScreenUpdatingOff()
and API.TurnEventsOff()
.
I'd just whip up an internal manager class that handles the whole thing similar to the following:
public sealed class ApplicationSettingsManager
{
readonly object app;
readonly Dictionary<string, object> appSettings;
public ApplicationSettingsManager(object app)
{
this.app = app;
appSettings = new Dictionary<string, object>();
}
public object Application { get { return app; } }
public void SaveSetting(string settingName)
{
var propInfo = app.GetType().GetProperty(settingName);
if (propInfo == null)
throw new ArgumentException("Specified name is not a valid storable setting.", "setting");
var value = propInfo.GetValue(app);
if (appSettings.ContainsKey(settingName))
{
appSettings[settingName] = value;
}
else
{
appSettings.Add(settingName, value);
}
}
public void SaveAllSettings()
{
var properties = app.GetType().GetProperties().Where(p => p.CanWrite &&
p.CanRead &&
p.SetMethod.IsPublic &&
p.GetMethod.IsPublic);
foreach (var p in properties)
{
var value = p.GetValue(app);
if (appSettings.ContainsKey(p.Name))
{
appSettings[p.Name] = value;
}
else
{
appSettings.Add(p.Name, value);
}
}
}
public void RestoreSetting(string settingName)
{
if (!appSettings.ContainsKey(settingName))
throw new ArgumentException("Specified name does not correspond to a valid stored setting.", "settingName");
var propInfo = app.GetType().GetProperty(settingName);
propInfo.SetValue(app, appSettings[settingName]);
}
public void RestoreAllSettingas()
{
foreach (var p in appSettings)
{
RestoreSetting(p.Key);
}
}
}
That should do the trick. You would use it as follows;
var excelSettingsManager = new ApplicationSettingsManager(AddinModule.CurrentInstance.ExcelApp);
//store all settings you are going to tamper with...
excelSettingsManager.SaveSetting("EnableEvents");
excelSettingsManager.SaveSetting("ScreenUpdating");
//change excel setting and do your thing...
//...
//when done, restore settings
excelSettingsManager.RestoreAllSettings();
And you are done!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With