Я пытаюсь скопировать данные Excel с одного листа на другой. Он работает нормально, но проблема: В исходном файле, если данные не запускаются из ячейки A1 (рассмотрите изображение ниже), в этом случае я хочу скопировать данные из ячейки В5. Здесь Some header
не требуется. Фактические данные начинаются с ячейки Emp ID
.
Что я пробовал, я могу предоставить textbox
для ввода в него адреса ячейки, а затем начать копирование данных с предоставленного адреса ячейки. Но это вводит ручное вмешательство. Я хочу, чтобы это было автоматизировано. Любая помощь в этом приветствуется. Спасибо за помощь.
@Damien_The_Unbeliever: данные могут начинаться где угодно на листе. Правило 3 может быть просто заголовком, таким как название компании или аналитика, или что-то вроде Result set
, которое на самом деле не связано при слиянии или извлечении данных.
Да, но если вы не можете придумать какие-то правила, которые мы можем применить, которые говорят, какие данные является или не, как вы можете ожидать, что компьютерная программа определит это? Как я уже сказал, мы не можем реализовать «я узнаю это, когда увижу это». Например. это первая ячейка, которая также содержит непустые ячейки непосредственно ниже и справа от нее? Это — это правило, которое мы могли бы реализовать. Но мы не знаем, соответствует ли это определениям твой.
Да, я понял вашу точку зрения. Вы правы, это первая ячейка, которая также содержит непустые ячейки непосредственно ниже и справа от нее. Но опять же, это может быть в одном конкретном файле, но не в другом. В другом файле Emp ID
может начинаться с ячейки A1, а может быть Some header
может вообще не присутствовать (первые несколько записей просто пустые). Так что в этом случае мое правило не будет действовать. Надеюсь, вы поняли мою точку зрения...?
@Damien_The_Unbeliever Думаю, оператор не хочет иметь никаких строгих правил в отношении операции копирования! Поскольку он указал, что может предоставить textbox
для этого (но не хочет ручного вмешательства), он ожидает что-то вроде автоматического извлечения ячейки, где находится EmpID. Вот как это?
Проблема заключается в том, что либо лист создается для использования в качестве входных данных для приложения, либо нет. Если лист создан кем-то, кто понимает, что его нужно импортировать, он обеспечит некоторую согласованность, на основе которой вы сможете создавать правила. Если они этого не делают, вы пытаетесь обработать непредсказуемый, неструктурированный ввод. Вещи будут меняться случайным образом и сделают вашу жизнь несчастной. Вам постоянно нужно будет добавлять все больше и больше разовых условий. Я видел, как это пытались. Это не самое счастливое место.
Я полностью согласен с вами, @ScottHannen.
Предполагая некоторые основные критерии, следующий код должен сделать это. Критерии, которые я предполагаю, следующие: 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 :)
Дайте нам четкое описание каковы правила для определения того, где начинаются данные. Они нужны нам и наверняка понадобятся компьютерной программе. т.е. по каким критериям содержимое правила 3 нет считается данными? Мы не можем просто использовать правило «Я узнаю это, когда увижу это».