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.
Related
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've been trying to modify an Excel file called "Hoja de Resultados" adding three different variables each time (Puntuacion = Score, Fecha = Date, Hora = Time) inside of Visual Studio (C#). The excel sheet is linked to a DataGridView window which updates everytime the values are changed. The problem is, when there are less than 3 rows on the excel sheet, the program stops modifying the XLSX and sometimes it throws a seemingly random exception on "Program.cs".
string Direccion = "G:\\Archivos\\Programación\\Visual Basic\\UVG\\Microcontroladores - Proyecto Final Comunicación Serial\\Hoja de Resultados.xlsx";
Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook Hoja = ExcelApp.Workbooks.Open(Direccion);
Microsoft.Office.Interop.Excel.Worksheet HojaActiva = ExcelApp.ActiveSheet as Microsoft.Office.Interop.Excel.Worksheet;
Excel.Range Rango = HojaActiva.UsedRange;
int Posicion = Rango.Rows.Count;
int NuevaPosicion = Posicion + 1;
HojaActiva.Cells[NuevaPosicion, 1] = Puntuacion;
HojaActiva.Cells[NuevaPosicion, 2] = Fecha;
HojaActiva.Cells[NuevaPosicion, 3] = Hora;
Hoja.Saved = true;
ExcelApp.DisplayAlerts = false;
ExcelApp.ScreenUpdating = false;
ExcelApp.Visible = false;
ExcelApp.UserControl = false;
ExcelApp.Interactive = false;
Hoja.Close(true, Type.Missing, Type.Missing);
Marshal.ReleaseComObject(Hoja);
Marshal.ReleaseComObject(HojaActiva);
ExcelApp.Quit();
Sorry if it's partially in Spanish. But for some guidance:
Hoja = Workbook
HojaActiva = ActiveWorkbook
The reason that your Excel file is not updating is because you're not saving it anywhere in code. To solve your saving problem,
Change this line:
Hoja.Saved = true;
To
Hoja.Save();
When you write Hoja.Saved = true;, it tells Excel that there are no changes to be saved, whether that is the case or not, and that it can safely exit. Thus it does not actually save anything. You have to call the Save() method explicitly.
Another possible issue in your code is if the active range does not begin at the very top. The line int NuevaPosicion = Posicion + 1; assumes that your input starts on row one, which may not be the case. I would recommend changing that line to this:
//This way it doesn't matter where the range starts.
// Rows.Row returns the row on which the active range begins.
int NuevaPosicion = Posicion + Rango.Rows.Row;
Now new data will always be appended to the end of the sheet.
Other than the two points above, I cannot replicate your problem with less than 3 rows on the excel sheet, the code you posted seems to run with no issues under all conditions I could think of. Try making the change above and see if that solves your other issues. If not, please update your question to describe the seemingly random exception on "Program.cs" a bit more explicitly.
I use following code to copy one Excel sheet to a different workbook. The source Excel sheet contains chart with series in hidden rows. (theese series are hidden by code in c# before following code)
Worksheet w; //My source worksheet with chart
w.Activate();
w.Name = CreateValidWorksheetName(targetSheetName);
w.get_Range("a1").EntireRow.EntireColumn.Copy();
w.get_Range("a1").EntireRow.EntireColumn.PasteSpecial(XlPasteType.xlPasteValues);
w.Range["A1:A1"].Select();
if (targetWorkbook != null)
{
w.Copy(targetWorkbook.Sheets[1], Type.Missing);
targetWorkbook.RefreshAll();
}
....
targetWorkbook.SaveAs(...
Now the visible series are copied correctly, but hidden series are copied as external links, e.g.:
='C:\X[sourceWorkbook.xlsx]PDK 0-32 kv'!$D$23:$D$100
Now comes the problematic part. When I open the "targetWorkbook" I see the ugly chart including hidden series. But as soon as I open manually in Excel also the "sourceWorkbook", the charts gets automatically fixed and hidden series disapear.
How to achieve this programatically?
I have now lost several hours of my life working around this bug in Worksheet.Copy method. Sometimes I wonder why I was not worse student and I could be doing something more useful now...
First I tried:
//Break links
System.Array links = (System.Array) ((object)targetWorkbook.LinkSources(XlLink.xlExcelLinks));
if (links != null)
{
for (int i = 1; i <= links.Length; i++)
{
try
{
targetWorkbook.UpdateLink((string)links.GetValue(i),
XlLinkType.xlLinkTypeExcelLinks);
targetWorkbook.BreakLink((string)links.GetValue(i),
XlLinkType.xlLinkTypeExcelLinks);
}
catch (Exception ex)
{
Tools.LogException(ex, "targetWorkbook.BreakLink");
}
}
}
No success and I got even HRESULT error. It was not possible to delete external links even using visual interface of Excel, which probably only swallowed this exception.
Finally this did the trick:
w.Activate();
w.Name = CreateValidWorksheetName(targetSheetName);
w.get_Range("a1").EntireRow.EntireColumn.Copy();
w.get_Range("a1").EntireRow.EntireColumn.PasteSpecial(XlPasteType.xlPasteValues);
w.Range["A1:A1"].Select();
if (targetWorkbook != null)
{
//Unhide all rows and then copy!!!
w.get_Range("a1").EntireRow.EntireColumn.Hidden = false;
w.get_Range("a1").EntireColumn.EntireRow.Hidden = false;
w.Copy(targetWorkbook.Sheets[1], Type.Missing);
//Then hide all rows again
HideRows(true, targetWorkbook.Sheets[1].UsedRange, "***HIDETHISROW***");
HideRows(false, targetWorkbook.Sheets[1].UsedRange, "***HIDETHISCOL***");
It is also important to check that the filetypes of the source workbook the target workbook match (both are xlsx), otherwise you may get:
"Excel cannot insert the sheets into the destination workbook, because it contains fewer rows and columns than the source workbook. To move or copy the data to the destination workbook, you can select the data, and then use the Copy and Paste commands to insert it into the sheets of another workbook."
_ExcelApp.DefaultSaveFormat = Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook;
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());
}
}
}
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;
}