All,
Apologies if this is a very basic question and has been asked before, I predominately write in VBA / JAVA. However a project I am working on requires a C# script. Which carries out 3 simple steps:
Target a excel workbook which is already open. File path:
\Csdatg04\psproject\Robot\Peoplesoft To LV\Master Files - Do not use\Transactions into LV Template.xlsm
Populate cells A1,A2 & A3 with three variables already retrieved earlier in the automation.
Run a macro stored within the filepath mentioned above Macro name "ControlMacroACT"
The code I have developed is below, however in each stage identified above I am encountering errors (Probably basic errors).
Error 1: This line of code is to open a workbook I would like this to target an already active workbook.
Error 2: Worksheet not found
public void RunActualsMacro(string Filepath, string Period, String FiscalYear)
{
//~~> Define your Excel Objects
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkBook;
//~~> Start Excel and open the workbook.
//Error 1
xlWorkBook = xlApp.Workbooks.Open("\\Csdatg04\\psproject\\Robot\\Peoplesoft To LV\\Master Files - Do not use\\Transactions into LV Template.xlsm");
// Populat Cells A1,A2,A3 with string variables
// Error 2 Worksheet not found
worksheet.Rows.Cells[1, 1] = Filepath;
worksheet.Rows.Cells[2, 1] = Period;
worksheet.Rows.Cells[3, 1] = FiscalYear;
//~~> Run the macro ControlMacroAct
xlApp.Run("ControlMacroACT");
//~~> Clean-up: Close the workbook
xlWorkBook.Close(false);
//~~> Quit the Excel Application
xlApp.Quit();
}
Any help would be much appreciated.
You need to use Marshal.GetActiveObject, and this code is roughly right, but cannot test right now.
public void RunActualsMacro(string Filepath, string Period, String FiscalYear)
{
//~~> Define your Excel Objects
Excel.Application xlApp = null;
Excel.Workbook xlWorkBook;
//~~> Start Excel and open the workbook.
//handle errors below
try {
xlApp = (Excel.Application) System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
} catch {
//perhaps exit - or throw??
}
xlWorkBook = xlApp.Workbooks["Transactions into LV Template.xlsm"];
// Populat Cells A1,A2,A3 with string variables
Excel.Worksheet ws = xlWorkBook.Worksheets["Sheet1"] //what the tab name of sheet
ws.Cells[1, 1] = Filepath;
ws.Cells[2, 1] = Period;
ws.Cells[3, 1] = FiscalYear;
//~~> Run the macro ControlMacroAct
xlApp.Run("ControlMacroACT");
//~~> Clean-up: Close the workbook
xlWorkBook.Close(false);
//~~> Quit the Excel Application
xlApp.Quit();
}
Related
I have written a small code to copy few columns from source excel file to another excel file (destination excel file) using c#. Below is sample image of source excel file.
The expected result in destination excel file should be as shown in below image.
Below is my code
string fileTarget = #"C:\Users\sia\Desktop\Excel Automation\destination.xlsx";
string fileTemplate = #"C:\Users\sia\Desktop\Excel Automation\source.xlsx";
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wbTemp, wbTarget;
Microsoft.Office.Interop.Excel.Worksheet sh;
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wbSource = excel.Workbooks.Open(fileTemplate, ReadOnly: false);
Microsoft.Office.Interop.Excel.Worksheet WorksheetSource = wbSource.Sheets[1];
//Copy all range in this worksheet
WorksheetSource.UsedRange.Copy(Type.Missing);
//Open destination workbook
Microsoft.Office.Interop.Excel.Workbook wbDestination = excel.Workbooks.Open(fileTarget, ReadOnly: false);
Microsoft.Office.Interop.Excel.Worksheet WorksheetDestination = wbDestination.Sheets[1];
WorksheetDestination.UsedRange.PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteAll, Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, Type.Missing, Type.Missing);
wbDestination.SaveAs(#"C:\Users\sia\Desktop\Excel Automation\destination.xlsx");
wbSource.Close();
excel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
But the i'm not getting the expected format, below is the result I'm getting.
where and what modification i need to do in my existing code to get the expected result.
Thanks
You need to specify proper column and range, otherwise by default paste will go in the first column
workSheet.Range
For reference: Copy/paste cells in Excel with C#
I'm trying to edit an Excel Sheet through C# code but the Excel sheet is giving me an error saying read only
CS0200 Property or indexer 'Range.Text' cannot be assigned to -- it is read only
This is the code that is trying to access the sheet.
Code:
//Load workbook
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(#"S:\Utils\documents\ServerManager\serverlist.xlsx");
Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
Excel.Range xlRange = xlWorksheet.UsedRange;
xlWorksheet.Range["D2"].Text = "Kelly Cooper";
xlWorksheet.Range["D2"].Style.Font.FontName = "Arial Narrow";
xlWorksheet.Range["D2"].Style.Font.Color = Color.DarkBlue;
In the properties the Excel sheet is not read only and when I open it to edit it does not prompt me with the "This document is read only, want to enable editing." How can I go around this, Visual Studio won't let me compile because of it.
This is Excel in Office365.
You want to use .Value instead of .Text.
xlWorksheet.Range["D2"].Value = "Kelly Cooper";
xlWorksheet.Range["D2"].Style.Font.FontName = "Arial Narrow";
xlWorksheet.Range["D2"].Style.Font.Color = Color.DarkBlue;
If you check the documentation you can see that Text is read-only.
Also, if you check the documentation you can see that Value is not read-only.
EDIT
You also might have to change your Open parameters to:
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(Filename: "path/to/file", ReadOnly: false);
I am trying to read an excel sheet using C# and store each row into an array. I am able to open the file but the code I am using currently reads to an "2D-Object" array but I would like to read the info into 1D-string arrays.
static void Main(string[] args)
{
// Reference to Excel Application.
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(Path.GetFullPath("excelpractice1.xlsx"));
// Get the first worksheet.
Excel.Worksheet xlWorksheet = (Excel.Worksheet)xlWorkbook.Sheets.get_Item(1);
// Get the range of cells which has data.
Excel.Range xlRange = xlWorksheet.UsedRange;
// Get an object array of all of the cells in the worksheet with their values.
object[,] valueArray = (object[,])xlRange.get_Value(Excel.XlRangeValueDataType.xlRangeValueDefault);
// Close the Workbook.
xlWorkbook.Close(false);
// Relase COM Object by decrementing the reference count.
Marshal.ReleaseComObject(xlWorkbook);
// Close Excel application.
xlApp.Quit();
// Release COM object.
Marshal.FinalReleaseComObject(xlApp);
Console.ReadLine();
}
}
}
`
Sorry, I was trying to comment only. =X
But did it worked for you anyway? LinqToExcel is a great library for manipulate spreadsheets!
Please, let me know if has any doubt yet.
=)
I have a .txt file that is already in Comma-separated values (csv) format.
I want to add the data in the .txt file as a sheet to an open Excel workbook.
this is how I open the workbook:
var xlApp = new Excel.Application { Visible = false };
Excel.Workbook newWorkbook = xlApp.Workbooks.Add(Type.Missing);
And this is how I try to add the .txt file to the workbook:
string txt2xls = Globals.HomeDir + "\\JSL\\Data1" + ".txt";
string csv2xls = Globals.HomeDir + "\\JSL\\Data1" + ".csv";
if (File.Exists(csv2xls))
File.Delete(csv2xls);
File.Move(txt2xls, Path.ChangeExtension(txt2xls, ".csv"));
newWorkbook.Sheets.Add(csv2xls, Type.Missing, Type.Missing, Type.Missing);
The last line gave me an error (HRESULT: 0x800A03EC).
What can i do to solved this problem?
thanks!
CSV file in Excel can have allways only one worksheet. You cannot add another sheet as CSV. You will have to open the CSV separately as another Workbook and copy the Worksheet from that Workbook to your multi-sheet xlsx Workbook newWorkbook.
Use Worksheet.Copy method as described in How to: Programmatically Copy Worksheets and here.
var xlApp = new Excel.Application { Visible = false };
Excel.Workbook newWorkbook = xlApp.Workbooks.Add(Type.Missing);
Excel.Workbook csvWorkbook = xlApp.Workbooks.Open(csv2xls);
Excel.Worksheet worksheetCSV = ((Excel.Worksheet)csvWorkbook.Worksheets[1]);
Excel.Worksheet targetWorksheet = ((Excel.Worksheet)newWorkbook.Worksheets[1]);
worksheetCSV.Copy(targetWorksheet);
Also mark that
If you do not specify either Before or After, Microsoft Office Excel
creates a new workbook that contains the copied sheet.
So you can do
worksheetCSV.Copy(Type.Missing, Type.Missing);
and no need to explitly Add newWorkbook.
I have a problem with Excel worksheet. I am trying to create an Excel file with c#.
This code works and runs correctly on my computer but in other computers get an error at last line:
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheetInvoice;
Excel.Worksheet xlWorkSheetInvoiceLine;
object misValue = System.Reflection.Missing.Value;
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheetInvoice = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheetInvoiceLine = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(2);
System.Runtime.InteropServices.COMException (0x8002000B): Invalid index. (Exception from HRESULT: 0x8002000B (DISP_E_BADINDEX))
at Microsoft.Office.Interop.Excel.Sheets.get_Item(Object Index)
I executed a sample application with similar code on a machine with Excel 2013 and it fails at the same line of code you mentioned. By default Excel 2013 application opens up with a single worksheet ("Sheet1") so you would have to modify the code accordingly
DISP_E_BADINDEX seems to suggest the number of worksheets is less on the other computers. Build in a check to see if the number of worksheets is less than 2 before using get_Item().
i have created new sheet and assigned xlWorkSheetInvoice and xlWorkSheetInvoiceLine to solve it.
var xlSheets = xlWorkBook.Sheets as Excel.Sheets;
var xlNewSheet = (Excel.Worksheet)xlSheets.Add(xlSheets[1], Type.Missing, Type.Missing, Type.Missing);
var xlNewSheet2= (Excel.Worksheet)xlSheets.Add(xlSheets[2], Type.Missing, Type.Missing, Type.Missing);
xlWorkSheetInvoice = xlNewSheet;
xlWorkSheetInvoiceLine = xlNewSheet2;
xlWorkSheetInvoice = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheetInvoiceLine = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(2);