Currently, I have the following method that writes to excel 2007.
public static void createSpreadsheet(String msg)
{
Excel.Application oXL;
Excel.Workbook oWB;
Excel.Worksheet oSheet;
Excel.Range oRng;
oXL = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
oWB = oXL.Workbooks.get_Item(1);
oSheet = (Excel.Worksheet)oWB.ActiveSheet;
oXL.Visible = true;
oXL.UserControl = false;
oRng = oSheet.get_Range("A1", "A" + 1);
oRng.Value2 = msg;
}
However, whatever msg I sent, it only get to write to column A1 which is evident from the code above.
How do I expand the code above so that whenever additional messages are sent, they are appended below the previously written column.??
In a console app, I could do this: Console.writeline(msg). How do I achieve that in excel?
Eg: Msg 1 (Col A1)
Msg 2 (Col A2)
Msg 3 (Col A3)
....
Define a variable called currentColumn and pass it to the method:
public static void createSpreadsheet(String msg, column)
In calling:
// there is an integer variable called currentColumn
createSpreadsheet("a message", currentColumn++)
You're only getting the A1 cell currently. If you want to write to some other row, just change the parameters to your range. For example:
oRng = oSheet.Range["A" + rowNumber, "A" + rowNumber];
oRng.Value = msg;
And now you can dynamically increment rowNumber after each message. Same thing works for columns, just replace "A" with the appropriate column.
Related
I am unable to export data from multiple rows in DTG to specific columns in excel. I have tried multiple methods from forums. So far, the results are excel opened but no data are exported (empty cells) or only the last row of DTG are copied to the specific columns in excel.
I want this excel sheet to compile the DTG data. Hence, example user open form 1st time, enter DTG data, saves to excel and closes form. User then open form 2nd time and enter another DTG data, the 2nd DTG data will go into the same excel columns but on the next empty row (underneath the row of the 1st DTG data).
Most codes that I've tried comes from this link [Programmatically getting the last filled excel row using C# ]. I did not put the column part as I only want last row. Do note that the skeleton of all the codes are the same but the way lastUsedRow was initialized are different.
Codes below gives empty cells
Excel.Application oXL;
Excel._Workbook oWB;
Excel._Worksheet oSheet;
try
{
oXL = new Microsoft.Office.Interop.Excel.Application();
oWB = oXL.Workbooks.Open("C:\\Users\\User\\Test.xlsx");
oSheet = oXL.Worksheets["Vehicles"];
Excel.Range last = oSheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
Excel.Range range = sheet.get_Range("A1", last);
int lastUsedRow = last.Row;
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
for (int j = 1; j < dataGridView1.Columns.Count; j++)
{
oSheet.Cells[lastUsedRow, j+1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
}
OR
int lasUsedRow = oSheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing).Row;
Codes below shows only last row of DTG
int lastUsedRow = oSheet.Cells.Find("*",System.Reflection.Missing.Value,
System.Reflection.Missing.Value, System.Reflection.Missing.Value, Excel.XlSearchOrder.xlByRows,Excel.XlSearchDirection.xlPrevious, false,System.Reflection.Missing.Value,System.Reflection.Missing.Value).Row;
OR
int lastUsedRow = oSheet.Range["B" + oSheet.Rows.Count].End[Excel.XlDirection.xlUp].Row+1;
Hope to get some help. Thank you so much!
As per Yoshi's comment, below is the updated code where it allows multiple datagridview rows to be added and compiled into excel.
Excel.Application oXL;
Excel._Workbook oWB;
Excel._Worksheet oSheet;
try
{
//Start Excel and get Application object.
oXL = new Microsoft.Office.Interop.Excel.Application();
//Get a new workbook.
oWB = oXL.Workbooks.Open("C:\\Users\\User\\Test.xlsx");
//Specify different sheet names
oSheet = oXL.Worksheets["Vehicles"];
//Define last row
int _lastRow = oSheet.Range["B" + oSheet.Rows.Count].End[Excel.XlDirection.xlUp].Row+1;
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
for (int j = 1; j < dataGridView1.Columns.Count; j++)
{
oSheet.Cells[_lastRow, j+1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
_lastRow++;
}
//Make sure Excel open and give the user control of Microsoft Excel's lifetime.
oXL.Visible = true;
oXL.UserControl = true;
//Autosave excel file
oWB.Save();
Marshal.ReleaseComObject(oXL);
}
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");
}
}
I'm trying to get all Excel selected range values including blank entries. What I have worked until is,when a blank is hit and then it exits the loop. I need to recognize the blank, do something with it and then go on to the next cell in the selected range.
This is my code:
// Get active excel instance
Excel.Application xlApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
// Get active excel workbook
string wbn = xlApp.ActiveWorkbook.Name;
Excel.Workbook xlWorkBook = (Excel.Workbook)xlApp.ActiveWorkbook;
// Get active excel worksheet
Excel.Worksheet xlWorkSheet = (Excel.Worksheet)xlWorkBook.ActiveSheet;
// Get range of values from Excel
Microsoft.Office.Interop.Excel.Range SelectedRange = xlApp.Selection as Microsoft.Office.Interop.Excel.Range;
string[] ExcelSelection = new string[1000];
int counter = 0;
foreach (object cell in xlApp.Selection.Cells) //original loop stopping when it hits a blank cell
{
try
{
ExcelSelection[counter] = ((Excel.Range)cell).Value2.ToString().Trim();
//run query to return SAP Description for Excel Active Cell Text
dataGridView1.DataSource = GetSAPDescription(ExcelSelection[counter]);
counter++;
}
catch
{
}
}
}
I want to read the each cell value in excel file, But i am not able to get the cell values even after trying different examples in NET. I am not getting result with the following code, can any one get back on this. I am using .net framework 2.0
string filePath = "F:/BulkTest.xlsx";
Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
ExcelApp.Visible = true;
Microsoft.Office.Interop.Excel.Workbook wb = ExcelApp.Workbooks.Open(filePath, 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);
Microsoft.Office.Interop.Excel.Worksheet sh = (Microsoft.Office.Interop.Excel.Worksheet)wb.Sheets["Sheet1"];
Range excelRange = sh.UsedRange;
for (int i=2; i<= excelRange.Count + 1 ; i++)
{
string values = sh.Cells[i,2].ToString();
}
Till now i am trying to take cell values directly to variables, now i will try to take cell values to an array using Range. Thanks!!!! – Teja Varma 13 mins ago
No. I didn't even mean that :) As I mentioned in the comment that you can store the entire range in an array. That doesn't mean that you need to loop though each cell to store it in an array. You can directly assign the values of the range to the array. See this example.
xlRng = xlWorkSheet.get_Range("A1", "A20");
Object arr = xlRng.Value;
foreach (object s in (Array)arr)
{
MessageBox.Show(s.ToString());
}
The correct answer would be to use:
Sheet.Cells[row,col].Value.ToString();
C# code
Tested OK
string s = xlSheet.UsedRange.Cells[1, 7].Value.ToString();
//or
string d = xlSheet.UsedRange.Cells[1, "G"].Value.ToString();
Full Code
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlBook;
Excel.Worksheet xlSheet;
string Path = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
xlBook = xlApp.Workbooks.Open(Path + "\\myfile.xlsx");
xlApp.Visible = true;
xlSheet = xlBook.ActiveSheet;
string s = xlSheet.UsedRange.Cells[1, 7].Value.ToString();
string d = xlSheet.UsedRange.Cells[1, "G"].Value.ToString();
xlBook.Close();
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
So here's what I am going through. I am using the Excel dll with c# in order to go inside a big and nasty excel sheet so that others don't have to.
We have a formula in one cell that is rather large and we don't want to copy it to every row because of this. This formula uses multiple values on the row that it is placed on. If it is on row 1, it uses lots of cells from that row.
When one copies this formula normally in excel, the new ranges of the cells are modified to reflect the new starting position.
The problem is that when I copy the formula like this, it still gives me all of the values that have to do with the first row instead of the row where I pasted it.....Here is my code:
sheet.Cells[77][row].Formula = sheet.Cells[77][1].Formula;
Can somebody let me know how to make the formula actually apply to the new row instead of row 1?
This will probably work, as it works from VBA... in most cases.
sheet.Cells[77][row].FormulaR1C1 = sheet.Cells[77][1].FormulaR1C1;
This would work because FormulaR1C1(not a very informative link) uses R1C1 notation which describes the referenced cells location in relation to the current cell instead of saying which cells to use. This means the actual references are dependent on the cell with the formula. When you just use Formula, you're copying the string of the Formula exactly including the hard coded cell references.
You could use Application.ConvertFormula
So, let's say my Cell = Cells77 has a formula that says =Sum(B77,C77) (Cells from the same row).
if want to copy it to a cell right below it, you would do something like:
string formula = Sheet1.Cells[77][2].Formula;
Sheet1.Cells[77][2].Formula = app.ConvertFormula(formula, XlReferenceStyle.xlA1, XlReferenceStyle.xlR1C1, XlReferenceType.xlRelative, Sheet1.Cells[77][3]);
Full console app that works (You need to modify cells though).
static void Main(string[] args)
{
var app = new Microsoft.Office.Interop.Excel.Application();
var workbook = app.Workbooks.Open(#"C:\Users\user\Desktop\Book1.xlsx");
Microsoft.Office.Interop.Excel.Worksheet Sheet1 = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.get_Item("Sheet1");
string formula = Sheet1.Cells[5][3].Formula;
Sheet1.Cells[5][4].Formula = app.ConvertFormula(formula, XlReferenceStyle.xlA1, XlReferenceStyle.xlR1C1, XlReferenceType.xlRelative, Sheet1.Cells[5][3]);
workbook.SaveAs(#"C:\Users\user\desktop\test.xlsx");
workbook.Close();
}
You can modify third and forth parameter of ConvertFormula method to your liking. Read more about the method here: ConvertFormula.
If you want to stretch formula accross multiple rows, you can try to use range.AutoFill()
Hi guys m posting this because this code is used to copy the formula behind a cell in Excel:
public void copy_Formula_behind_cell()
{
Excel.Application xlapp;
Excel.Workbook xlworkbook;
Excel.Worksheet xlworksheet;
Excel.Range xlrng;
object misValue = System.Reflection.Missing.Value;
xlapp = new Excel.Application();
xlworkbook =xlapp.Workbooks.Open("YOUR_FILE", 0, true, 5, "",
"",true,Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t",
false,
false, 0, true, 1, 0);
xlworksheet = (Excel.Worksheet)xlworkbook.Worksheets.get_Item(1);
string sp = xlworksheet.Cells[3,2].Formula;//It will Select Formula using Fromula method//
xlworksheet.Cells[8,2].Formula =
xlapp.ConvertFormula(sp,XlReferenceStyle.xlA1,
XlReferenceStyle.xlR1C1, XlReferenceType.xlAbsolute,
xlworksheet.Cells[8][2]);
//This is used to Copy the exact formula to where you want//
xlapp.Visible = true;
xlworkbook.Close(true, misValue, misValue);
xlapp.Quit();
releaseObject(xlworksheet);
releaseObject(xlworkbook);
releaseObject(xlapp);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
I am posting this code for range the excel formulas using c# code and Microsoft.Office.Interop.Excel Library:
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Excel();
}
public void Excel()
{
Application xlApp = new Application();
Workbook xlWorkBook;
Worksheet xlWorkSheet;
object misValue = Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Worksheet)xlWorkBook.Worksheets.get_Item(1);
for (int r = 1; r < 5; r++) //r stands for ExcelRow and c for ExcelColumn
{
// Its a my sample example: Excel row and column start positions for writing Row=1 and Col=1
for (int c = 1; c < 3; c++)
{
if (c == 2)
{
if (r == 1)
{
xlWorkSheet.Cells[r, c].Formula = "=SUM(A1+200)";
}
continue;
}
xlWorkSheet.Cells[r, c] = r;
}
}
Range rng = xlWorkSheet.get_Range("B1");
// This is the main code we can range our excel sheet formulas
rng.AutoFill(xlWorkSheet.get_Range("B1", "B4"), XlAutoFillType.xlLinearTrend);
xlWorkBook.Worksheets[1].Name = "MySheetData";//Renaming the Sheet1 to MySheet
xlWorkBook.SaveAs(#"E:\test.xlsx");
xlWorkBook.Close();
Marshal.ReleaseComObject(xlWorkSheet);
Marshal.ReleaseComObject(xlWorkBook);
Marshal.ReleaseComObject(xlApp);
}
}
Ok, so I have a class, customer, that I use to process data, and then add to a list box, like below:
//Submit data from current form
customer aCustomer = new customer(comboBox1.Text, textBox1.Text, ChannelSelecBox.Text,
PurchaserTextBox.Text, NameTextBox.Text, emailTextBox.Text, AddressTextBox.Text, StateBox.Text,
PayMethodDropDown.Text, Prod1Num.Value.ToString(), Prod2Num.Value.ToString(),
Prod3Num.Value.ToString(), Prod4Num.Value.ToString(), Prod5Num.Value.ToString(),
Prod6Num.Value.ToString(), SubTData.Text, DiscountTextBox.Text, TaxData.Text, CommentTextBox.Text,
ShipData.Text, TotalData.Text);
// Add aCustomer to ListBox
Orders.Items.Add(aCustomer);
I have a string override so that the listbox just displays the purchaser and the date.
Now I want to take all the orders entered into the list box and put, most of, this data into an excel spreadsheet, each into it's own column. How could I do this?
If you need more information or to see more of my code, let me know.
try the following;
object oOpt = System.Reflection.Missing.Value; //for optional arguments
Excel.Application oXL = new Excel.Application();
Excel.Workbooks oWBs = oXL.Workbooks;
Excel.Workbook oWB = oWBs.Add(Excel.XlWBATemplate.xlWBATWorksheet);
Excel.Worksheet oSheet = (Excel.Worksheet)oWB.ActiveSheet;
//outputRows is a List<List<object>>
int numberOfRows = outputRows.Count;
int numberOfColumns = outputRows.Max(list => list.Count);
Excel.Range oRng =
oSheet.get_Range("A1", oOpt)
.get_Resize(numberOfRows, numberOfColumns);
object[,] outputArray = new object[numberOfRows, numberOfColumns];
for (int row = 0; row < numberOfRows; row++)
{
for (int col = 0; col < outputRows[row].Count; col++)
{
outputArray[row, col] = outputRows[row][col];
}
}
oRng.set_Value(oOpt, outputArray);
oXL.Visible = true;
more details can be found at http://csharp.net-informations.com/excel/csharp-create-excel.htm
Use CSV as file format, not XLS. Excel is a pain. Especially when reading from XLS. Some incorrect cell formatting and you sometimes get the value, but sometimes not. Even in same file. Personal experience.