need custom validation (date + particular text) in excel sheet generated using C# - c#

I am looking to have a validation in an excel sheet which is generated using C# such that it allows either date value or the text "train" in the excel cell. I found XlDVType.xlValidateDate for validating date in a cell and XlDVType.xlValidateList to allow text values. But I want a combination of both, user should either be able to enter date or a particular text in the cell. Can this be accomplished using XlDVType.xlValidateCustom ??
any help on this would be greatly appreciated.

I want a combination of both, user should either be able to enter date
or a particular text in the cell.
The following code snippet sets the desired validation for cell A1 in your worksheet:
Excel.Range range = xlWorkSheet.Range["A1"];
range.ClearFormats();
range.Validation.Delete();
range.Validation.Add(Excel.XlDVType.xlValidateCustom,
Formula1: "=OR(EXACT(LEFT(CELL(\"format\",A1)),\"D\"),EXACT(A1,\"train\"))");
The most complicated part is the actual validation formula. It uses the following functions:
EXACT(cell,string) compares the contents of a cell with a literal string and returns TRUE only if they are exactly the same.
CELL("format",cell) returns a code containing the format of the indicated cell, where the code for a date always starts with a D. See Office help for CELL for an explanation and a list of all possible codes. This snippet only looks at the first character, which has to be a D in order for the contents to be formatted as some kind of date.
LEFT(text,count) returns the leftmost count characters in text, with count defaulting to 1. In this case, it returns TRUE if the contents are some kind of date.
OR(logical1, logical2) returns logical1 OR logical2, so TRUE if the contents are either a date, or exactly equal to the string "train".
This solution is not yet ideal, because A1 is hardcoded into the formula. There is a way around that using INDIRECT, described here. You might need that, for example if you want to apply the validation to a whole range of cells in one go. In that case, the hardcoded A1 needs to be replaced by INDIRECT("RC",FALSE), which is the mechanism to indicate the current shell. You can read it as a short-cut for INDIRECT("R"&ROW()&"C"&COLUMN(),FALSE).
With that adjustment, he last line of code then looks like this (tested in Excel, but not from C#):
range.Validation.Add(Excel.XlDVType.xlValidateCustom,
Formula1: "=OR(EXACT(LEFT(CELL(\"format\",INDIRECT(\"RC\",FALSE))),\"D\"),EXACT(INDIRECT(\"RC\",FALSE),\"train\"))"
Update
As the OP points out, there appears to be a problem with this approach if a date has first been entered into the cell, and then is changed to an incorrect string or number value -- see the comments below. Using the CELL function therefore does not seem to be the best approach.
However, if the cell format is explicitly set to the (more flexible) Text format, it is possible to impose the validation with the following lines:
range.Validation.Delete();
range.NumberFormat = "Text";
range.Validation.Add(Excel.XlDVType.xlValidateCustom,
Formula1: =OR(ISNUMBER(DATEVALUE(INDIRECT(\"RC\",FALSE))),EXACT(INDIRECT(\"RC\",FALSE),\"train\"));
Again tested in Excel, but not from C#.

Related

copy data from Excel cells without formatting c#

I have winform project in c# that I want to copy data from Excel cells to my datagirdview. But the excell cells is formatted with 2 digits after the comma.I want to get all value.
What i mean :
The excell cell value = 884,79258
Formatted value = 884,79
I am getting the data with Clipboard.GetText() method. Bu it gives me formatted value(884,79).
But i want the get all value which is 884,79258.
These are my codes
String[] lines = Clipboard.GetText().Split('\n');
string result = lines[0];
Thanx.
Edit:
Thanx to dr.nulll. The link that he shared is worked.
I am sharing the link below for those who have similar request.
Copying decimal values from Excel to C# causes to copy only displayed values
Don’t go via the clipboard. Either use Excel via interop or a 3rd party library like NPOI. If you must use the clipboard then the value copied reflects the current formatting of the cell, so you need it set to show 4 digits after the decimal point.

How to convert date and number format to text in excel so that when we query it using ODBC it returns the datafield as string

Problem--> Recently I completed an import program for which the input is excel.
To make the matter worse or good I assumed that every column of excel sheet will be of type string.
In excel we have some field that has MPN and partnumber. Internally the partnumber is stored as xx/xx/xxxx, which looks same as UK Date format.
The excel has made these column as number and data, which I never asked it to do.
If I query this sheet using odbc then I get .0 appended with MPN and part number I get as datetime.
To solve this problem I tried to paste the sheet in another blank sheet, I also tried to paste special (Values), but I am not able to paste it in text format. I even tried to paste it in note pad, but doing so is converting numbers in scientific notation.
My question: How can I change the type to text, without converting it to values.
Select the column, right click format cells and choose Text. But there would be a caveat there, since the internal format of dates is a number then you would get the underlying number as text I guess.
Saving as CSV would be a simple workaround.
Change the import-program in such a way that it casts all imported values to string? In Excel VBA it would look something like this:
Function importDateAsString(rng As Range)
importDateAsString = CStr(rng.Value)
End Function

Conditional Formatting Hides Text

I have an Excel worksheet which I'm adding conditional formatting to from an add-in written in C#.
The condition fires ok and I'm able to change the fill colour but the text always gets hidden.
If I remove the fill colour from the format, the text still gets hidden when the formatting is applied.
If I remove all the formatting and just apply the condition without any format changes, the text is still hidden.
When the format condition is no longer valid, the text appears as you would expect.
The cell value is definitely set correctly.
Why would this happen?
C# code as follows:
var disabledFormat = "IF(blah blah...),FALSE,TRUE)";
var formatCondition = (Excel.FormatCondition)cell.FormatConditions.Add(
Excel.XlFormatConditionType.xlExpression,
Type.Missing, disabledFormat);
formatCondition.Font.Color = ColorTranslator.FromHtml("#C0C0C0");
formatCondition.Interior.Color = ColorTranslator.FromHtml("#F0F0F0");
[Edit]
I have tried changing the colour to white, black, red etc. but it is still invisible when the conditional formatting applies.
[/Edit]
[Edit2]
Full disabledFormat string as requested:
(The code does not look exactly link this as it spans several classes, I've just tried to fill-in the blanks to be helpful :$)
const string FORMAT_DISABLED = "=IF(LEFT(MID('{2}'!{0},FIND(\"|\",'{2}'!{0},FIND(\"|\",'{2}'!{0})+1)+1,999),LEN(INDIRECT(\"'$lookup_grading'!\"&ADDRESS({1},1))))=INDIRECT(\"'$lookup_grading'!\"&ADDRESS({1},1)),FALSE,TRUE)";
var dropdownCell = "Q5";
var disabledFormat = string.Format(FORMAT_DISABLED, cellName, dropdownCell, controlSheetName);
Resolves to:
=IF(LEFT(MID('$controls_Distribution Grid'!W19,FIND("|",'$controls_Distribution Grid'!W19,FIND("|",'$controls_Distribution Grid'!W19)+1)+1,999),LEN(INDIRECT("'$lookup_grading'!"&ADDRESS(Q5,1))))=INDIRECT("'$lookup_grading'!"&ADDRESS(Q5,1)),FALSE,TRUE)
To try to clarify further, what this does is it looks up a value in a cell in another worksheet with the same address, grabs a value from a formatted string in that cell and compares it to the value indicated by the selected item in a dropdown. If there is a match TRUE is returned.
The same formula is also used to return 1 or 0 for the cell value so I know this works ok.
[/Edit2]
[Edit3]
I've narrowed the problem down to the NumberFormat, which is "a";;;.
When the conditional formatting does not trigger this correctly shows a (or a tick with Webdings applied).
But when the conditional formatting triggers the output from the NumberFormat does not appear.
I can't think why this would be intentional so I'm guessing this is a bug in Excel, but I'll do some Googling to check
[/Edit3]
This is the formula in the cell which returns a 1 or 0 (hope it's clear enough!):
=IF(
LEFT(
MID('$controls_Distribution Grid'!$V$19,
FIND("|",'$controls_Distribution Grid'!$V$19,
FIND("|",'$controls_Distribution Grid'!$V$19)+1
)+1,999),
LEN(INDIRECT("'$lookup_grading'!"&ADDRESS(Q5,1)))
)=INDIRECT("'$lookup_grading'!"&ADDRESS(Q5,1)),
1,0)
The definition of a number format is four fields separated by ;
<POSITIVE>;<NEGATIVE>;<ZERO>;<TEXT>
Your number format "a";;; means if the value is positive display a , if it's zero, negative or text display nothing.
Your formula returns TRUE or FALSE, which are treated as text, so when your condition fires, the format hides the cell value.
I suggest you change your formula to return 1 or 0 which will then display a or nothing
try using this
formatCondition.Font.ThemeColor = ColorTranslator.FromHtml("#909090");
formatCondition.Interior.ThemeColor = ColorTranslator.FromHtml("#F0F0F0");
formatCondition.Interior.PatternColorIndex = xlAutomatic;
I don't know if the PatternColorIndex is necessary or not, that is what I got from macro recording.
Edit:
this is the macro if that helps you:
With Selection.Font
.ThemeColor = xlThemeColorDark1
.TintAndShade = -0.499984740745262
End With
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorDark1
.TintAndShade = -0.149998474074526
.PatternTintAndShade = 0
End With
This sounds like it could be an error in the font file. Try a standard character A-Z to see it it disappears when formatted. If it doesn't disappear then you could have a corrupt font file. Might have to dump the wingdings font and re-install.

Insert Text to Word Range

I use interop.Word to create a Word document programmatically.
In the document I have a particular range which I would like to insert text to.
When I google it I see that the way to do this is :
range.Text=" Whatever...";
but I have no "Text" property for the range object.
Any ideas?
For the orignal question - this is just an intellisense bug, there is such property in the Range class.
For the problem from comments that
Range range=wordApp.ActiveDocument.TablesOfFigures[i].Range;
range.Text=" Whatever...";
replaces the ToF instead of prepending it with text. If you just want to set a header of the table, you can use Caption:
wordApp.ActiveDocument.TablesOfFigures[i].Caption = "Header text";
If however you need some text preceeding the ToF - check out this thread which is discussing similar case, but for the list instead of Table of Figures.
Another way to set caption is to select range you need and call InsertCaption:
wordApp.ActiveDocument.TablesOfFigures[i].Range.Select();
wordApp.Selection.InsertCaption("Whatever");
Note that InsertCaption accepts various args of various types, make sure to try different.
If you want to insert text at a range position, you can use Range.InsertBefore.
Range range=wordApp.ActiveDocument.TablesOfFigures[i].Range;
range.InsertBefore("My Text here. ");

Query excel spreadsheet for cell format.... (percentage)

I am using the .Net 4.0 and excel 2003
How can i use an oledb connection to retrieve the cell format of an excel spreadsheet... I specifically want to find out if a cell column (or cell itself) is in a numeric percentage format.
I cannot seem to find this information in the GetOleDbSchemaTable method.
EX: My web app reads numbers from an excel spreadsheet. This works fine; However, if the numbers are in a percentage format, excel displays it as (fraction*100) but the actual value is a fractional decimal (1/3 = .3333..) - Excel displays as 33.33% - (Notice the decimal point).
Therefore, i need a way of distinguishing between what is a percentage & what is not to allow my webapp to work properly...
Any ideas?
Thanks in advance.....
You might be able to get out this information with OleDbConnection.GetSchema, but I'm not sure what information you'll get for an Excel sheet with that. Documentation here.
Search the NumberFormat property of the Cell (Range) in question for a % sign.
Also, if you can get the format type, then you're looking for a format that starts with 'P', like 'P1'.
EDIT: The only way I can see is either using XML or Automation. For automation you need to use the Interop Assembly. Namespace: Microsoft.Office.Interop.Excel, Interface: DisplayFormat, Property: NumberFormat.
Can you just read the first row of data as a string and parse it looking for '%' in the string.

Categories