Как выполнить итерацию коллекции столбцов Excel в C++ с помощью автоматизации?
Я хочу сделать моральный эквивалент следующего кода VBA:
For Each col In Worksheets("Sheet1").Columns
# do stuff
Next col
Я сгенерировал оболочки MFC для библиотеки типов Excel, которые дошли до меня (все сгенерированные типы являются производными от COleDispatchDriver
:
CApplication app;
app.CreateDispatch( clsid, e );
CWorkbooks wbks( app.get_Workbooks() );
CWorkbook book( wbks.Open( filename, /* optional args */ ) );
CRange cols( app.get_Columns() );
long numCols = cols.get_Count();
и оттуда я застрял. Похоже, я могу как бы перебирать ячейки, используя Range::get_Item( rowid, colid )
, а затем получать столбец из ячейки, но я искал более прямой перевод вышеупомянутого цикла.
(РЕДАКТИРОВАТЬ) Уточнение: на самом деле я не забочусь об отдельных ячейках. Моя цель - определить, какие столбцы имеют ширину 0 (скрыты) и удалить их с рабочего листа.
Ответов (2)2
Я предполагаю, что вы пытаетесь пройти по всем ячейкам в электронной таблице. Вы можете получить диапазон "всех ячеек" активного рабочего листа и просмотреть его строки и столбцы в цикле:
CSheets sheets = book.get_WorkSheets();
CWorkSheet sheet = sheets.get_ActiveSheet();
Range cells = sheet.get_Cells();
int nRows = cells.get_Rows().get_Count();
int nCols = cells.get_Columns().get_Count();
for (int i = 0; i <= nRows; i++)
{
for (int j = 0; j <= nCols; j++)
{
Range cell = cells.get_Item(i+1,j+1);
//Do stuff with individual cell
}
}
РЕДАКТИРОВАТЬ: В ответ на разъяснение OP:
Это, вероятно, сделает то, что вы ищете:
CSheets sheets = book.get_WorkSheets();
CWorkSheet sheet = sheets.get_ActiveSheet();
Range cols= sheet.get_Columns();
int nCols = cols.get_Count();
for (int i = nCols; i > 0; i--)
{
Range topCellOfCol = cells.get_Item(1, i);
Range entireCol = topCellOfCol.get_EntireColumn();
if (entireCol.get_Hidden())
entireCol.Delete( xlShiftToLeft );
}
Благодаря Стиву я добился большей части пути. Оказывается, несмотря на документацию Excel VBA, Range :: Item ведет себя по-разному в зависимости от того, как создается диапазон; таким образом:
COleVariant OPTIONAL( (long)DISP_E_PARAMNOTFOUND, VT_ERROR );
Range cols = sheet.get_Columns();
for ( long i = cols.get_Count(); i > 0; --i )
{
Range col = cols.get_Item( COleVariant( i ), OPTIONAL ) ;
// ...
}
будет перебирать диапазоны, представляющие столбцы, и
Range rows = sheet.get_Rows();
for ( long i = rows.get_Count(); i > 0; --i )
{
Range row = cols.get_Item( COleVariant( i ), OPTIONAL );
// ...
}
будет перебирать диапазоны, представляющие строки. Это подразумевается в примерах VBA, но фактически не указано в документации.