Get values of Excel Cells in C# including blank cells - c#

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
{
}
}
}

Related

How to excel file import to database in c#?

I have the same database table with excel in my hand.And I want to read the values ​​in this excel and save it in the database.And in the meantime excel would also like to read by providing control of whether the values ​​are empty or not.I want to do this with mvvm.If you click on the save button to check if the database is correct and I want to save.
If you excel in the empty column etc. if you want to print it to datagrid.
If not, I want to print to the database
Excel is:
ID NAME CLASS
12 JOHN 3
24 Alex 7
Database Table is:
ID NAME CLASS
I want to this excel is read and excel is insert to table.But I dont read and insert to table.I want to read excel and set datatable in excel.
I try to:
//Excel Read Code
Excel.Application app=new Excel.Application();
Excel.Workbook workbook=app.workbooks.Open(fileName,Type.Missing,Type.Missing);
Excel.Worksheet sheet=workbook.Sheets[1];
Excel.Range range=sheet.UsedRange;
`public void ReadExcel(string path){
try
{
System.Data.DataTable dt = new System.Data.DataTable();
Microsoft.Office.Interop.Excel.Application xlApp = new
Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(path);
Microsoft.Office.Interop.Excel.Worksheet xlWorksheet = xlWorkbook.Sheets[1];
Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
int rowCount = xlRange.Rows.Count;
for (int r = 2; r <= rowCount; r++)
INSERT INTO mytable (ID,NAME,CLASS)VALUES (dr[c - 1] = xlRange.Cells[r, c].Text,
xlRange.Cells[r,c+1].Text, xlRange.Cells[r,c+2].Text);
}
}
}catch(Exception ex){throw ex;}
`

c# winforms: Unable to export data from multiple rows in DTG to last available row in excel

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");
}
}

Writing to sheet leads to "name already taken"

I'm learning how to use Interop.Excel. The test Winforms program reads an existing Excel file, checks if a tab names "Added_by_program" exists, deletes the sheet if it does, and creates a new sheet named "Added_by_program." If I don't try to write to the new sheet, the program runs perfectly, over and over. I get problems when I try to write to it. If the sheet is not present in the original file, the program runs perfectly one time, and writes correctly to the newly created sheet. but on subsequent runs, I get:
"System.Runtime.InteropServices.COMException: 'That name is already taken. Try a different one.'"
for the line that tries to name the new sheet. I have to manually kill the open Excel instance. What am I missing?
Code (irrelevant lines taken out)
using System;
using System.IO;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
namespace excelReadWrite
{
public partial class Form1 : Form
{
string readFolder = myPath;
string inFileName = #"Aram test excel file.xlsx";
string newSheetName = "Added_by_program";
Range rawRange = null;
Range pasteRange = null;
int rawCols = 0;
int rawRows = 0;
int iInSheet = 0;
int iNewSheet = 0;
int nInSheets = 0;
bool foundRawSheet = false;
bool foundNewSheet = false;
Worksheet worksheet = null;
public Form1()
{
InitializeComponent();
}
private void start_Button_Click(object sender, EventArgs e)
{
string inFile = myPath+ inFileName;
int nSheets = 0;
string sheetNames = "";
// Open Excel workbook to read
Microsoft.Office.Interop.Excel.Application xl = new Microsoft.Office.Interop.Excel.Application();
Workbook workbook = xl.Workbooks.Open(inFile);
// Count worksheets in opened Excel file
nSheets = workbook.Worksheets.Count;
nSheets_TextBox.Text = nSheets.ToString();
nInSheets = 0;
foreach (Worksheet worksheet in workbook.Worksheets)
++nInSheets;
//foreach (Worksheet worksheet in workbook.Worksheets)
for (int iSheet = nInSheets; iSheet >= 1; --iSheet)
{
worksheet = workbook.Worksheets[iSheet];
sheetNames += " " + worksheet.Name;
// The program is going to add a worksheet. If it already exists, delete it before adding it.
if (string.Equals(worksheet.Name, newSheetName))
{
workbook.Worksheets[iSheet].Delete();
}
}
// Add a new sheet and name it
if (foundRawSheet)
{
newWorksheet = workbook.Worksheets.Add();
newWorksheet.Name = newSheetName;
// THE NEXT LINE IS THE PROBLEM LINE
// "Written" WILL BE WRITTEN TO A1:C3 WHEN THE SHEET IS CREATED, BUT THIS LINE
// CAUSES THE ERROR IN SUBSEQUENT RUNS
// IF I COMMENT IT OUT, THE PROGRAM RUNS FINE, REPEATEDLY
newWorksheet.Range["A1", "C3"].Value2 = "Written";
workbook.Save();
workbook.Close();
xl.Quit();
}
}
}
Did you set xl.DisplayAlerts=false?
If not, deleting a worksheet with existing data will cause a confirm dialog to be displayed. .
If the Excel application is visible, the Worksheet.Delete will block until the dialog is acknowledged.
If the Excel application is not visible, your code execution will proceed (the dialog is effectively canceled --> delete not confirmed), but the worksheet will not be deleted.

Change MS Excel Row Colour in Excel using C#

I am currently creating a small program that will allow a user to input data into a windows form. Once this data has been input into the form it will then be added to a Excel Document using OleDb.
I have no problems with the above section and I can input data no bother however my problem comes when I try to change the colour of the Excel Row.
I am looking to change the colour of the row to red if the row currently has no fill.
The code I am currently using:
Excel.Application application = new Excel.Application();
Excel.Workbook workbook = application.Workbooks.Open(#"C:\Users\jhughes\Desktop\ScreenUpdate.xls");
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets["DailyWork"];
Excel.Range usedRange = worksheet.UsedRange;
Excel.Range rows = usedRange.Rows;
try
{
foreach (Excel.Range row in rows)
{
if (row.Cells.EntireRow.Interior.ColorIndex = 0)
{
row.Interior.Color = System.Drawing.Color.Red;
}
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
I am getting the error "Cannot implicitly convert type int to bool" at the line "If(row.Cells.EntireRow....)"
You are attempting to set the ColorIndex to 0, not comparing it to 0. Use == when you compare.
foreach (Excel.Range row in rows)
{
if (row.Cells.EntireRow.Interior.ColorIndex == 0) // changed = to ==
{
row.Interior.Color = System.Drawing.Color.Red;
}
}
You need to use == operator instead of = operator. == operator for equality but = operator is for assignment.
if (row.Cells.EntireRow.Interior.ColorIndex == 0)
= operators simply assign right operand to the left variable/property/indexer and returns the value as its result. That's why when you write
if (row.Cells.EntireRow.Interior.ColorIndex = 0)
it is equal to
if(0)
which is won't compile since if statement expects boolean expression.
I think you not added saving to workbook and change in if condition. Somehow the default colorindex is coming as -4142. Tested now able to change the change color
Excel.Application application = new Excel.Application();
Excel.Workbook workbook = application.Workbooks.Open(#"C:\Users\MyPath\Desktop\ColorBook.xls");
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets["DailyWork"];
Excel.Range usedRange = worksheet.UsedRange;
Excel.Range rows = usedRange.Rows;
try
{
foreach (Excel.Range row in rows)
{
if (row.Cells.EntireRow.Interior.ColorIndex == -4142)
{
row.Interior.Color = System.Drawing.Color.Red;
}
}
workbook.Save();
workbook.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}

Copying A Formula--And applying it to a new cell range

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);
}
}

Categories

Resources