Hi Kristof,
If you need to write to a large, contiguous block of cells, COM will let you do this with one write operation (just select the Range and assign an object[,]) to it's Value2 property.
Also, remember to disable the calculation stuff before you write back. Otherwise, Excel will recalculate the sheet before letting you write more values. Here is an IDisposable class which let's you wrap that disable stuff in a using statement.
//
http://pyxr.sourceforge.net/PyXR/c/python24/lib/site-packages/win32/lib/winerror.py.html public static class ExcelCOMErrorCodes {
public const uint RPC_E_CANTCALLOUT_INASYNCCALL=0x800AC472;
}
public class DisableAutoCalc : IDisposable {
private readonly _Application app;
private readonly XlCalculation? calc;
private readonly bool? screenUpdates;
public DisableAutoCalc(_Application app) {
this.app=app;
this.calc=app.Calculation;
this.screenUpdates=app.ScreenUpdating;
MultipleRetry<XlCalculation?>(() => app.Calculation=XlCalculation.xlCalculationManual, null);
MultipleRetry<bool?>(() => app.ScreenUpdating=false, null);
}
protected void Dispose(bool disposing) {
if(disposing && (app!=null)) {
if(calc.HasValue) {
app.Calculation=calc.Value;
}
if(screenUpdates.HasValue) {
app.ScreenUpdating=screenUpdates.Value;
}
}
}
public void Dispose() {
Dispose(true);
}
public void Close() {
Dispose(true);
}
~DisableAutoCalc() {
Dispose(false);
}
private const int MaxNumComRetries=8;
public static T MultipleRetry<T>(Func<T> func, T onError) {
for(var i=0; i<MaxNumComRetries; i++) {
try {
return func();
// the action succeeded--return
} catch(COMException c) {
if(c.ErrorCode!=ExcelCOMErrorCodes.RPC_E_CANTCALLOUT_INASYNCCALL) {
throw;
}
}
}
return onError;
}
}