I work on a macro vba which manipulate different dates.
I have an incomprehensive error with Decembre. For exemple
DateValue("11-NOV-14")
return : 11/11/2014
DateValue("11-DEC-14")
return an error type '13'
I already try to put the string into a var and pass it to DateValue but same results.
Maybe i can get around this problem but i want to know why i have this mystic error.
Thanks for your help.
Your is a system-dependent problem. The month of November passes well because, in French, November = Novembre so "11-NOV-14" is equal to the English version.
However, "Décembre" is different because it has an accent on the second letter. In fact, on a French system, this will be ok:
a = DateValue("11-DéC-14")
while this will be not:
a = DateValue("11-DEC-14")
To avoid this problem and make the code "language-independent" (without asking the user to change the date formatting from the Control Panel), I think you should add a function that translate dates from string to date values:
Function MyDateValue(ByVal myDate As String) As Date
myDay = Left(myDate,2)
myMonth = Right(Left(myDate,6),3)
Select Case myMonth
Case "JAN":
myMonth = 1
'etc.
End Select
myYear = Right(myDate,2)
MyDateValue = DateSerial(myYear,myMonth,myDay)
End Function
So, you will be able to use myDateValue rather than DateValue and will make sure that it will work with your input data whatever will be the system language.
Related
I'm trying to convert a four-digit numerical code to a four-digit (one letter + 3 numbers) with a CASE clause in Data Studio. The four-digit numerical code is being pulled out of a Sheets file. I keep getting an error that says "Invalid formula - Operator "=" doesn't support NUMBER = TEXT. Operator "=" supports ANY = ANY." I'm assuming the one letter is messing everything up. Any ideas of how to fix this?
Current formula:
CASE
WHEN store_identifier = '1234' THEN 'D111'
END
The error is pretty clear. The identify is a number, so drop the single quotes:
(CASE WHEN store_identifier = 1234 THEN 'D111' END)
I have some basic expressions to highlight certain fields:
=IIF(Fields!Failure.Value > 0, "Red", "Transparent")
However, I have another field that contains dates in the following format:
22/08/2016 22/08/2016 - each field can contain multiple dates.
This is stored in SQL as a VARCHAR.
I need to run a similar expression in my report to achieve the following:
If the date is 1 day older than the date the report is run, highlight the field. If the date is greater than 1 day older, highlight the field a different colour.
I#m familiar with basic expressions, but I can't think of an easy way to obtain the current date, and then compare between the two.
As others have said, you really shouldn't be using hacks like this...
But, this should work for you:
=iif(Len(Replace(Replace(Fields!DateField.Value," ",""), Format(Today, "dd/MM/yyyy"),"")) = 0, "Transparent" ,iif(Len(Replace(Replace(Replace(Fields!DateField.Value," ",""), Format(Today, "dd/MM/yyyy"),""), Format(Today().AddDays(-1), "dd/MM/yyyy"),"")) = 0, "Green", "Red"))
Essentially, remove the joining character (in this case, space) and then replace all instances of the current date in the given format. If there are any characters left, you have a date that doesn't match today. Then take that value and repeat for any instances of yesterday.
Obviously this will fall down if your date formatting changes.
But then you already knew that comparing dates as strings was a bad idea, right...
You can use the Split function to generate an array of values. Of course, you'll still need to select one of those to test. The following may get you going again.
=Iif(
CDate(
Split(
"21/08/2016, 22/08/2016",
","
).GetValue(0)
) < Today,
"True",
"False"
)
If, however, you are dealing with a date string that can contain any number of dates and you to test all of them then a simple SSRS expression won't handle that. Fortunately we can use a bit of custom code.
Right-click the report background and select report properties. Click the 'Code' item and paste the following into code box
Public Function TestDate(DateString As String) As String
Dim DatesArray() As String = Split(DateString)
Dim ReturnValue As String = "Transparent"
For Each d As String In DatesArray
If Date.Parse(d) = DateAdd(DateInterval.Day, -1, Date.Today) Then
ReturnValue = "Red"
End If
If Date.Parse(d) < DateAdd(DateInterval.Day, -1, Date.Today) Then
ReturnValue = "DarkRed"
End If
Next
Return ReturnValue
End Function
Now change the expression as below
=Code.TestDate("21/08/2016 22/08/2016")
I've used Date.Today in the VB to restrict the comparison of the date to the day. If you wanted to be more precise ie: the exact time, use Date.Now instead
I created a Table's Field, and in addition to this, I created my custom EDT, named : MyEDT (for example).
MyEDT is INTEGER type and I have extended the System standard EDT YearBase.
So, if I insert the alphabetic characters (look like "abecjskjfh") I get an error.
But I need to have a rule, I want to insert only value with 4 Number character, I only want values look like : 2000 , 2006, 1982 etc... .
I can check/control this by code, in methods validateWrite or validateField I insered this code :
switch (p1)
{
case fieldNum(MyTable, MyField) :
if (strLen( (strFmt("%1",this.MyField)) ) != 4)
throw error ("Inser only value AAAA");
break;
}
But,It's possible or exist to creato or axtends the YEAR EDT with only 4 number char length ? Or, there is another way to check the length the field valu ?
Thanks all,
enjoy!
If you want to use an integer EDT, I think there is no way to restrict the range of allowed numbers, except the AllowNegative property. So you have to do the validation in code like in your question. But I would suggest to change your validation logic to validate a number range instead of casting the number to a string and then validating the number of characters. This way you could also make sure that users cannot enter a year like 0000.
if (this.MyField< 1900 || this.MyField > 9999)
{
throw error("Please enter a year between 1900 and 9999");
}
Another possibility could be to use a date EDT where you set the DateYear, DateMonth and DateDay properties such that only the year is shown. This would also help with data entry (e.g. 2 gets replaced with 2002) and gives you a nice error dialog if the users enters for example "abc".
You can use X++ match function.
match('<:d:d:d:d>','2004') would match all 4 digit string (0000-9999).
match('<[12]:d:d:d>','2004') would match string 1000-2999.
Alternate way is to use System.Text.RegularExpressions.Regex.IsMatch('1234', '^\d{4}$')
I am using vb.net and I create a list of months (3 char representation) by using the following function.
Public Function getMonths() As Array
Dim months As String = ""
For i = 1 To 12
months += StrConv(MonthName(i, True), VbStrConv.ProperCase) + ","
Next
months = months.Substring(0, months.Length - 1)
getMonths = months.Split(",")
End Function
This works beautifully, as the site I am building can change language etc on the fly.
However when I try to then change the month back to the numeric value to process using this function
Public Function monthToNumber(ByVal monthin As String, ByVal culture As System.Globalization.CultureInfo) As Integer
monthToNumber = DateTime.ParseExact("01/" + monthin + "/1999", "dd/MMM/yyyy", culture).Month
End Function
, the date.ParseExact throws an exception of date input is not in a valid string.
The month is being produce by the culturalisation, so I can't understand the failure. This only happens with a culture of {pt-PT}. The process works fine for spain, uk, france,italy.
If you use DateTime.ParseExact, you have to use the right DateSeparator.
For pt-PT, it's not /, but -.
/ can work as default DateSeparator, but only if you use CultureInfo.InvariantCulture. But if you do, you can't parse the culture specific date abbreviation.
That's why your code fails.
To generate the month abbreviations, simple use DateTimeFormatInfo.AbbreviatedMonthNames or DateTimeFormatInfo.AbbreviatedMonthGenitiveNames; no need to write a method yourself.
Also, you should look into String.Join (another thing you don't have to reinvent).
For parsing the string back, you could use something like
monthToNumber = DateTime.ParseExact(monthin, "MMM", culture).Month
No need for day/year if you simply use MMM for your format string.
Hi in my program i am converting the dates in string for my application purposes. I want to compare those strings to see if the dates have the appropriate difference between them. Example date1 = "07/02/2015 12:12:000" and date2 = "08/02/2015 16:15:000". How can i compare for starters only the year value without parsing the string to date. Thanks in advance.
I have tried with .Length -something but with no luck at all.
Convert to DateTime objects and then use the normal arithmetic operations to compare them.
dim d1 = DateTime.Parse(input1); // Use ParseExact or more control
dim d2 = DateTime.Parse(input2);
If d1.Year != d2.Year Then
' years do not match
End If
' or even...
If (d1 - d2).Days > 365 Then
// more than a year apart (modulo leap years)
End If
Meta comment: I know you said "without parsing", but unless you have a really good reason (and tell us) and sensible answer will be to parse: because it is much easier and far easier to get right.