Mail merge replaces entire merge field and loses formatting - c#

I have an existing word document which has a formatted mail merge field({ MERGEFIELD Payment_Date \# "MMMM d,yyyy" }).
When I pass a string(say (01/01/2016)) from C# to do a mail merge the code field.Select() selects the entire merge field and replaces it with the string I am passing and I lose the formatting.
How can I prevent this?
foreach (Microsoft.Office.Interop.Word.Field field in document.Fields)
{
if (field.Code.Text.Contains("Payment_Date"))
{
DateTime pDate = new DateTime(2016, 12, 30);
field.Select();
application.Selection.TypeText(pDate.ToString());
}
}
This is the code that I am using to do the mail merge.

You either have to extract the format string from the field and transform it into something that lets you format your C# string correctly, or (simpler IMO) replace the field by one that retains the format string and let Word do the formatting for you.
For example, you might be able to replace it with
{ QUOTE "2016-12-30" \# "MMMM d,yyyy" }
(I would advise that you insert the date string in YYYY-MM-DD format, as I believe Word always interprets the day and month correctly in that case).
(NB, you can't just insert the text with { } - you have to insert a field. Then, if you just want the result, you can ensure the field has been Updated, then Unlink the field, just leaving the result).
One situation remains - what if the MERGEFIELD field has no date/time format switch? In that case you will need to impose a format (I do not think it will be possible to discover the document author's intent).

Related

String was not recognized as a valid DateTime from SQLite file

I have a program, that puts the .txt files to a database file (im using system.data.sqlite NuGET package). I have yyyy.MM.dd format set on my Pc, and it's used by the database too, however I still get the above mentioned error.
An additional info, that could help, is that when I set the table's appropriate column to a simple string it's working as normal, but as soon As I set it to date it gives me this exeption.
Can someone please help me?
You seem to be mixing up how a type is formatted into text with the type itself. If a column is typed as date, then its expecting a date, not a text conforming to whatever date format you have in mind.
Its the same is if you try to do the following:
DateTime date = "01.01.2020";
This won't compile, because string, nevermind if it represents a valid formatted date, and DateTime are two altogether different types.
If you are reading from a text file, you first need to convert the formatted string representations to their corresponding DateTime. See DateTime.TryParse method on how to do this. Once you have valid dates in your hands, try pushing those to the DB.

DateTime format - one digit day not recognized

I need to read a String in the following format: "6102015" (meaning October 6th, 2015) and turn it into DateTime objects.
I tried the following code, which did not work:
DateTime.ParseExact("6102015", "dMyyyy", CultureInfo.CurrentCulture);
But when I tested the code using the date string with an extra 0, it worked.
DateTime.ParseExact("06102015", "dMyyyy", CultureInfo.CurrentCulture); // works correctly
Is there a way to read this date format without having to add the 0?
I thank you in advance for any help.
Is there a way to read this date format without having to add the 0?
Adding a 0 is the least of your worries, IMO. That takes one line of code.
Assuming you've got a copy of the database or something you can alter, effectively, I would:
Create a field of a date/time type, or if you must use a string, do so but use an ISO-8601 format (yyyy-MM-dd)
Parse all the values which are already 8 characters
Parse all the values which are 6 characters by inserting two 0s (so abcccc becomes 0a0bcccc)
For each remaining value, of the form abcyyyy:
Try parsing it as 0abcyyyy
Try parsing it as ab0cyyyy
If only one parse worked, store that result in the new column
Now look at all the remaining rows (i.e. the ones you haven't populated with a "known good" value
You may be able to use other data (such as insertion order) to work out which is the "right" parse...
You may not - in which case you need to decide what to do

Is this c# code enough to handle globalization?

My C# winforms program will be used in following countries
United Kingdom : date format day-month-year , currency separator is '.'
United States : date format month-day-year , currency separator is '.'
Denmark : date format day-month-year , currency separator is ','
I want to make the program run properly irrespective of what regional settings are on users computer. My main concern is handling date format and currency fields
(Language translation is not a problem because the program will only show English text)
To do this I have decided that all dates in the database will be saved with yyyy-mm-dd format and all decimal fields will be saved with . as separator.
I created the database with Danish_Norwegian_CI_AS collation .
So I am assuming the data will be saved in the above datetime format & decimal format without me requiring to do anything special.
I have put the following code in my program
var cult = new CultureInfo("en-GB");
Thread.CurrentThread.CurrentCulture = cult;
Thread.CurrentThread.CurrentUICulture = cult;
CultureInfo.DefaultThreadCurrentCulture = cult;
CultureInfo.DefaultThreadCurrentUICulture = cult;
Please help me by telling from your experience if the above code is enough to make my program safe
Culture applies only in the following two scenarios:
Converting a string representation of a value to a native format, which is called "parsing".
Converting the native format of a value to a string representation, which is called "formatting".
When you store a datetime or a decimal or some other type into the database, it is stored in a native format. In a SQL database, this is usually some compact binary value that you will never work with directly.
Consider the following SQL:
declare #dt datetime
set #dt = '01/02/2015 12:34:56'
select #dt
In the first line, we declare a variable of type datetime. It's not a string, it's a specific data type that takes up 8 bytes of memory or disk.
In the second line, we assign a string value to the variable. SQL parses the string, converting it to a datetime so it can be stored in the #dt variable. The actual value stored has a hexadecimal representation of 0x0000A41400CF5940.
When it did the parsing, the current culture for the environment where the code was running was applied. Because I am in the USA, it interpreted the date as January 2nd. If I was in Europe, it would interpret the date as February 1st (changing the internal value to 0x0000A43200CF5940).
Using dates in yyyy-mm-dd format will avoid misinterpretation, but that does not mean that the actual value is stored as a string in that format. It's just that the format is unambiguous, so it will be parsed the same way regardless of culture.
In the third line of code above, we select the variable to include it in a result set. Though we are selecting it in its native form without any conversion, we ultimately see it in a string representation. If you are running the query in a tool such as SQL Server Management Studio, the output window will format the native values to strings so you can read them. When doing so, the current culture is again applied. SQL's default is to show dates in yyyy-mm-dd format, rather than the culture-specific format. But other values, such as decimals, will use the current culture's separator.
If instead of running this in SSMS you actually retrieved the results through your own code in a SqlDataReader (for example), then formatting never occurs. The reader maps SQL's binary native value directly to the appropriate .NET native type, using the mappings shown here. A SQL datetime gets natively mapped to a .NET DateTime.
DateTime dt = (DateTime) reader["dt"];
Now quite often, you see someone doing silly things like this:
DateTime dt = Convert.ToDateTime(reader["dt"].ToString());
This is wasteful because the value is already a DateTime, and this code would use the current culture to format the string, then use it again to parse the string. That's a lot of string manipulation for no reason whatsoever.
Ultimately, in your .NET code, you will end up using that DateTime value and converting it to a string somewhere for output. When you do, that's when you apply the current culture.
Likewise, when you receive an input string from your user (such as when filling out a form), you parse the value to a DateTime using the current culture again.
Native data types are not strings - and are thus not affected by culture.
Notes:
If you want to see the hexadecimal representation of the native binary form of any SQL data type, you can use something like: select convert(varbinary, #dt)
Be aware of whatever the native format is for anywhere you are working. If you're writing to an http stream, a text file, or a document database, etc., the string representation does indeed matter, because a string is the native format in those scenarios.
And just to prove this applies to more than dates, consider:
select 123, 123.45, convert(varbinary, 123), convert(varbinary, 123.45)
--results: 123 123.45 0x0000007B 0x0502000139300000

C# to Excel set custom date display and value

Given a certain date, I want to set the value of a cell with a DateTime object, but without the "Time" information. For example, for today the value would just be "29/06/2012" and not "29/06/2012 16:54:36".
Concerning the display, for today's date I want it to be written like this (it is in french, I don't know how it would be in english): "29 juin" and not "29/06/2012".
How can I achieve this?
EDIT : I just took a look at the display formatting I need in Excel, it is "jj mmmm" ("dd mmmm" in C#). But the cell, though taking the value, does not take the formatting. Here is a piece of code:
cell.Value = string.Format("{0:dd/MM/yyyy}", DateTime.Now);
cell.NumberFormat = "jj mmmm";
I also tried:
cell.Value = DateTime.Now;
cell.NumberFormat = "jj mmmm";
In that case, the display formatting is OK, but the cell value contains the Time information, which is not OK.
See this StackOverflow question, and my answer to it. It will allow you to set the custom format for the cell directly in the excel sheet, from there you just need to research what the different date format strings are.
That is only helpful if you are using excel automation though.
Otherwise, formatting the DateTime.ToString output will be better. Once again, researching the different DateStringFormatting options will be helpful to you.
Final option. Directly change the template, not using automation. Goto the cell and manually change the cell format until the display is what you want. This does not change the actual data, just its display.
UPDATE
There are two specific issues to deal with.
Issue one is making sure excel recognizes that this IS a date. To that end, make certain that the date data itself is formatted en-US. Why, because Microsoft is dumb, and doesn't recognize international date formats.
Issue two is the display format for the cell. For a 3 letter abbreviation of the month, use the string d mmm. If you want the full month name, use d-mmmm.
I was testing and noted that excel refused to treat 29/06/2012 16:54:36 as a date, but it accepted 06/29/2012 16:54:36 without an issue. As I said, microsoft is dumb.
just change DateTime.Now to DateTime.Date and the time will be zero'd out
DateTime has a method called ToShortDateString
// Displays Fri 29 Aug
Console.WriteLine(date1.ToString("ddd d MMM", CultureInfo.CreateSpecificCulture("fr-FR")));
This would be a good resource for you: msdn custom date and time format strings

SqlDatareader GetValue returning date value acording to system date format

Hi i am reading a value from a table using SqlDatareader, problem is it is always formatting the value acording to the machine date format settings.
for example the original date format in the source table is saved as
yyyy/mm/dd
when i use SqlDatareader.GetValue in a machine that has date set as MM/dd/YY
it is atutomatically converted to that format
is there anyway to retrive the date value with the original date formatting intact?
thanks
There is no "original date formatting", dates are kept internally as numbers, not strings.
Within a SQL query, you can choose the output formatting with
CONVERT(varchar(30), theColumn, nnn)
where "nnn" is one of the common date formats listed here: MSDN.
Personally I find that page confusing, so another (more useful) page is here: SQL Server Helper. From that page:
CONVERT(VARCHAR(20), GETDATE(), 100)
will return 'Jan 1 2005 1:29PM'
Probably not what you're looking for. But if you want to store the formatted date time, may be you should rather use VARCHAR or CHAR(N) as the field type. I would think the DATETIME field is to store datetime and the format it self isn't that important (or what it is meant for). However, you could reconvert it back to that format in C#.

Categories