I'm trying to move column B in front of column Q in an excel sheet as part of a report I'm working on. I have experience in VBA but relatively little in c# so I've spent the last hour on Google and can't find a solution, I feel like this should be simple but I can't quite get it.
Method one, which results in a “Insert method of Range class failed” msg.
Excel.Range rngCut1 = JobLabourSheet.get_Range("B:B", Type.Missing);
Excel.Range rngPaste1 = JobLabourSheet.get_Range("Q:Q", Type.Missing);
rngCut1.Columns.Cut(rngPaste1.EntireColumn.Insert(Excel.XlInsertShiftDirection.xlShiftToRight, rngCut1));
Method two results in a “Unable to get a Cut property of the Range class” msg.
Excel.Range rngCut1 = JobLabourSheet.get_Range("B:B", Type.Missing);
Excel.Range rngPaste1 = JobLabourSheet.get_Range("Q:Q", Type.Missing);
rngCut1.Columns.Cut(rngPaste1.EntireColumn.Insert(Excel.XlInsertShiftDirection.xlShiftToRight, Missing.Value));
In the second method when I omit the CopyOrigin I get the msg but it does insert a blank column in front of column Q.
In VBA I would use the following:
Columns("B:B").Cut
Columns("Q:Q").Insert Shift:=xlToRight
But like I said, my c# experience is limited at the moment so I have no idea how to go about translating it to c#
This isn't very intuitive, but this is how I got it to work. I took an "insert" range and used the Insert() method and passed a "range.Cut()" method as the "Copy Origin" parameter.
Reference docs:
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.insert.aspx
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.xlinsertshiftdirection.aspx
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.cut.aspx
Here is a sample app (be sure to add a reference to Microsoft.Office.Interop.Excel):
using System;
using System.Collections.Generic;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExcelCutAndInsertColumn
{
class Program
{
static void Main(string[] args)
{
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWb = xlApp.Workbooks.Open(#"C:\stackoverflow.xlsx");
Excel.Worksheet xlWs = (Excel.Worksheet)xlWb.Sheets[1]; // Sheet1
xlApp.Visible = true;
// cut column B and insert into A, shifting columns right
Excel.Range copyRange = xlWs.Range["B:B"];
Excel.Range insertRange = xlWs.Range["A:A"];
insertRange.Insert(Excel.XlInsertShiftDirection.xlShiftToRight, copyRange.Cut());
}
}
}
Related
I'm working on a program that allows the user to pull up part numbers from a database. The part numbers are then to be pasted into an active Excel Sheet.
I'm trying to do this with Excel interop Excel 16.0. I can copy the data but am having issues getting it to paste into excel.
private void cmdCopyToExcel_Click(object sender, EventArgs e)
{
string wb = cmb_BookName.Text.ToString();
string ws = cmb_SheetName.Text.ToString();
if (chkContainer.Checked)
{
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks[wb];
Excel.Worksheet xlWorksheet = xlWorkbook.Sheets[ws];
xlWorksheet.Cells[48, 4] = cboContainer.Text;
}
I'm able to get the open excel workbook and worksheet that I need, but when I try to paste it into excel all I get is a COM Exception. The exception occurs on line 10. I've tried using ("wb name") and ("ws name"), have also tried using index numbers [1] for workbook and [3] for worksheets but nothing works.
Can anyone see what I'm doing wrong or is there an easier way to copy from C# and paste into an excel cell?
Addition:I tried opening the workbook that I wanted to add test to, just to see if I could get it to work.
Here is the code:
private void button1_Click(object sender, EventArgs e)
{
try
{
//create a instance for the Excel object
Excel.Application oExcel = new Excel.Application();
//specify the file name where its actually exist
string filepath = #"K:\R&D Dept\Development Lab\R&D Test Request System (For testing and training)\Test Matrices\JRD Test Matrix for part numbers.xlsm";
//pass that to workbook object
Excel.Workbook WB = oExcel.Workbooks.Open(filepath);
// statement get the workbookname
string ExcelWorkbookname = WB.Name;
// statement get the worksheet count
int worksheetcount = WB.Worksheets.Count;
Excel.Worksheet wks = (Excel.Worksheet)WB.Worksheets[3];
// statement get the firstworksheetname
string firstworksheetname = wks.Name;
//statement get the first cell value
var firstcellvalue = ((Excel.Range)wks.Cells[48, 4]).Value;
}
catch (Exception ex)
{
string error = ex.Message;
}
}
}
}
This worked, so I guess my question becomes how to work with an Excel workbook and worksheet that are already open?
I would start by getting a range of cells: i.e.{Range test = {yourWorksheet}.Cells[RowNumber, ColumnNumber]}
Once you have that, you can set the value of that cell by calling the value, or value2 property like so: {test.Value or test.Value2 = {yourPastedData}}
I am currently facing when I want to change the color of my excel sheet.
With my code I am already inserting entries into my excel file. Some specific cells should receive a special color.
When I run my code, I always get the same error.
Analyzing the Google/Stackoverflow results, I did not find a solution, even though there have been some complaints about this.
Workbooks wbs = excel.Workbooks;
Workbook sheet = wbs.Open(fileName);
excel.DisplayAlerts = false;
Worksheet y = sheet.ActiveSheet;
y.Copy(y, Type.Missing);
int index = y.Index;
int addRow = 2;
Worksheet x = (Worksheet)excel.Worksheets[index];
//...
//this line throws the error
x.Cells[addRow++, 1].Interior.Color = System.Drawing.Color.Blue;
//...
I am using Microsoft Office Interop which was very useful and did its job...until now.
You have to use the XlRgbColor to implement Color (for Excel interop 14.0):
x.Cells[addRow++, 1].Interior.Color = XlRgbColor.xlBlue;
if you have older version : you have to use translator
x.Cells[addRow++, 1].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Silver
I want to avoid generated spreadsheets having empty/superfluous sheets named "Sheet1" and such. I thought I could do that by specifying how many sheets a workbook should have this way:
_xlApp = new Excel.Application { SheetsInNewWorkbook = 1 };
...But I'm still getting an unwanted "Sheet1" in addition to the sheet I create. Here is the pertinent code:
using Excel = Microsoft.Office.Interop.Excel;
. . .
private Excel.Application _xlApp;
private Excel.Workbook _xlBook;
private Excel.Sheets _xlSheets;
private Excel.Worksheet _xlSheet;
. . .
private void InitializeSheet()
{
_xlApp = new Excel.Application { SheetsInNewWorkbook = 1 };
_xlBook = _xlApp.Workbooks.Add(Type.Missing);
_xlBook.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
_xlSheets = _xlBook.Worksheets;
_xlSheet = (Excel.Worksheet)_xlSheets.Item[1];
_xlSheet.Name = String.Format("Price Compliance {0} {1}", _month, _year);
}
So since setting SheetsInNewWorkbook to 1 in the Excel.Application instance doesn't do the trick, what do I need to do to prevent these tramp sheets from showing up?
The answer to your question can be found in the documentation of the Template parameter on the Workbook.Add method.
[...] If this argument is omitted, Microsoft Excel creates a new
workbook with a number of blank sheets (the number of sheets is set by
the SheetsInNewWorkbook property).
Your code is omitting it, therefore it is creating a single Worksheet for you (since you've set SheetsInNewWorkbook to 1.
That property is also constrained to be between 1 and 255, so you aren't able to add a work book without a sheet (unless you use a file template).
Also from the Template parameter documentation:
If this argument is a constant, the new workbook contains a single
sheet of the specified
type. Can be one of the following Microsoft.Office.Interop.Excel.XlWBATemplate
constants: xlWBATChart, xlWBATExcel4IntlMacroSheet, xlWBATExcel4MacroSheet,
or xlWBATWorksheet.
So an alternative way to do this is:
_xlApp = new Excel.Application();
_xlBook = _xlApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
_xlSheets = _xlBook.Worksheets;
_xlSheet = (Excel.Worksheet)_xlSheets.Item[1];
_xlSheet.Name = String.Format("Price Compliance {0} {1}", _month, _year);
Which simply renames the single created sheet.
Hello I have been trying to use the PasteSpecial paste values on another sheet but every thing I've tried I keep receiving the same error.
PasteSpecial method of Range class failed
xl.Application xlApp = Globals.ThisWorkbook.Application;
xl.Workbook wb = xlApp.ActiveWorkbook;
xl.Worksheet data = wb.Sheets["Data"];
xl.Worksheet datasheet = wb.Sheets["DataSheet"];
xl.Worksheet pivot = wb.Sheets["Pivot"];
xl.Range dataRng = data.Range["A1:C" +
xlApp.WorksheetFunction.CountA(data.Range["A:A"])];
xl.Range pivotRng = pivot.Range["A1"];
addPivot ap = new addPivot();
ap.DataRange = dataRng;
ap.DestRng = pivotRng;
ap.PivotSheet = pivot;
ap.createPivot("FullName","Date");
pivot.PivotTables("PivotTable1").NullString = "0";
pivot.UsedRange.Copy();
datasheet.Range["A2:GT999"].ClearContents();
datasheet.Range["A2"].PasteSpecial(xl.XlPasteType.xlPasteValues,
xl.XlPasteSpecialOperation.xlPasteSpecialOperationNone,
System.Type.Missing, System.Type.Missing);
datasheet.Range["2:2"].ClearContents();
I have Tried
datasheet.Range["A2"].PasteSpecial(xl.XlPasteType.xlPasteValues
datasheet.Range["A2"].PasteSpecial(xl.XlPasteType.xlPasteValues,
xl.XlPasteSpecialOperation.xlPasteSpecialOperationNone)
and what you see above.
thanks!
Do the ClearContents before the Copy. Excel is removing your copied range (same as hitting ESC in the program) when you clear those cells out. Then you are trying to PasteSpecial but nothing is in the clipboard any longer.
//...code above
datasheet.Range["A2:GT999"].ClearContents();
pivot.UsedRange.Copy();
datasheet.Range["A2"].PasteSpecial(xl.XlPasteType.xlPasteValues,
xl.XlPasteSpecialOperation.xlPasteSpecialOperationNone,
System.Type.Missing, System.Type.Missing);
//code below...
If you are debugging this step-by-step, you would see the dashed border around the copied range disappear after the ClearContents call. Excel is a bit odd (but predictable) about when the copied range is forgotten. Editing cells anywhere in the Workbook is one sure way to make it forget.
we are trying to retrieve a calculated value from a cell which has add-In formulas in it.
The sample add-in "myUtilityl.xla" is working properly in excel. It retrieves value for the addin function =ISOWEEKNUM(F9). But we are unable to retrieve the value programatically using C# & Microsoft Object Library. The add-In "myUtilityl.xla" is attached to Excel. Environment is VS2010
I am providing the sample code here.
string path = #"C:\Test.xls";
Workbook theWorkbook;
Worksheet theWorksheet;
Range readRange;
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
theWorkbook = app.Workbooks.Open(path);
Sheets theSheets = (Sheets)theWorkbook.Worksheets;
theWorksheet = (Worksheet)theWorkbook.Worksheets.get_Item("Sheet1");
readRange = theWorksheet.get_Range("B1");
MessageBox.Show(Convert.ToString(readRange.Value));
//theWorkbook.Save();
app.Workbooks.Close();
I am new to Microsoft Object library. Any help or clue will be very helpful.
Well Brijesh its working now. The only thing that was missing was that we have to open the xla.
app.Workbooks.Open(xlaFilePath);
Then it started working..
Thank you very much. i am posting the code here anyways
string path = #"C:\Test2.xls";
string xlaPath = #"C:\Test2.xla";
Workbook theWorkbook;
Worksheet theWorksheet, theWorksheet2;
Range readRange;
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
app.Workbooks.Open(xlaPath);
theWorkbook = app.Workbooks.Open(path);
theWorksheet2 = (Worksheet)theWorkbook.Worksheets.get_Item("Sheet2");
theWorksheet2.get_Range("A3").Value = 7;
theWorksheet2.get_Range("A4").Value = 7;
theWorkbook.RefreshAll();
theWorksheet = (Worksheet)theWorkbook.Worksheets.get_Item("Sheet1");
readRange = theWorksheet.get_Range("A1");
Console.WriteLine(Convert.ToString(readRange.Value));
Console.ReadLine(); //theWorkbook.Save();
theWorkbook.Close();
app.Workbooks.Close();
Above code inputs two values into cells of sheet2 and the VBA UDF calculated value is retrieved.
you may add following in your code sample
var addins = Application.AddIns.Add(xlaFilePath);
if (!addins.Installed)
{
addins.Installed = true;
}