I am using Excel Interop to generate Excel Table into an xlsx file. I have a very simple table with 3 columns and no header, no totals but has 2 rows.
Now when I generate the Excel file, I use the following code
...
Range rng = worksheet.Range["$A$1:$C$2"];
ListObject lo = worksheet.ListObjects.Add(xlSrcRange, rng, Type.Missing, XlYesNoGuess.xlNo);
lo.ShowHeaders = false;
...
With the above code it generates the table with cell range A2:C3 instead of A1:C2. But any values I set in the A row are set but outside of the table.
If I set the ShowHeaders to true in the 3rd line of code above, then Excel is converting the top row as the header line and still moves the table cell range to A2:C3
Am I doing something wrong? I appreciate any and all help and guidance to fix this issue.
Thanks
Jaideep
Try this
//
//~~> Rest of your code
//
Range rng = worksheet.Range["$A$1:$C$2"];
ListObject lo = worksheet.ListObjects.Add(xlSrcRange, rng, Type.Missing, XlYesNoGuess.xlNo);
lo.ShowHeaders = false;
Excel.Range rngRowOne = worksheet.get_Range("A1", "A1");
rngRowOne.EntireRow.Delete(Excel.XlDirection.xlUp);
//
//~~> Rest of your code
//
Related
I am reading excel file using XSSF. while reading excel sheet by row
wise if the empty cell is present in the row it tends to skip that cell value and
auto populate it with next column which gives me the wrong output. what need to be change in the program to read the row exactly what
is there in the excel including blank cell values.Below is my sample code.
XSSFWorkbook wb = new XSSFWorkbook(file);;
XSSFSheet ws =(XSSFSheet)wb.GetSheetAt(0);
for (i = 1; i <= ws.LastRowNum; i++)
{
XSSFRow row = (XSSFRow)ws.GetRow(i);//the code where empty cells are skipping
}
I have an Excel worksheet with some data. I also have a List of the column headers of the worksheet. The headers in the list are in a different order than the headers in the worksheet, and I need to reorder the Excel worksheet's columns to be the same order as the list.
List<string> dataset1Variables = new List<string>() { "Variable1", "Variable2", "Variable3", "Variable4" };
The headers of my Excel sheet may look like this:
Variable 3 | Variable 1 | Variable 4 | Variable 2
I have come across this code to shift columns but this is only for moving 1 column to a specific location. The list might be completely mixed up so I would need to shift many columns.
Excel.Range copyRange = xlWs.Range["C:C"];
Excel.Range insertRange = xlWs.Range["A:A"];
insertRange.Insert(Excel.XlInsertShiftDirection.xlShiftToRight,
copyRange.Cut());
What would be the best approach for doing this? Preferably using Interop.
If you have an empty row right above your worksheet with data, you can add matching formula right above headers. In below assuming your list is on Sheet2 range B2:B5 and your data headers start on Sheet1 range A2:D2
Excel.Workbook myBook = xlApp.Workbooks.Open(#"path\excel.xlsx");
Excel.Worksheet ws = myBook.Worksheets[1];
// You can use all dynamic ranges instead
// Excel.Range xlRng = ws.Range[ws.Cells[yourRow, firsColumn], ws.Cells[yourRow, lastColumn]];
Excel.Range xlRng = ws.Range[ws.Cells[1, 1], ws.Cells[1, 4]]; // ws.Range["A1:D1"];
xlRng.FormulaR1C1 = "=MATCH(R[-1]C,Sheet2!R2C2:$R5C2,0)";
// Below is how you can get full address for your list if it's in different workbook and replace Sheet2!R2C2:$R5C2 with rangeFullAddress
// string rangeFullAddress = xlRng.Address[true,true,Excel.XlReferenceStyle.xlR1C1,true];
xlRng.Calculate();
xlRng.Value = xlRng.Value;
After this you can just sort your data using Excel Sort by 1st row. After sorting your 1st row it would look like this: 1, 2, 3, 4. Then clear data on 1st row ws.Range["A1:D1"].Clear();.
Your sort key would be Key1: ws.Range["A1:D1"], here is c# sort example using c# to sort a column in excel only change Excel.XlSortOrientation and adjust for your range.
There are other ways to sort but this way you'll keep individual formats, comments of each cell within your data
I missed 1 important detail - that your list is not in Excel sheet, but you can add it to Excel, perhaps in temporary workbook or right on the same sheet:
object [,] columnHeaders = new object[3,0]; // or object[0,3]; if you'd like to add into 1 row
columnHeaders[0, 0] = "Variable1";
columnHeaders[1, 0] = "Variable2";
columnHeaders[2, 0] = "Variable3";
columnHeaders[3, 0] = "Variable4";
xlRng.FormulaR1C1 = columnHeaders; // xlRng would be in the above Sheet2!R2C2:$R5C2
I was trying to insert a new row at the end of a worksheet using OLEDB. The worksheet has a format table in a Range (a1:xx), with format and formula stored. But OLEDB insert does not come with any format.
I have read the post How to copy format of one row to another row in Excel with c# talking about get the format, but doesn't work for me. Also, I don't think it will get the formula.
In the Excel UI, at the lower right corner of a formatted table, a double arrow would appear, and we can drag it to expand the format table range.
Anything we could do through C#?
Thanks.
Excel.Range last = xlWS.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
Excel.Range RngToCopyOri = xlWS.get_Range("A1", last).EntireRow;
Excel.Range RngToCopy = RngToCopyOri.Resize[RngToCopyOri.Rows.Count + 1, RngToCopyOri.Columns.Count]; //because insert will add only 1 row, so the range would be one row larger
Excel.Range RngToInsert = xlWS.get_Range("A1", Type.Missing).EntireRow;
RngToInsert.Insert(Excel.XlInsertShiftDirection.xlShiftDown, RngToCopy.Copy(Type.Missing));
I tried to copy Range(A1,lowerleft cell) to its original location, but nothing changed.
I tried Range.resize, autofill, autoformat. All of them has sort of problems. I finally gave up using OLEDB to insert data. Instead, i used
worksheet.UsedRange.Item[rowNo,getColumnIndex(worksheet,columnTitle)]=value
private int getColumnIndex(Excel.Worksheet sheetname, string header) {
int index=0;
Excel.Range activeRange=sheetname.UsedRange;
for (int i = 1; i <= activeRange.Columns.Count; i++) {
if (header == (string)(activeRange.Item[1,i] as Excel.Range).Value) {
index = i;
}
}
if(index==0)
throw some exception you like;
return index;
}
The getColumnIndex function aims to locate the column in SELECT [column] from...
In this way, the format table will automatically expand to the range you input the value.
I have an Excel file with one column which is filled with numbers. I would like to be read the numbers from this column into an array in C#. How can I do that?
The easiest way is probably to use the Excel ODBC driver. This allows you to use OdbcConnection to read the worksheet into a DataTable. You can then iterate over the table's Rows collection, copying the values into a list or array.
You can use Excel Interop and do something along the lines of:
Excel.Range firstCell = excelWorksheet.get_Range("A1", Type.Missing);
Excel.Range lastCell = excelWorksheet.get_Range("A10", Type.Missing);
Excel.Range worksheetCells = excelWorksheet.get_Range(firstCell, lastCell);
var cellValues = worksheetCells.Value2;
You should get an array of objects (1-based index), and can cast the contents using (for instance) Convert.ToDouble().
SpreadsheetGear for .NET can do it. Below is some C# source. Note that the SpreadsheetGear API is similar to the Excel API, so the code below could be adapted to Excel.
using System;
using SpreadsheetGear;
namespace Program
{
class Program
{
static void Main(string[] args)
{
// Load a workbook from disk and get the first worksheet.
var workbook = SpreadsheetGear.Factory.GetWorkbook(#"C:\tmp\Numbers.xlsx");
// Allocate a list of doubles to store the number.
var numbers = new System.Collections.Generic.List<double>();
var worksheet = workbook.Worksheets[0];
// Assuming that column A is the column with the numbers...
var columnA = worksheet.Cells["A:A"];
var usedRange = worksheet.UsedRange;
// Limit the cells we look at to the used range of the sheet.
var numberCells = usedRange.Intersect(columnA);
// Get the numbers into the list.
foreach (IRange cell in numberCells)
{
object val = cell.Value;
if (val is double)
numbers.Add((double)val);
}
// Write the numbers to the console.
foreach (double number in numbers)
Console.WriteLine("number={0}", number);
}
}
}
You can download the free SpreadsheetGear trial here if you want to try it yourself.
Disclaimer: I own SpreadsheetGear LLC
In Excel VBA (or if you could in C#, I'm using the Excels Object Library from .NET), how to copy a worksheet from one workbook to another sheet in another workbook. Basically, what I'm doing is copying every of my sheet into a central worksheet in another workbook and then will do all the stuff I need to do there. I tried using Range.Copy method, I gave the Destination parameter as the range of the other workbook. It worked perfectly, but there is one problem, that is every time I copy it replaces the older data in that worksheet. How do I do something like so that when I paste it pastes in the end of the sheet.
EDIT: I searched and found a way, but now when I copy the cells I get a COM exception with the message "To paste all cells from an Excel worksheet into the current worksheet, you must paste into the first cell (A1 or R1C1)."
Following is the code, it is in C#
logWorksheet = logWorkbook.ActiveSheet as Excel.Worksheet;
Excel.Range tempRange = logWorksheet.Cells[logWorksheet.Rows.Count, "A"] as Excel.Range;
tempRange = tempRange.get_End(Excel.XlDirection.xlUp);
int emptyRow;
if (tempRange.Row > 1)
emptyRow = tempRange.Row + 1;
else
emptyRow = tempRange.Row;
string copyLocationAddress = Convert.ToString(emptyRow);
Excel.Range copyLocation = logWorksheet.get_Range(
"A" + copyLocationAddress, Type.Missing) as Excel.Range;
// copy whole workbook to the central workbook
tempLogSheet.Cells.Copy(copyLocation);
-- UPDATE --
This snippet copies the cells A1:A3 of Book1 to Book2. It will find the last used cell in Book2 and will append the data underneath it.
Sub CopyRange()
Dim source As Worksheet
Dim destination As Worksheet
Dim emptyRow As Long
Set source = Workbooks("Book1.xlsx").Sheets("Sheet1")
Set destination = Workbooks("Book2.xlsx").Sheets("Sheet1")
'find empty row (actually cell in Column A)'
emptyRow = destination.Cells(destination.Rows.Count, 1).End(xlUp).Row
If emptyRow > 1 Then
emptyRow = emptyRow + 1
End If
source.Range("A1:A3").Copy destination.Cells(emptyRow, 1)
End Sub
-- OLD --
This sample copies all the sheets of Book1.xlsx to Book2.xlsx:
Workbooks("Book1.xlsx").Worksheets.Copy Before:=Workbooks("Book2.xlsx").Sheets(1)