excel xml window width property - c#

This answer is strangely vacant from the internet, or my google-fu is getting rusty.
I'm making an excel file from C# via xml... When it loads up the worksheet width is pitifully small. Using <ss:WindowWidth>13395</ss:WindowWidth>
as prescribed by the internet does... nothing. (edit: tried this in excelworkbook and worksheetoptions, if that gives any idea to the problem) Tried with and without the ss: additions. Also, I cannot seem to find exactly why everyone uses values with this in and around the tens of thousands.
I'm thoroughly confused. If someone links a LMGTFY that answers this I'll eat my hat, because I damn well don't see it.
Silly excel. No one likes you.
Just for you L.
Figured windowWidth would give the jist of it.

I've seen some people add an ExcelWorkbook element to the 'Workbook' element. The ExcelWorkbook element has WindowWidth and WindowHeight elements.
Here is an example that lists (all?) of the child elements for the ExcelWorkbook element.
<Workbook>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>6795</WindowHeight>
<WindowWidth>8460</WindowWidth>
<WindowTopX>120</WindowTopX>
<WindowTopY>15</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
...
</Workbook>
EDIT
The WindowWidth element is an unsigned int that is specified in twips. Twips is defined as a twentieth of a point.
Twips Link
http://en.wikipedia.org/wiki/Twip

You can maximize the workbook programmatically via the COM interface. In VBA you would do something like this:
ActiveWindow.WindowState = xlMaximized
Maybe that helps.

Related

Setting chart gap width in EPPlus / Office Open Xml

How can I set the Gap Width value on a column/bar chart in EPPlus?
I have not found a built-in property for this and am expecting I will need to manipulate the chart's Xml, but I've been unable to find the Office Open Xml syntax for doing this.
This is supported in EPPLus.
For example:
var barChart = chart.PlotArea.ChartTypes[0] as ExcelBarChart;
barChart.GapWidth = 0;
I found the answer by creating what I wanted in a standard Excel sheet, and then looking at the underlying XML it had crated.
I set the Gap Width on an existing chart using the Excel, saved the workbook, renamed the file extension to .zip, and found the corresponding chart XML file within the Zip.
In this case I found the element <c:gapWidth val="15" /> at the following location in the chart's XML: c:chartSpace/c:chart/c:plotArea/c:barChart
I highly recommend this method for solving similar OOXML syntax queries, as the documentation I've seen so far is very dense and not easy to navigate, whereas learning by example in this way helped me find the answer in seconds.

Filter Range by specific Color Index/RGB using Worksheet.Range.Autofilter(Field,Criteria,Operator)

I am doing some automated excel manipulation using C#. I have been having a hard time figuring out how to autofilter based on a specific color.
There is very little documentation about this type of manipulation, however I have found some VB.net and VBA code for it. I cannot seem to convert the code to C# as "RGB" is not usable as it is in VB.net and VBA (See VB.net code below).
Since there has been no answers to this questions, I want to specify the code that needs to be looked at. In Autofilter(Field,Criteria,Operator), I need to know the C# Microsoft.Office.Interop.Excel criteria that would let me choose a color to filter.
Here is what my code looks like:
Excel.Worksheet xs1:
Excel.Range xRange1;
Excel.Range xRange2;
Excel.Range lastrow;
Excel.Range lastcol;
lastrow = xs1.Rows.End[Excel.XlDirection.xlDown];
lastcol = xs1.Columns.End[Excel.XlDirection.xlToRight];
xRange1 = xs1.Cells[2, 14];
xRange2 = xs1.Cells[lastrow.Row, 14];
Below selects the entire sheet and adds an autofilter(), setting it to filter for color. This works fine, but how do I pick the color I want it to filter for?
xs1.Range["A1", xs1.Cells[lastrow.Row, lastcol.Column]].
AutoFilter(14,Excel.XlColorIndex.xlColorIndexAutomatic,
Excel.XlAutoFilterOperator.xlFilterCellColor);
Here is an example of what the autofilter code would look like in VB.net. It looks very similar to this in an excel macro as well.
xs1.Range("A1", xs1.Cells(lastrow.Row, lastcol.Column)).
AutoFilter(Field:=14,Criteria1:=RGB(0,202,255),
Operator:=Excel.XlAutoFilterOperator.xlFilterCellColors)
So this is how you pick the color index for any poor souls that need to figure it out themselves. I could not find this anywhere on the internet.
xs1.Range["A1", xs1.Cells[lastrow.Row, lastcol.Column]].
AutoFilter(14, xlBook.Colors[33], Excel.XlAutoFilterOperator.xlFilterCellColor);
The important part is the "xlBook.Colors[33]". xlBook being the Workbook. 33 being the color index.
I don't have any reputation points, so I must submit an answer instead of a comment. Anyway, thank you, thank you, thank you. I have spent weeks looking for this answer and happened to search the right key words to find this post. I signed up just to upvote the answer!
My scenario is not exactly like yours, but similar enough that you led me to the solution. So, I will share what worked for me. I am trying to filter by color index using PowerShell. However, PowerShell does not allow the RGB values, as in the VB.net example above. Now, for my contribution to the answer. If you are doing this in PowerShell then it will need to look like this:
$xlFilterCellColor = 8
$xl = New-Object -comobject excel.application
$xl.Visible = $true
$xl.DisplayAlerts = $False
$wb = $xl.Workbooks.Open("\\path\to\file.xlsx")
$ws = $wb.worksheets.items(1)
$xlCellTypeLastCell = 11
$used = $ws.usedRange
$lastCell = $used.SpecialCells($xlCellTypeLastCell)
$range = $ws.range(A1:$lastCell)
$range.select | out-null
$range.autofilter(1,$wb.colors(6),$xlFilterCellColor)
The operator decimal values are listed here. In the code above, I am filtering yellow colored cells. Cell index colors and values can be found here.

Range.PastSpecial(...) is failing

I am using Interop.Excel for doing this task.
I am trying to copy a range of cells from one workbook's sheet and paste it into a separate workbook's sheet, but I want to keep the formatting from the source sheet and paste it into the destination sheet. I found the PasteSpecial, and tried to use that, but when I try it, I get an unhelpful exception message : "PastSpecial methos of Range class failed", which has an HResult of -2146827284. Could not find anything via google, so here I am to hopefully get some help...
I use the code below to try this. I also did try using Excel.XlPasteType.xlPasteAll as the initial parameter to the PastSpecial method, and that did actually Paste the data into the destination sheet, and so I thought great, this works, but when I looked closer, I could see, very fiently, what looked like extra gridlines, and when I clicked on the pasted data, it was a whole object which could be moved around, much like an image pasted in that can be moved. This of course is not what I wanted. The idea is that I need to preserve the formatting and the border styles and the colors used.
Many thanks for reading - apologies if my formatting in the post has messed up.
Excel.Range rng6 = sht6.Cells.get_Range("A1", "O55");
Excel.Range rng1 = sht.get_Range("A" + rowStart6.ToString(), "O" + rowEnd6.ToString());
rng6.Copy(mis);
/** Fails here at PasteSpecial**/
rng1.PasteSpecial(Excel.XlPasteType.xlPasteFormats, Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);

C# Interop Excel Range get_End is returning with 1 less element

I need to parse an Excel file. First I wrote an extension in Visual Basic inside the Excel file, all worked good. Now I need to port it to C# so it can be a separate application. While the functions I use are the same, the result is not the same...
When I choose from the GUI which Worksheet to parse, I do something like:
range = (workbook.Worksheets.get_Item(itemIndex) as Excel.Worksheet).UsedRange;
Then, for the first row I need to parse I do something like:
range.get_Range(range.Cells.get_Item(6, 2),
range.Cells.get_Offset(6,2).get_End(Excel.XlDirection.xlToRight)))
And I get the right result with all the fields I need.
The second time when I need to get another row, I do:
range.get_Range(range.Cells.get_Item(13, 3),
range.Cells.get_Offset(13, 3).get_End(Excel.XlDirection.xlToRight)))
This time it gives me all the elements except the last one. And I have more functions like this, some with XlDirection.xlDown and all of them return me the range without the last element.
I tried to swap the functions, thinking may be I need to release range and then acquire it again or something(wanted to check if it's always working only for the first function being executed) but it is always working only for the first example, whenever the function is being executed...
This is even stranger because it worked in VBA Excel.
I also tired with Excel.Application get_Range and Excel.Worksheet get_Range...
Anyone knows why this happens?
I managed to solve this strange behavior. It's not the correct way of getting out the data.
The correct way would be: range.get_Range(range.Cells[6, 2], (range.Cells[6, 2] as Excel.Range).get_End(Excel.XlDirection.xlToRight)) - for the first example.
Hope it helps somebody...

Excel xlXYScatter has lines when generated by C#

I'm using an app written in WPF C# to generate an Excel Worksheet and plot out some data.
xlXYScatterLines, xlXYScatterLinesNoMarkers, xlXYScatterSmooth, xlXYScatterSmoothNomarkers all worked out fine.
Except for xlXYScatter which always produces connects the data point with lines (= xlXYScatterLines), while it is supposed to display only scattered dots. Below is my code.
Excel.ChartObjects xlCharts = (Excel.ChartObjects)oSheet.ChartObjects(Type.Missing);
Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(350,20,500,350);
Excel.Chart chartPage = myChart.Chart;
chartPage.ChartType = Excel.XlChartType.xlXYScatter;
is this a bug?
[SOLUTION - not answer]
After two days of playing around, I accidentally found if I set the source data before defining chart type. The problem would not occur and xlXYScatter will show as xlXYScatter, not xlXYScatterLines.
chartPage.SetSourceData(Range, Missing.Value);
chartPage.ChartType = Excel.XlChartType.xlXYScatter;
I do not understand why and how this gets around the problem because it a intuitive to define the source after you define the chart, and in the opposite doesn't make much sense.
So I consider this as a solution, but not an answer. Hope someone can still answer the question.
I haven't done this in C#, but in VBA I had some similar grief. I ended up having to create the chart as xlXYScatterLinesNoMarkers. Then after the chart was created, I changed the type to xlXYScatter. Ugly, but it seemed to work for me in VBA.

Categories

Resources