2016-11-29 6 views
0

Скажите, что у вас есть файл excel с множеством цифр и строк, около 100 строк.(C# - Excel) Как написать формулу для вновь созданного столбца для каждой существующей строки?

Я хочу программно написать столбец с формулой, которая добавляет значения связки полей для каждой существующей строки.

В первую очередь, конечно, я бы создал Openfiledialog для файла Excel, найти путь, открыть его через OleDb. Получил это. Теперь скажите, что у меня есть следующая таблица:

[Друзья | Деньги | Деньги Проиграл | Прошедшие дни | Решение]

Бильбо, 50, 50, 7, * Формула здесь

Bilso, 80, 50, 7, * Формула здесь

и т.д ...

Проблема, я дон У меня есть точное число для строк, поэтому мне придется перечислить все, что обнаружено соединением OleDb. Формула будет чем-то вроде = (B2-C2) * D2, но 2 также неверна, и она должна относиться к любой строке, в которой она находится, т. Е. Строка 3 будет = (B3-C3) * D3. Я не уверен, как это сделать.

Я узнал, что запись непосредственно в ячейку также не приводит к тому, что формула обрабатывает номера прямо.

=====

EDIT:

private Excel.Application Xls; 
    private Excel.Workbooks WBs; 
    private Excel.Workbook WB; 
    private Excel.Worksheet WS; 
    private Excel.Sheets SS; 
    Excel.Range cellsRange = null; 
    Excel.Range columnRange = null; 
    Excel.Range rowRange = null; 
    int numberOfColumns = 0; 
    int numberOfRows = 0; 
    private void btnColumn_Click(object sender, EventArgs e) 
    { 
     if (btnColumn.FlatStyle == FlatStyle.Flat) 
      btnColumn.FlatStyle = FlatStyle.Standard; 
     else 
     { 
      btnColumn.FlatStyle = FlatStyle.Flat; 
     } 

     OpenFileDialog openFileDialog = new OpenFileDialog(); 
     openFileDialog.Filter = "Excel Files|*.xls;*.xlsx"; 
     openFileDialog.ShowDialog(); 
     string pather = openFileDialog.FileName; 

     if (pather == "" || pather == " " || pather == null) 
     { 
      return; 
     } 

     if (!string.IsNullOrEmpty(openFileDialog.FileName)) 
     { 
      try 
      { 
       Xls = new Excel.Application(); 
       WBs = Xls.Workbooks; 
       WB = WBs.Open(pather, 0, false, 5, "", "", true, 
        XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); 
       SS = WB.Worksheets; 
       WS = SS.get_Item(1);      
       cellsRange = WS.Cells; 
       columnRange = cellsRange.Columns; 
       rowRange = cellsRange.Rows; 
       numberOfColumns = columnRange.Count; 
       numberOfRows = rowRange.Count; 
       int LastCell = numberOfColumns+1; 
       WS.Cells[1, LastCell] = "Tax Formula"; 
       for (int i = 2; i < numberOfRows; i++) 
       { 
        //string niceFormula = "=SUM(L" + i + ",M" + i + ")*N"+ i ; 
        //WS.Cells[i, LastCell].Formula = niceFormula; 
        WS.Cells[i, LastCell].Value = (WS.Cells[i, 12] + WS.Cells[i, 13]) * WS.Cells[i, 14]; 
       } 
       //========================== 
       WB.Save(); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show("Write Excel: " + ex.Message); 
      } 
      finally 
      { 
       GC.Collect(); 
       GC.WaitForPendingFinalizers(); 
       WB.Close(); 
       Xls.Quit(); 

       releaseObject(cellsRange); 
       releaseObject(columnRange); 
       releaseObject(rowRange); 
       releaseObject(SS); 
       releaseObject(WS); 
       releaseObject(WBs); 
       releaseObject(WB); 
       releaseObject(Xls); 
      } 
     MessageBox.Show("Finished Updating File", "Task complete"); 
    } 
} 

Кто знает, почему этот код бросает следующее сообщение об ошибке при попытке записи?

HRESULT: 0x800A03EC

употреблено в пищу весь код для вашего удобства. Он все еще выплевывает ошибку HRESULT.

Целевой элемент состоит из 4 рядов глубиной с 1 рядом заголовков и шириной около 16 колонок.

+1

Было бы медленно обрабатывать каждую ячейку значения по одному. Я бы предложил вам получить все данные в Excel в таблицу данных и выполнить расчет (используя LINQ или обычные циклы) и добавить вычисленное значение в новый столбец в той же таблице данных. В конце экспортируйте таблицу данных в лист Excel в требуемом формате. –

+0

Вы не сказали нам, как вы пишете дату. VBA? Или приложение Winform с Excel Interop? Или приложение WinForm с EPPlus? Пожалуйста, укажите более подробную информацию. – nabuchodonossor

+0

@nabuchodonossor, я изначально оставил его открытым, потому что иногда кто-то приходил в готовность с ответом VBA, но отключился тегом C#. В некоторых случаях я могу преобразовать логику в один подходящий для C#, таким образом, будет больше ответов, но да, это Winform с Excel Interop. – Aroueterra

ответ

1

Edit:

Вы можете попробовать это:

numberOfColumns = WS.UsedRange.Columns.CountLarge; 
numberOfRows = WS.UsedRange.Rows.CountLarge; 

тьфу, а также изменить их long вместо int если вы используете CountLarge вместо Count

Okay - Я получил это наконец, работать - не знаю, почему у меня было так много проблем.

Для меня я, видимо, должен сделать приложение видимым или не работает.

Там может быть другой обходной путь - я вытащил его отсюда: https://stackoverflow.com/a/17061714/1274820

Этот код работает для меня, наконец:

Обратите внимание, что это консольное приложение (фигурный я исключаю), но вы должен просто быть в состоянии добавить магические линии.

Application excelApp = new Application(); 
excelApp.SheetsInNewWorkbook = 1; 
//////////////////////////////////////////// 
//Add these lines to make it work??? 
//////////////////////////////////////////// 
try { 
    excelApp.Visible = true; 
} 
catch {} 
//////////////////////////////////////////// 
Workbook excelWB = excelApp.Workbooks.Open(@"C:\test.xls", Type.Missing, false); 
_Worksheet excelWS = excelWB.Sheets[1]; 
Range cellsRange = excelWS.UsedRange; 
long LastCell = cellsRange.Columns.CountLarge + 1; 
long numberOfRows = cellsRange.Rows.CountLarge; 
excelWS.Cells[1, LastCell] = "Tax Formula"; 
for (int i = 2; i <= numberOfRows; i++) 
{ 
    string niceFormula = "=SUM(L" + i + ",M" + i + ")*N" + i; 
    excelWS.Cells[i, LastCell].Formula = niceFormula; 
} 
excelWB.Close(true); 
excelApp.Quit(); 

До:

Before

После:

After

Как заполнить DataTable с таблицей Excel:

////////////////////////////////////////////////////////////////////////////////// 
//This function is absolute magic >.> - Fill DataTable with excel spreadsheet 
//HDR=YES means "Spreadsheet has headers" Change to NO if not. 
//name = "Log"; - This is the Sheet name to pull the data from 
////////////////////////////////////////////////////////////////////////////////// 
//oconn takes an SQL like command (Select Everything from name sheet) using con 
//HDR=YES means that our data has headers :) 
////////////////////////////////////////////////////////////////////////////////// 
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + copyToPath + ";Extended Properties='Excel 12.0 XML;HDR=YES;';"; 
OleDbConnection con = new OleDbConnection(constr); 
OleDbCommand oconn = new OleDbCommand("Select * From [Log$]", con); 
con.Open(); 
OleDbDataAdapter sda = new OleDbDataAdapter(oconn); 
DataTable data = new DataTable(); 
sda.Fill(data); 
con.Close(); 
////////////////////////////////////////////////////////////////////////////////// 
+0

Да, это намного опрятно, чем то, что у меня было, хотя я не помещал его в datatable, а скорее в DataGridView. Используя это, как вы получите доступ к данным в данных? Как и массив? int 'foo = data [1,1]'? Единственные времена, с которыми я работал с таблицей данных, заключались в том, чтобы заполнить DataGridView (который я _then_ сопрягался), но он работал. Ох и кстати, как я уже говорил выше, я пробовал свой код, но я получаю ту же ошибку, что и раньше. Возможно, что-то не так с моими объявлениями диапазона, я не замечаю? – Aroueterra

+0

Я работаю в обратном направлении на вашем atm - вы дважды объявляете «Xls» и «Wbs» в своем коде, поэтому там явно проблема. Вы также получаете объект книги перед тем, как открыть файл. Это, вероятно, не очень хорошая идея. – user1274820

+0

Я отправил весь свой код без бита формулы, аналогичный код работает в другой функции, которая просто добавляет значения в ячейки, поэтому базовая структура кода должна работать. Тем не менее я по-прежнему получаю ошибку HRESULT по какой-то причине. – Aroueterra