С#: есть ли способ получить адрес ячейки в excel, откуда начинаются данные?

Я пытаюсь скопировать данные Excel с одного листа на другой. Он работает нормально, но проблема: В исходном файле, если данные не запускаются из ячейки A1 (рассмотрите изображение ниже), в этом случае я хочу скопировать данные из ячейки В5. Здесь Some header не требуется. Фактические данные начинаются с ячейки Emp ID.

С#: есть ли способ получить адрес ячейки в excel, откуда начинаются данные?

Что я пробовал, я могу предоставить textbox для ввода в него адреса ячейки, а затем начать копирование данных с предоставленного адреса ячейки. Но это вводит ручное вмешательство. Я хочу, чтобы это было автоматизировано. Любая помощь в этом приветствуется. Спасибо за помощь.

Дайте нам четкое описание каковы правила для определения того, где начинаются данные. Они нужны нам и наверняка понадобятся компьютерной программе. т.е. по каким критериям содержимое правила 3 ​​нет считается данными? Мы не можем просто использовать правило «Я узнаю это, когда увижу это».

Damien_The_Unbeliever 04.04.2019 08:34

@Damien_The_Unbeliever: данные могут начинаться где угодно на листе. Правило 3 может быть просто заголовком, таким как название компании или аналитика, или что-то вроде Result set, которое на самом деле не связано при слиянии или извлечении данных.

Raj 04.04.2019 11:45

Да, но если вы не можете придумать какие-то правила, которые мы можем применить, которые говорят, какие данные является или не, как вы можете ожидать, что компьютерная программа определит это? Как я уже сказал, мы не можем реализовать «я узнаю это, когда увижу это». Например. это первая ячейка, которая также содержит непустые ячейки непосредственно ниже и справа от нее? Это — это правило, которое мы могли бы реализовать. Но мы не знаем, соответствует ли это определениям твой.

Damien_The_Unbeliever 04.04.2019 12:57

Да, я понял вашу точку зрения. Вы правы, это первая ячейка, которая также содержит непустые ячейки непосредственно ниже и справа от нее. Но опять же, это может быть в одном конкретном файле, но не в другом. В другом файле Emp ID может начинаться с ячейки A1, а может быть Some header может вообще не присутствовать (первые несколько записей просто пустые). Так что в этом случае мое правило не будет действовать. Надеюсь, вы поняли мою точку зрения...?

Raj 04.04.2019 13:34

@Damien_The_Unbeliever Думаю, оператор не хочет иметь никаких строгих правил в отношении операции копирования! Поскольку он указал, что может предоставить textbox для этого (но не хочет ручного вмешательства), он ожидает что-то вроде автоматического извлечения ячейки, где находится EmpID. Вот как это?

Ashish Srivastava 04.04.2019 13:43

Проблема заключается в том, что либо лист создается для использования в качестве входных данных для приложения, либо нет. Если лист создан кем-то, кто понимает, что его нужно импортировать, он обеспечит некоторую согласованность, на основе которой вы сможете создавать правила. Если они этого не делают, вы пытаетесь обработать непредсказуемый, неструктурированный ввод. Вещи будут меняться случайным образом и сделают вашу жизнь несчастной. Вам постоянно нужно будет добавлять все больше и больше разовых условий. Я видел, как это пытались. Это не самое счастливое место.

Scott Hannen 04.04.2019 20:28

Я полностью согласен с вами, @ScottHannen.

Raj 08.04.2019 13:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
604
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предполагая некоторые основные критерии, следующий код должен сделать это. Критерии, которые я предполагаю, следующие: 1) если строка содержит какие-либо объединенные ячейки (например, ваш «Некоторый заголовок»), то это не начальная строка. 2) начальная ячейка будет содержать текст в ячейке справа и в ячейке под ней.

private static bool RowIsEmpty(Range range)
{
  foreach (object obj in (object[,])range.Value2)
  {
    if (obj != null && obj.ToString() != "")
    {
      return false;
    }
  }

  return true;
}

private static bool CellIsEmpty(Range cell)
{
  if (cell.Value2 != null && cell.Value2.ToString() != "")
  {
    return false;
  }

  return true;
}

private Tuple<int, int> ExcelFindStartCell()
{
  var excelApp = new Microsoft.Office.Interop.Excel.Application();
  excelApp.Visible = true;

  Workbook workbook = excelApp.Workbooks.Open("test.xlsx");
  Worksheet worksheet = excelApp.ActiveSheet;

  // Go through each row.
  for (int row = 1; row < worksheet.Rows.Count; row++)
  {
    Range range = worksheet.Rows[row];

    // Check if the row is empty.
    if (RowIsEmpty(range))
    {
      continue;
    }

    // Check if the row contains any merged cells, if so we'll assume it's
    // some kind of header and move on.
    object mergedCells = range.MergeCells;
    if (mergedCells == DBNull.Value || (bool)mergedCells)
    {
      continue;
    }

    // Find the first column that contains text in this row.
    for (int col = 1; col < range.Columns.Count; col++)
    {
      Range cell = range.Cells[1, col];

      if (CellIsEmpty(cell))
      {
        continue;
      }

      // Now check if the cell to the right also contains text.
      Range rightCell = worksheet.Cells[row, col + 1];

      if (CellIsEmpty(rightCell))
      {
        // No text in right cell, try the next row.
        break;
      }

      // Now check if cell below also contains text.
      Range bottomCell = worksheet.Cells[row + 1, col];

      if (CellIsEmpty(bottomCell))
      {
        // No text in bottom cell, try the next row.
        break;
      }

      // Success!
      workbook.Close();
      excelApp.Quit();
      return new Tuple<int, int>(row, col);
    }
  }

  // Didn't find anything that matched the criteria.
  workbook.Close();
  excelApp.Quit();
  return null;
}

Да, это работает, но я немного изменил решение. Я обновил ответ. Огромное спасибо gunnerone :)

Raj 08.04.2019 13:26

Другие вопросы по теме