Поиск в коллекции листов Excel с C #

2

Я пытаюсь получить С#, чтобы изучить любую книгу, которую выбрал пользователь, и найти любые листы, которые содержат данные о запасах. Конкретно это означало бы просмотр ряда ячеек (например, r < 6, c < 10) для "Close", "close" или "ЗАКРЫТЬ".

В следующем коде показана точка, в которой пользователь выбрал файл .xls.

Я не уверен, как прокручивать листы в книге, чтобы искать нужный текст.

Я предполагаю, что это связано с созданием набора листов и назначением его тем, кто находится в текущая рабочая книга, но мои попытки пока не сработали.

private void button1_Click(object sender, System.EventArgs e)
{
  try
  {
    OpenFileDialog dlg = new OpenFileDialog();
    dlg.Filter = "Excel Files (*.xls)|*.XLS";

    if (dlg.ShowDialog() == DialogResult.OK)
    {

       // MessageBox.Show(dlg.FileName, "My Application", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
       Excel.Application xlApp = new Excel.ApplicationClass();
       xlApp.Visible = true;
       Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(dlg.FileName,
                0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
                true, false, 0, true, false, false);

     }

  }
  catch (Exception theException)
  {
    String errorMessage;
    errorMessage = "Error: ";
    errorMessage = String.Concat(errorMessage, theException.Message);
    errorMessage = String.Concat(errorMessage, " Line: ");
    errorMessage = String.Concat(errorMessage, theException.Source);

    MessageBox.Show(errorMessage, "Error");
  }
}

Спасибо за любые идеи.

Джефф

Теги:
excel

4 ответа

2

Вам нужно назначить objSheets чему-то, скорее всего:

Excel.Sheets objSheets = xlWorkbook.Sheets;

Ваш оператор foreach должен выглядеть более как это (без предварительного объявления переменной ws):

foreach(Excel.Worksheet ws in objSheets)
{
     rng = ws.get_Range(ws.Cells[1,1], ws.Cells[5,9]);
}

Очевидно, что вы захотите сделать что-то более существенное в этом цикле.

2

Всегда обращайте особое внимание на очистку при использовании библиотек Interop. В противном случае вы, скорее всего, получите несколько десятков процессов EXCEL.EXE, выполняющихся в фоновом режиме во время отладки (или когда пользователь нажимает на ошибку).

private static bool IsStockDataWorkbook(string fileName)
{
    Excel.Application application = null;
    Excel.Workbook workbook = null;
    try
    {
        application = new Excel.ApplicationClass();
        application.Visible = true;
        workbook = application.Workbooks.Open(fileName, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);

        foreach (Excel.Worksheet sheet in workbook.Worksheets)
        {
            if (IsStockWorksheet(sheet))
            {
                return true;
            }
        }

        return false;
    }
    finally
    {
        if (workbook != null)
        {
            workbook.Close(false, Missing.Value, Missing.Value);
        }
        if (application != null)
        {
            application.Quit();
        }
    }
}
private static bool IsStockWorksheet(Excel.Worksheet workSheet)
{
    Excel.Range testRange = workSheet.get_Range("C10", Missing.Value);
    string value = testRange.get_Value(Missing.Value).ToString();

    return value.Equals("close", StringComparison.InvariantCultureIgnoreCase);
}
  • 0
    Все эти «Missing.Value» объясняют, почему люди предпочитают взаимодействие VB.NET для Office, и почему C # 4 имеет динамическое ключевое слово.
  • 0
    Да, это правда, что вам нужно навести порядок; Я не упомянул об этом в своем небрежном ответе ниже. Насколько я понимаю, Marshal.FinalReleaseComObject (объект) должен вызываться для каждой переменной, назначенной COM-объекту. Я думаю, это также означает, что вы не можете использовать цикл foreach, как показано здесь.
Показать ещё 4 комментария
1

Это легко: используйте листы в .

0
Workbooks workbooks = xlApp.Workbooks;
foreach(Workbook wb in workbooks)
{
    Worksheets worksheets = wb.Worksheets;
    foreach(Worksheet ws in worksheets)
    {
        Range range = ws.get_Range(ws.Cells[1,1], ws.Cells[5,9]);
        Range match = range.Find("close", ws.Cells[1,1],
            xlFindLookIn.xlValues, xlLookAt.xlPart,
            xlSearchOrder.xlByColumns, xlSearchDirection.xlNext,
            false, false, false); //that first false means ignore case
        // do something with your match here
        // this will only return the first match; to return all
        // you'll need to run the match in a while loop
    }
}
  • 0
    Спасибо, Джей. Кажется, моя проблема в том, чтобы заставить коллекцию рабочих листов работать должным образом. По некоторым причинам это зацикливается на выражении foreach. Все, что я пробовал, отображается красным. Возможно, мне не хватает пространства имен или ссылки? Я буду продолжать смотреть на это. Спасибо джефф

Ещё вопросы

Сообщество Overcoder
Наверх
Меню