#c# #excel #worksheet-function
#c# #excel #worksheet-функция
Вопрос:
Я работал над надстройкой Excel.
Это конструктор для добавления:
public AddinModule()
{
Application.EnableVisualStyles();
InitializeComponent();
AddinFinalize = new ADXEvents_EventHandler(FinalizeAddIn);
AddinInitialize = new ADXEvents_EventHandler(InitializeAddIn);
OnError = new ADXError_EventHandler(OnErrorAddIn);
EventDel_CellsChange = new Excel.DocEvents_ChangeEventHandler(CellsChange);
}
Существует кнопка, которая, помимо прочего, создает новый рабочий лист, и после его создания на рабочий лист добавляется метод CellsChange.Измените событие следующим образом:
//some code
CreateWorkSheet();
sheet = ExcelApp.ActiveSheet as Excel.Worksheet;
sheet.Change = EventDel_CellsChange;
//some code
Значения столбца А загружаются при создании рабочего листа. Это работает, как и ожидалось. Значения столбцов от B до E зависят от значения, выбранного в предыдущем столбце. Проблема, с которой я столкнулся, заключается в том, что изменение в любом из этих столбцов не всегда вызывает событие. Я, очевидно, отладил надстройку, добавив точки останова в метод cellschange, но результат тот же: иногда он прерывается в точке останова, а иногда нет. Когда он останавливается, все работает просто отлично. Как только событие не будет запущено, оно больше не будет работать, если только рабочий лист не будет удален и добавлен нажатием ранее упомянутой кнопки. Я что-то упускаю из виду?
Наконец, метод cellsChange:
private void CellsChange(Excel.Range Target)
{
Excel.Worksheet sheet = null;
Excel.Range rng = null;
Excel.Range columns = null;
Excel.Range column = null;
try
{
foreach (Excel.Range c in Target.Cells)
{
if (c.Row != 1 amp;amp; c.Column < (int)Columnas.Column6 amp;amp; c.Value2 != null)
{
sheet = CurrentInstance.ExcelApp.ActiveSheet as Excel.Worksheet;
string[] values = null;
string AValue;
string BValue;
switch (c.Column)
{
case (int)Columnas.A:
values = GetBValues(c.Value2.ToString());
rng = sheet.Cells[c.Row, (int)Columnas.B] as Excel.Range;
break;
case (int)Columnas.B:
AValue = (string)(sheet.Cells[c.Row, (int)Columnas.A] as Excel.Range).Value;
values = GetCValues(AValue, c.Value2.ToString());
rng = sheet.Cells[c.Row, (int)Columnas.C] as Excel.Range;
break;
case (int)Columnas.C:
AValue = (string)(sheet.Cells[c.Row, (int)Columnas.A] as Excel.Range).Value;
BValue = (string)(sheet.Cells[c.Row, (int)Columnas.B] as Excel.Range).Value;
values = GetDValues(AValue, BValue, c.Value2.ToString());
rng = sheet.Cells[c.Row, (int)Columnas.D] as Excel.Range;
break;
case (int)Columnas.D:
if (c.Value2.ToString() == FUTURE)
{
AValue = (string)(sheet.Cells[c.Row, (int)Columnas.A] as Excel.Range).Value;
BValue = (string)(sheet.Cells[c.Row, (int)Columnas.B] as Excel.Range).Value;
string moneda = (string)(sheet.Cells[c.Row, (int)Columnas.C] as Excel.Range).Value;
values = GetEValues(AValue, BValue, moneda, c.Value2.ToString());
rng = sheet.Cells[c.Row, (int)Columnas.E] as Excel.Range;
}
break;
default:
break;
}
if (values != null)
{
sheet.Unprotect(Type.Missing);
columns = rng.Columns;
column = columns[1] as Excel.Range;
column.Validation.Delete();
SetRangeFormat(column, FormatType.Text);
column.Validation.Add(Excel.XlDVType.xlValidateList, Excel.XlDVAlertStyle.xlValidAlertInformation,
Type.Missing, string.Join(Separator, values), Type.Missing);
column.Validation.InCellDropdown = true;
column.Locked = false;
sheet.Protect(Type.Missing, false, true, false, false, true, true, true, false, false, true, false, false, true, true, true);
}
}
}
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
finally
{
if (sheet != null)
{
Marshal.ReleaseComObject(sheet);
}
if (columns != null) Marshal.ReleaseComObject(columns);
if (rng != null) Marshal.ReleaseComObject(rng);
if (column != null)
{
Marshal.ReleaseComObject(column);
}
}
}
Комментарии:
1. Мне интересно, есть ли что-нибудь
Application.EnableEvents = False
в остальной части вашего кода2. Есть ли у вас доступ, например, к коду «OnErrorAddIn»?
3. @anefeletos, нет, их там нет
Application.EnableEvents = false
.