Enter code here .. I am trying to automate application through coded UI. I am stuck at this point:
Application has Table(ControlType : WinTable) and it is divided into 7 rows(ControlType : Row) like this:
FilePath : C:\test.txt
Printer Name : xyz
..
..
According to requirement, value of "FilePath" will take from excel sheet and same for "Printer name".
Here is the code:
WinWindow winP = new WinWindow();
winP.SearchProperties.Add(new PropertyExpression(WinWindow.PropertyNames.Name, "Create Print Job", PropertyExpressionOperator.Contains));
WinTable tbP = new WinTable(winP);
tbP.SearchProperties.Add(new PropertyExpression(WinTable.PropertyNames.Name, "Properties Window", PropertyExpressionOperator.Contains));
Excel.Workbook MyBook = null;
Excel.Application MyApp = null;
Excel.Worksheet MySheet = null;
MyApp = new Excel.Application();
MyApp.Visible = false;
MyBook = MyApp.Workbooks.Open("C:\\DEPCON\\DataInput.xlsx");
MySheet = (Excel.Worksheet)MyBook.Sheets[1];
Excel.Range range = MySheet.UsedRange;
for (int rCnt = 2; rCnt <= range.Rows.Count; rCnt++)
{
for (int cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
{
WinRow row = tbP.GetRow(0);
row.Value= (string)(range.Cells[rCnt, cCnt] as Excel.Range).Value2; // row.Value is showing read only.
}
}
I also tried string[] values = tbP.GetContent();. Can anyone tell me how to assign a value on Row from excel sheet, one-by-one? I also checked WinTable function. All functions are related to get a value. I do not know how to set(assign) a value.
Related
I am trying to export a datatable filled with numbers and letters with spacing before and after. I am using the below code to export - it works great. However, all columns are centered instead of being aligned to the left.
How do I adjust my below code to left-justify the excel sheet?
internal static void Export2Excel(DataTable dataTable, string RevisedFileName)
{
object misValue = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.Application _appExcel = null;
Microsoft.Office.Interop.Excel.Workbook _excelWorkbook = null;
Microsoft.Office.Interop.Excel.Worksheet _excelWorksheet = null;
try
{
// excel app object
_appExcel = new Microsoft.Office.Interop.Excel.Application();
// excel workbook object added to app
_excelWorkbook = _appExcel.Workbooks.Add(misValue);
_excelWorksheet = _appExcel.ActiveWorkbook.ActiveSheet as Microsoft.Office.Interop.Excel.Worksheet;
// Left align all cells - THIS DOES NOT WORK.
_excelWorksheet.get_Range("A1", "A1").Style.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
// column names row (range obj)
Microsoft.Office.Interop.Excel.Range _columnsNameRange;
_columnsNameRange = _excelWorksheet.get_Range("A1", misValue).get_Resize(1, dataTable.Columns.Count);
// column names array to be assigned to _columnNameRange
string[] _arrColumnNames = new string[dataTable.Columns.Count];
for (int i = 0; i < dataTable.Columns.Count; i++)
{
// array of column names
_arrColumnNames[i] = dataTable.Columns[i].ColumnName;
}
// assign array to column headers range, make 'em bold
_columnsNameRange.set_Value(misValue, _arrColumnNames);
_columnsNameRange.Font.Bold = true;
// populate data content row by row
for (int Idx = 0; Idx < dataTable.Rows.Count; Idx++)
{
_excelWorksheet.Range["A2"].Offset[Idx].Resize[1, dataTable.Columns.Count].Value =
dataTable.Rows[Idx].ItemArray;
}
// Autofit all Columns in the range
_columnsNameRange.Columns.EntireColumn.AutoFit();
_excelWorkbook.SaveAs(#Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/" + RevisedFileName + " Revised.xlsx");
_excelWorkbook.Close();
System.Runtime.InteropServices.Marshal.ReleaseComObject(_appExcel);
}
catch { throw; }
MessageBox.Show("Success! Revised file has been saved to Desktop!");
}
I would guess the line
_excelWorksheet.get_Range("A1", "A1").Style.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
ends with
....xlHAlignCenter
but should end something like
....xlHAlignLeft;
I am trying to use function COUNTIF at column B (CustomerName) in table "Products". But I get an error.
Can anyone help why I am getting error and how to fix it.
Thank you so much.
void Duplicate()
{
int ketqua = 1;
Double t;
GetActiveExcelFile();
Excel.Worksheet esh = oWB.Worksheets["Order detail"];
long lastRow;
lastRow = esh.Cells[esh.Rows.Count, 2].End(Excel.XlDirection.xlUp).Row;
Excel.Application a = new Excel.Application();
if (lastRow == 55)
for (int i = 2; i <= lastRow; i++)
{
Excel.Range objRange = (Excel.Range)esh.Cells[i, 2];
String strData = objRange.get_Value(System.Type.Missing).ToString(); //get the value cell[i,2]
if (strData != "")
{
t = a.WorksheetFunction.CountIf(esh.get_Range("B2","B55"), strData);
if (t > 1)
{
ketqua = 1;
break;
}
else
ketqua = 0;
}
}
}
Use always objects, or ranges in excel
//t = a.WorksheetFunction.CountIf(esh.get_Range("B2","B55"), strData);
t = a.WorksheetFunction.CountIf(esh.get_Range("B2","B55"), (Excel.Range)esh.Cells[i, 2]);
OS language vs numberformat
use the default numberformat on your system
I believe it is when you created a new Excel.Application. That's what my problem was. You are referencing an already declared worksheet varaible on a new application. I'm new to coding so hopefully that helps.
Building an application that reads a CSV file and converts it into xls with c# in VS 2017.
I'm using CsvHelper and Microsoft.Office.Interop.Excel to accomplish this.
The application can read a CSV file in a windows form, have the program set up a template and insert into that formatted template all the values in the correct cells HOWEVER the very first page created no matter which file is used is not formatted and gets inserted in a un-formatted excel page.
I have attempted:
changing the arguments of the "Workbook.Sheets.Add"
where in the logic the sheets get added
changing the arguments in the SaveAs function
Changing various indexes from 1 to 0 and visa versa
I am new to working with the (Interop.Excel) namespace and have spent much time reading the DOCS on the MS web-page yet I still cannot resolve this issue.
Here is how I am adding the pages to the workbook:
if (!backgroundWorker.CancellationPending)
{
backgroundWorker.ReportProgress(index++ * 100 / pageCount);
Thread.Sleep(delay);
wb.Sheets.Add(missing,After:wb.Sheets[wb.Sheets.Count],Count:missing,Type:template);
Worksheet ws = (Worksheet)wb.Sheets[wb.Sheets.Count];
}
Here is how I am saving the pages:
wb.SaveAs(fileName, XlFileFormat.xlWorkbookDefault, missing, missing, true, false, XlSaveAsAccessMode.xlNoChange,
XlSaveConflictResolution.xlLocalSessionChanges,
missing, missing);
excel.Quit();
Here is a reference to the whole method:
namespace csvReader
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
struct DataParameter
{
public List<material> materialList;
public List<material> smallMats;
public Workbook wbData;
public string Filename { get; set; }
public int Delay;
}
DataParameter _inputParameter;
private void btnWrite_Click(object sender, EventArgs e)
{
if (backgroundWorker.IsBusy)
return;
using (SaveFileDialog sfd = new SaveFileDialog() { Filter = "Excel Workbook|*.xls" })
{
if (sfd.ShowDialog() == DialogResult.OK)
{
_inputParameter.Filename = sfd.FileName;
_inputParameter.materialList = materialBindingSource2.DataSource as List<material>;
_inputParameter.Delay = 100;
progressBar.Minimum = 0;
progressBar.Value = 0;
backgroundWorker.RunWorkerAsync(_inputParameter);
}
}
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
object missing = Type.Missing;
List<material> list = ((DataParameter)e.Argument).materialList;
List<material> cellM = ((DataParameter)e.Argument).smallMats;
string fileName = ((DataParameter)e.Argument).Filename;
int pageCount = 1;
int process = list.Count;
int setRows = 19;
int delay = 100;
if (list.Count > setRows)
{
pageCount = process / setRows;
}
Microsoft.Office.Interop.Excel.Application excel = new
Microsoft.Office.Interop.Excel.Application();
string template = "(mytemplatefilepath)";
Workbook wb = ((DataParameter)e.Argument).wbData;
wb = excel.Workbooks.Add();
excel.Visible = false;
int index = 1;
try
{
for (int i = 1; i < pageCount; i++)
{
if (!backgroundWorker.CancellationPending)
{
backgroundWorker.ReportProgress(index++ * 100 / pageCount);
Thread.Sleep(delay);
wb.Sheets.Add(missing,After:wb.Sheets[wb.Sheets.Count],Count:missing,Type:template);
Worksheet ws = (Worksheet)wb.Sheets[wb.Sheets.Count];
}
}
int range = 1;
int sheetIndex = 1;
foreach (Worksheet w in wb.Sheets)
{
w.Name = "Sheet" + sheetIndex++;
//w.Cells["L", 3] = tbSpecial.Text;
cellM = list.GetRange(range, 19);
int startCell = 7;
foreach (material m in cellM)
{
if (!backgroundWorker.CancellationPending)
{
backgroundWorker.ReportProgress(index++ * 100 / process);
Thread.Sleep(delay);
Microsoft.Office.Interop.Excel.Range newInput = w.get_Range("C" + startCell, "L" + startCell) as Microsoft.Office.Interop.Excel.Range;
w.Cells[startCell, 2] = m.Qty.ToString();
w.Cells[startCell, 3] = m.Section.ToString();
w.Cells[startCell, 4] = m.Length.ToString();
w.Cells[startCell, 5] = m.Camber.ToString();
w.Cells[startCell, 6] = m.Ends.ToString();
w.Cells[startCell, 7] = m.Grade.ToString();
w.Cells[startCell, 8] = m.Seq.ToString();
w.Cells[startCell, 9] = m.Member.ToString();
//w.Cells["L", 3] ="700";
startCell++;
}
}
range = range + 19;
}
wb.SaveAs(fileName, XlFileFormat.xlWorkbookDefault, missing, missing, true, false, XlSaveAsAccessMode.xlNoChange,
XlSaveConflictResolution.xlLocalSessionChanges,
missing, missing);
excel.Quit();
}
catch (Exception ex)
{
backgroundWorker.CancelAsync();
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Here is the first page of a data set of 203 pages
https://imgur.com/t6dd2ip
and the other 202 pages appear as so
https://imgur.com/jMuNMeb
I feel like it's syntax error I'm making somewhere.
Although it is easy to fill in one excel page I'd rather have the program complete 100% of this work with the technologies I am using.
The reason the first sheet did not have the template layout and that if 'i = 0' bombs is that by default when instantiating a workbook with Workbooks.Add() a new Worksheet is added. This sheet will not be formatted however a template can be added in the parenthesis of the Add method to give that first sheet that format.
string template = "C:/whereEverMyTemplateIs/template"
wb = excel.Workbooks.Add(template);
Then just remember that it is added and make as many more as needed
for (int i = 1; i < pageCount; i++)
{
if (!backgroundWorker.CancellationPending)
{
backgroundWorker.ReportProgress(index++ * 100 / pageCount);
Thread.Sleep(delay);
wb.Sheets.Add(missing,After:wb.Sheets[wb.Sheets.Count],Count:missing,
Type:template);
//Worksheet ws = (Worksheet)wb.Sheets[wb.Sheets.Count];
}
}
I want to retrieve the background color of cell of excel using c# but I just can't find a way to do it
which library shall I use ? microsoft.office.tools.excel.workbook.aspx or microsoft.office.interop.excel ? what's the differents?
I have tried following code but get no luck:
using Excel = Microsoft.Office.Interop.Excel;
private void button1_Click(object sender, EventArgs e)
{
ofd.Filter = "xlsx|*.xlsx|xls|*.xls";
if(ofd.ShowDialog() == DialogResult.OK)
{
textBox2.Text = ofd.FileName;
Excel.Application excel = new Excel.Application();
Excel.Workbook wb = excel.Workbooks.Open(textBox2.Text);
Excel.Worksheet ws = wb.Sheets[1];
Excel.Range xlRange = ws.Cells[0, 0];
Debug.WriteLine("===" + xlRange.Interior.Color);
}
}
There is nice lib called EPPlus, that makes your relationships with excel much easier. You can find it on NuGet.
So use this code to get color:
var x = sheet.Cells[rowIndex, colIndex].Style.Fill.BackgroundColor;
And this to set color:
sheet.Cells[rowIndex, colIndex].Style.Fill.SetCellsColor( Color.Yellow );
Easiest solution what-so-ever :
private void Get_Colors()
{
Excel.Workbook excel = Globals.ThisAddIn.Application.ActiveWorkbook;
Excel.Worksheet sheet = null;
Excel.Range ran = sheet.UsedRange;
for (int x = 1; x <= ran.Rows.Count; x++)
{
for (int y = 1; y <= ran.Columns.Count; y++)
{
string CellColor = sheet.Cells[x, y].Interior.Color.ToString(); //Here I go double value which is converted to string.
if (sheet.Cells[x, y].Value != null && (CellColor == Color.Transparent.ToArgb().ToString() || **CellColor == Excel.XlRgbColor.rgbGold.GetHashCode().ToString()**))
{
sheet.Cells[x, y].Interior.Color = Color.Transparent;
}
}
}
}
Here's an answer that uses closed.xml. It's open-source and works with modern Excel sheets.
IXLWorkbook wb = new XLWorkbook("C:\File_path_to_excel_file"); // Replace with your file path
IXLWorksheet ws = wb.Worksheet("SheetName") // Put your sheet name here
int backgroundColor = ws.Cell(rowIndex, colIndex).Style.Fill.BackgroundColor.Color.ToArgb(); // Gives the Argb values for the cell's background. Replace rowIndex and colIndex with the index numbers of the cell you want to check
Typically an uncolored cell's Argb color is 16777215.
That's as simple as following:
using Excel = Microsoft.Office.Interop.Excel;
var cellColor = sheet.Cells[rowIndex, colIndex].Style.Fill.BackgroundColor;
I want to create docx files programatically. I need to include excel charts in it, and then I have to export it into pdf. I use C# 4.0 and Microsoft.Office.Interop for that.
The problem is that in the exported pdf files the 1/5 part of the charts are cut down.
Here is an example of the problem:
2shared.com link to the pdf file
This happens too if I try to save in xps.
If I copy and paste the excel chart in word, then it works somehow after that...
There is another problem too. The charts are randomly sized down. This depends on if the excel chart was visible during the scripting process or not (this picture is captured from word 2010, I circled the problem with red):
I create the excel charts as InlineShapes, with the AddOLEObject method, classtype: "Excel.Chart.8" . I set their size to 200x200 (wrdInlineShape.Width, wrdInlineShape.Height)
Adam said that I should include the source code. It is long, but here you go:
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
app.Visible = true;
Word.Document doc = app.Documents.Open(#"D:\programozás\OHV\template.docx");
string classtype = "Excel.Chart.8";
object oEndOfDoc = "\\endofdoc";
Bookmark titleBookMark = doc.Bookmarks.get_Item("title");
titleBookMark.Range.Text = "I love OHV";
for (int xi = 1; xi <= 2; xi++)
{
// Microsoft.Office.Interop.Word.Range wrdRng = doc.Bookmarks.get_Item(ref oEndOfDoc).Range;
Bookmark shapeBookMark = doc.Bookmarks.get_Item("shape" + xi );
Bookmark subtitleBookMark = doc.Bookmarks.get_Item("title" + xi);
subtitleBookMark.Range.Text = "Super Subject";
Word.InlineShape wrdInlineShape = doc.InlineShapes.AddOLEObject(classtype, Range: shapeBookMark.Range);
if (wrdInlineShape.OLEFormat.ProgID == classtype)
{
object verb = Word.WdOLEVerb.wdOLEVerbHide;
wrdInlineShape.OLEFormat.DoVerb(ref verb);
Random rn = new Random();
Excel.Workbook obook = (Excel.Workbook)wrdInlineShape.OLEFormat.Object;
Excel.Worksheet sheet = (Excel.Worksheet)obook.Worksheets["Sheet1"];
for (int i = 1; i <= 5; i++)
{
((Microsoft.Office.Interop.Excel.Range)sheet.Cells[i, 1]).Value = i + ".";
for (int c = 2; c <= 3; c++)
{
((Microsoft.Office.Interop.Excel.Range)sheet.Cells[i, c]).Value = rn.Next(1, 5);
((Microsoft.Office.Interop.Excel.Range)sheet.Cells[i, c]).Value = rn.Next(1, 5);
}
((Microsoft.Office.Interop.Excel.Range)sheet.Cells[i, 4]).Value = "";
}
wrdInlineShape.Width = 200;
wrdInlineShape.Height = 200;
Excel.Chart chart = obook.ActiveChart;
obook.ActiveChart.ApplyLayout(9, Excel.XlChartType.xlColumnClustered);
obook.ActiveChart.ChartTitle.Caption = "BMEVIHVA109 - Jelek és Rendszerek\n XY kurzus - Dr Erős Péter";
obook.ActiveChart.ChartTitle.Font.Size = 6;
chart.ChartArea.Fill.ForeColor.SchemeColor = 41;
Console.WriteLine(chart.ChartArea.Fill.ForeColor.RGB);
chart.ChartArea.Fill.BackColor.SchemeColor = 23;
Console.WriteLine(chart.ChartArea.Fill.BackColor.RGB);
chart.ChartArea.Fill.TwoColorGradient(Microsoft.Office.Core.MsoGradientStyle.msoGradientHorizontal, 1);
obook.ActiveChart.SetSourceData(sheet.get_Range("A1", "B5"));
obook.ActiveChart.Legend.Delete();
chart.ChartArea.RoundedCorners = true;
Excel.Axis axis = (Excel.Axis)chart.Axes(
Excel.XlAxisType.xlCategory,
Excel.XlAxisGroup.xlPrimary);
axis.HasTitle = true;
axis.AxisTitle.Text = "54 kérdőív";
axis.AxisTitle.Font.Size = 6;
axis.HasMajorGridlines = true;
axis = (Excel.Axis)chart.Axes(
Excel.XlAxisType.xlValue,
Excel.XlAxisGroup.xlPrimary);
axis.HasTitle = false;
axis.HasMajorGridlines = true;
axis.MaximumScale = 5;
axis.MinimumScale = 0;
wrdInlineShape.Width = 200;
wrdInlineShape.Height = 200;
Microsoft.Office.Interop.Word.Range tableRange = doc.Bookmarks.get_Item("table" + xi).Range;
// sheet.UsedRange.Copy();
doc.SetDefaultTableStyle("Light List - Accent 4", false);
Table table = doc.Tables.Add(tableRange, 3, 2);
Object style = "Table Grid 1";
table.set_Style(ref style);
table.Cell(1, 1).Merge(table.Cell(1, 2));
table.Cell(1, 1).Range.Text = "Válaszok száma";
table.Cell(1, 1).Range.Font.Bold = 2;
table.Cell(2, 1).Range.Text = "This works lol";
table.Cell(2, 2).Range.Text = "This works lol 2 2";
table.Cell(3, 1).Range.Text = "This works lol";
table.Cell(3, 2).Range.Text = "This works lol 2 2";
table.Cell(4, 1).Range.Text = "This works lol";
table.Cell(4, 2).Range.Text = "This works lol 2 2";
table.Borders.OutsideLineWidth = WdLineWidth.wdLineWidth225pt;
}
}
// doc.InlineShapes.AddPicture(#"D:\programozás\OHV\OHV\OHV\bin\Debug\Capture.JPG", false, true);
doc.SaveAs2(#"D:\programozás\OHV\Doksi.docx");
Console.WriteLine("Exit");
try
{
//Novacode.DocX docx = Novacode.DocX.Load(#"D:\programozás\OHV\Doksi.docx");
//docx.SaveAs(#"D:\programozás\OHV\Doksi.pdf");
doc.ExportAsFixedFormat(#"D:\programozás\OHV\Doksi.pdf",WdExportFormat.wdExportFormatPDF);
doc.Close();
app.Quit();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine();
}
I found a workaround for this.
I cut the excel chart I just made to the clipboard, then I paste it to the same place, then I wait for 2 seconds, and continue with the next chart.
The cut/paste seems to convert the chart to another type of word object, that is properly exported via pdf.
wrdInlineShape.Range.Cut();
shapeBookMark.Range.Paste();
Thread.Sleep(2000);
(shapeBookMark was the original range where I have put the chart. The 2 seconds wait is needed because otherwise Word freezes with an error message)