Can someone please guide which one of the below is the correct Data Annotation, if I want to allow just alphabets:
[RegularExpression(#"[a-zA-Z]*", ErrorMessage = "Invalid {0}")]
OR
[RegularExpression(#"^[a-zA-Z]*", ErrorMessage = "Invalid {0}")]
Both seems to be working. The difference is ^ symbol.
^ Caret is a Position Anchor.
Position Anchors does not match character, but position such as start-of-line, end-of-line, start-of-word and end-of-word.
In this case you need both ^ and $: start-of-line and end-of-line respectively. E.g., ^[0-9]$ matches a numeric string.
So you should go with,
[RegularExpression(#"^[a-zA-Z]*$", ErrorMessage = "Invalid {0}")]
Becase you need strings starts and ends with alphabetical characters only, not having any other characters such as symbols or numerals. Here are some examples that you can play with.
let str1 = 'abcDef';
let str2 = '123abcDef';
let str3 = 'abcDef123';
let str4 = 'abc123Def';
let my_regex = /^[a-zA-Z]*$/;
let your_regex = /[a-zA-Z]*/;
alert(str1 + " : " + my_regex.test(str1) + " with my regex");
alert(str2 + " : " + my_regex.test(str2) + " with my regex");
alert(str3 + " : " + my_regex.test(str3) + " with my regex");
alert(str4 + " : " + my_regex.test(str4) + " with my regex");
alert(str1 + " : " + your_regex.test(str1) + " with your regex");
alert(str2 + " : " + your_regex.test(str2) + " with your regex");
alert(str3 + " : " + your_regex.test(str3) + " with your regex");
alert(str4 + " : " + your_regex.test(str4) + " with your regex");
The Caret (^) character is also referred to by the following terms:
Terminology
hat, control, uparrow, chevron, circumflex accent
Usage
It has two uses in regular expressions:
To denote the start of the line
If used immediately after a square bracket ([^) it acts to negate the set of allowed characters (i.e. [123] means the character 1, 2, or 3 is allowed, whilst the statement [^123] means any character other than 1, 2, or 3 is allowed.
Character Escaping
To express a caret without special meaning, it should be escaped by preceding it with a backslash; i.e. ^.
You can find it here...
I think you want something more like this:
[RegularExpression(#"^[a-zA-Z]+$", ErrorMessage = "Invalid {0}")]
which says to match
the beginning of the string ^
followed by 1 or more alphabetic characters [a-zA-Z]+ (you do need more than zero right)?
followed by the end of the string $
This doesn't allow other strings to match such as 123abc or abc123 because the anchors of ^ and $ prevent that.
In your first example, the match would allow an empty string, and would allow for the cases I mentioned in the paragraph above. Your second example would allow empty string, but would at least filter out 123abc but would still allow abc123 because you don't have the $ marker.
If you want to take my solution and extend it beyond ASCII alphabetic characters, you can change [a-ZA-Z]+ to \p{L}+, which should work universally in Unicode (but that seems like it might be more than you're looking for; just including for completeness).
Finally, [RegularExpression] uses the standard regex capability that has been part of .NET for quite some time, expressed in the Regular Expression Language - Quick Reference.
Related
Im trying to make a app for cafe. It has a simple interface coffee names with labels and quantity with numericupdown, receipt textbox and receipt button. I coded receipt button to show coffee name and quantity in receipt textbox like this:
If (espresso.Value > 0) Then receipt.AppendText("Espresso" + vbTab + vbTab + espresso.Value.ToString + Environment.NewLine)
that works fine but i want to add the price next to quantity of the coffee so i added these lines :
Dim espressoprice As Double
espressoprice = 3
Dim espressoquantity As Double = Convert.ToDouble(espresso.Value)
Dim espressototal As Double
espressototal = (espressoprice * espressoquantity)
(espresso.value is numericupdown value)
and changed the first codeline like this:
If (espresso.Value > 0) Then receipt.AppendText("Espresso" + vbTab + vbTab + espresso.Value.ToString + vbTab + espressototal + Environment.NewLine)
but i keep getting this error:
"Espresso 2 " "Conversion from string "" to type 'Double' is not valid."
What am i doing wrong please help.
The proper solution to this problem is to use the correct operator. You are trying to perform string concatenation but you are using the addition operator. This:
"Espresso" + vbTab + vbTab + espresso.Value.ToString + vbTab + espressototal + Environment.NewLine
is actually performing multiple additions. Addition maps to concatenation for two Strings but for numbers, addition is mathematical, NOT textual. In order to add a String and a numeric value, the system has to implicitly convert one of them to the other type. You are obviously assuming that the number will be converted to a String but it's actually the opposite that is happening, i.e. the system is trying to convert a String to a number and it is failing. This is why you should not rely on implicit conversions. If you used the concatenation operator, as you should when performing concatenation, then there's only one way it can go:
"Espresso" & vbTab & vbTab & espresso.Value.ToString & vbTab & espressototal & Environment.NewLine
Notice that, in this case, you don't have to explicitly convert the number to a String because the concatenation operator is defined for Strings and numeric values. Concatenation is a String operation so you know for a fact that everything that can be treated as a String, will be.
That said, there are better options anyway, e.g.
receipt.AppendText(String.Concat("Espresso", vbTab, vbTab, espresso.Value, vbTab, espressototal, Environment.NewLine)
In your line where you added expressototal you need to convert its value to a string in order to add it to other strings, that is, expressototal.ToString.
I m wondering, does Xpath use ' or " for the value ?
I have this web element that I want to grab
<div class="has-error ng-scope ng-hide" ng-show="element['ServerValidationFailed']">Sorry, that isn't a valid number.</div>
Normally Xpath should have this pattern Xpath=//tagname[#attribute='value']
But when I tried using ' to surround the value like these
//div[#ng-show='element['ServerValidationFailed']'] and
//div[text()='Sorry, that isn't a valid number.'] ,
these don't work (Google Chrome Developer Tool won't find the web element).
When I tried " for the value like these
//div[#ng-show="element['ServerValidationFailed']"] and
//div[text()="Sorry, that isn't a valid number."]
It works fine (Chrome Developer tool will find a match).
I am a bit confused now, should it be single quote ' or double quote " ?
Either one works fine. It comes down to the content you want to match against.
Examples shown in w3.org xpath abbreviated syntax suggests double quotes (").
The reason is because you can escape " with \" but you cannot escape ' with \'.
If the value you want to match contains ' character, you should use " to wrap the value.
//div[#ng-show="element['ServerValidationFailed']"]
If the value you want to match contains " but not ', you can use ' to wrap the value.
//div[#ng-show='element["ServerValidationFailed"]']
If the value you want to match contains both " & ', you have to use " to wrap the value and escape your " in your value with \".
//div[#ng-show="element['ServerValidationFailed']==\"0\""]
This will match something like
<div ng-show="element['ServerValidationFailed']=="0""></div>
Not saying you should do this but just in case if you need it.
The xpath supports both single and double quotes for defining the attributes, but in case of single quote escaping it doesn't follow the general programming concept. So in case of single quote escaping always put attribute value in double quotes .
Please have a look:: https://github.com/xmlunit/xmlunit/issues/110
This is what i use for this specific condition of single and/or double quotes.
Try this and check with the text you need to verify.
if (!TextString.contains("'")) {
XPath = "//*[contains(text(), \"" + TextString + "\")]" + " | " + "//*[contains(normalize-space(), \"" + TextString + "\")]";
} else if (!Label.contains("\"")) {
XPath = "//*[contains(text(), '" + TextString + "')]" + " | " + "//*[contains(normalize-space(), '" + TextString + "')]";
} else {
XPath = "//*[contains(text()," + "concat('" + TextString.replace("'", "',\"'\",'") + "'))]" + " | " + "//*[contains(normalize-space()," + "concat('" + TextString.replace("'", "',\"'\",'") + "'))]";
}
I want to use double quotations in the URL of my VB software, tried nearly everything but nothing works. Any suggestions?
For example, I want my program to search on for "Powered by BlogEngine.NET" but instead it searches without quotations like Powered by BlogEngine.NET
Dork = " ""Powered by BlogEngine.NET"""
Searchterm = FlatTextBox1.Text
Input = FlatTextBox1.Text
System.Diagnostics.Process.Start("http://www.google.com/search?q=" + Dork + " " + Searchterm + " " + TLD + "&tbs=qdr:" + UDate + "&num=" + Numbers)
I see you have this working now but a better approach (also mentioned by #halfer) would be to build the url string then use HttpUtility.URLEncode to properly convert the quotes and any other characters.
I wrote a custom function that parses an HL7 interface message. These are messages sent between healthcare information systems, but basically it's just a long text string, delimited with various characters to indicate different fields, that I paste into a cell in Excel. The function I created searches and counts to find the fields specified in the arguments.
DISCLAIMER: I am new to VBA. I've been teaching myself via online research and trial-and-error over the past 3-4 weeks, so I'm no VBA expert. I'd prefer NOT to use arrays because when I tried that, the code got too complex for me to troubleshoot. So, I'm OK with the code being easy-to-follow, as opposed to being the fastest/most-efficient.
Anyhow, I've got it working pretty well to do what I want, but I'm stuck on adding in logic for an OPTIONAL argument.
So, this is how I WANT it to work:
Formula =KWHL7(A1, "MSH", 8)
NOTE only 3 arguments
Result I Want ADT^A08
Result I Get ADT
NOTE I know I told it to stop at the next instance of "HL7_SUBFIELD_DELIMITER" which is " ^ "
Formula =KWHL7(A1, "MSH", 8,1)
NOTE the optional 4th argument
Result I Want ADT
Formula =KWHL7(A1, "MSH", 8,2)
NOTE the optional 4th argument
Result I Want A08
The contents "value" of cell A1:
<11>MSH|^~\&|OPS|384|RISIC|384|20160923093012||ADT^A08|Q1230569238T1410271390|P|2.3|||*PM_ALLERGY*|||8859/1<13>
EVN||20160923<13>
PID|1||000000808^^^SCH MRN^MRN^SC||ZZTEST^LEANN||20160706|F|||459 CORPORATION ST.^^BEAVER^PA^15009^USA||(724)775-7418^PRN|||S||000000008082^^^SCH Account Number^FIN NBR|||||||0<13>
PV1|1|I|SCH Periop^^^^^^||||08888^Bullian^Leann~08888^Naylor^Daniel|||10|||||||08888^Nguyen-potter^Rose~00187^TEST^STCHRISRES^L^MD^^MD^^SCH Doc Number|1|1287593^^^TEMP FIN^VISITID||||||||||||||||||||384||A|||20160707131900<13>
PV2|||PA^<13>
OBX|1||Dosing Weight^WEIGHT||5|kg<13>
OBX|2||Height^HEIGHT||25|cm<13>
AL1|1|Drug|d00308^morphine^Multum Drug||66382015<13>
ZAL|||16655315|16655315||Active|66382015^Anaphylaxis^673967||||20160923093008|^Naylor^Daniel|0<13>
AL1|3|Drug|d00012^codeine^Multum Drug||103576018<13>
ZAL|||16655323|16655307||Active|103576018^Diarrhea^673967||||20160923093008|^Naylor^Daniel|0<13>
<28><13>
My VBA code (sorry for all the comments, I'm just learning!):
Public Function KWHL7(KW_Cell_With_HL7_Message As Variant, KW_HL7_Segment_Name As String, KW_HL7_Field_Number As Integer)
'KW_Cell_With_HL7_Message = KW_Cell_With_HL7_Message.Value
'KW_Cell_With_HL7_Message = ActiveCell.Value
'KW_HL7_Segment_Name = "PID"
'KW_HL7_Field_Number = 18
Const HL7_SEGMENT_DELIMITER = vbLf 'using "<13>" did not work due to carriage return
Const HL7_FIELD_DELIMITER = "|" ' Pipe means next field
Const HL7_SUBFIELD_DELIMITER = "^"
'Various carriage returns and line breaks: vbLf, vbCr, vbCrLf, vbNewLine, Chr(10), Chr(13)
KWSegmentStringToSearchFor = HL7_SEGMENT_DELIMITER & KW_HL7_Segment_Name 'Using the segment delimiter ("<13>" or "vbLf" / carriage return) before segment name implies that the segment / line STARTS with this text
KWSegmentCharacterPosition = InStr(1, KW_Cell_With_HL7_Message, KWSegmentStringToSearchFor)
'** FOR TESTING ** MsgBox ("Segment Character Position: " & KWSegmentCharacterPosition & ", 5 Characters starting there = " & Mid(KW_Cell_With_HL7_Message, KWSegmentCharacterPosition, 5))
'Now we have the character position of the start of the proper SEGMENT / line
'Now we have to find the Proper Field in that segment
'So we'll use this position + the length of the end of the Segment Delimiter as the start
'***WARNING***: Still must add logic to make sure we stop if we encounter another Segment Delimiter
KWFieldCharacterPosition = KWSegmentCharacterPosition + Len(HL7_SEGMENT_DELIMITER) 'instead of starting at character 0, start at the beginning of the segment found previously
' ** FOR TESTING ** MsgBox ("Length of Segment Delimiter = " & Len(HL7_SEGMENT_DELIMITER))
' ** FOR TESTING ** MsgBox ("Field Character Position: " & KWFieldCharacterPosition & ", 5 Characters starting there = " & Mid(KW_Cell_With_HL7_Message, KWFieldCharacterPosition, 5))
For J = 1 To KW_HL7_Field_Number
KWFieldCharacterPosition = InStr(KWFieldCharacterPosition + 1, KW_Cell_With_HL7_Message, HL7_FIELD_DELIMITER)
If KWFieldCharacterPosition = 0 Then Exit For
Next
' ** FOR TESTING ** MsgBox ("Field Character Position: " & KWFieldCharacterPosition & ", 5 Characters starting there = " & Mid(KW_Cell_With_HL7_Message, KWFieldCharacterPosition, 5))
'Determine the number of characters to return after the start position
'Want to pull text UNTIL the next Segment Delimiter or Field Delimiter or Subfield Delimiter
'Find the position of the next Segment Delimiter or Field Delimiter or Subfield Delimiter
'Since the InStr function does not accept multiple substrings to search for, and does not allow OR statements inside...
Next_HL7_Segment_Delimiter = InStr(KWFieldCharacterPosition + 1, KW_Cell_With_HL7_Message, HL7_SEGMENT_DELIMITER)
Next_HL7_Field_Delimiter = InStr(KWFieldCharacterPosition + 1, KW_Cell_With_HL7_Message, HL7_FIELD_DELIMITER)
Next_HL7_Subfield_Delimiter = InStr(KWFieldCharacterPosition + 1, KW_Cell_With_HL7_Message, HL7_SUBFIELD_DELIMITER)
'Added logic to handle issue where the next delimiter was not found, making result 0, making it the lowest value in the next lines of code
If Next_HL7_Segment_Delimiter = 0 Then Next_HL7_Segment_Delimiter = 99999
If Next_HL7_Field_Delimiter = 0 Then Next_HL7_Field_Delimiter = 99999
If Next_HL7_Subfield_Delimiter = 0 Then Next_HL7_Subfield_Delimiter = 99999
'Set the Last Character Position to whichever Next Delimiter is the lowest / minimum number - Segment or Field or Subfield
KWLastCharacterPosition = WorksheetFunction.Min(Next_HL7_Segment_Delimiter, Next_HL7_Field_Delimiter, Next_HL7_Subfield_Delimiter)
' ** FOR TESTING ** MsgBox ("Last Character Position: " & KWLastCharacterPosition & ", 5 Characters starting there = " & Mid(KW_Cell_With_HL7_Message, KWLastCharacterPosition, 5))
'Determine the number of characters to return in the MID function by subtracting the first character position from the last character position
KWNumberOfCharactersToReturn = KWLastCharacterPosition - KWFieldCharacterPosition - 1
' ** FOR TESTING ** MsgBox ("Number of characters to return: " & KWNumberOfCharactersToReturn)
KWResult = Mid(KW_Cell_With_HL7_Message, KWFieldCharacterPosition + 1, KWNumberOfCharactersToReturn)
'MsgBox ("Result: Segment " & KW_HL7_Segment_Name & ":" & KW_HL7_Field_Number & " is " & KWResult)
KWHL7 = KWResult
End Function
The problem I had with using the split function was that it put everything into arrays. And since I needed to search FIRST for the KWSegmentStringToSearchFor (i.e. "MSH" or "PV1"), before couting the pipe (|) characters, I would need the array to have separate nested arrays and it got way too confusing for me.
So I abandoned the split function, and my initial plans to use arrays, and just wrote everything to find things sequentially. So it searches for the KWSegmentStringToSearchFor (i.e. "MSH" or "PV1") with InStr() and then counts the pipe (|) characters from there to determine which number field to return.
Since the strings are of variable length, but delimited with special characters, next I have to determine how many characters to return with the MID function. So I search for the next delimiter FROM THERE / using the field I found as the starting point and call that the end of my field.
The issue:
The logic considers ANY of the 3 possible delimiters the end of the field.
If I take that out, the code wouldn't know where the end of the string is.
Even if I add some sort of IF statement that IF the optional 4th argument exists (which I'm not sure how to do yet), THEN ignore the ^ as a delimiter... that would always return the full field (ADT^A08). It wouldn't return just the sub-field / component I want.
Thanks!
A simple answer, would be to split on the LineFeed then it may need tweaking would be, split(range("a1").value,"|")(intFieldNumber)
i.e.
split("11>MSH|^~\&|OPS|384|RISIC|384|20160923093012||ADT^A08|Q1230569238T1410271390","|")(8)
gives the result ADT^A08
In a SSRS Matrix cell I want to be able to have a line break between each output given.
I have the following code in my MS SQL Server Stored Procedure which I then point my SSRS report to
SELECT Customer, Hostname, (QName + QHostname + Qtag + QSerial + QCategory + QType + QItem + QManu + QModel + QVersion) AS AdditionalInfo1
FROM TableQ
At the moment in the AdditionalInfo1 cell when one of the options is returned they are separated by a comma
e.g.
QName, QHostname, Qtag.
Instead I would like them to be separated by a line break all within the same cell
e.g.
QName
QHostname
Qtag
I have tried putting + char(13) + between each Q... in AdditionalInfo1 but this didn't work.
For SSRS, you want to use Chr(10), not Chr(13). I've used this in expressions and as a Join delimiter argument and it produced the desired effect: line breaks within the textbox.
Edit:
Below is an expression that will include the fields with line breaks if a value is present, or omit both if the field is null.
=Fields!QName.Value
+ IIF(ISNOTHING(Fields!QHostname.Value),"", vbCrLf + Fields!QHostname.Value)
+ IIF(ISNOTHING(Fields!Qtag.Value),"", vbCrLf + Fields!Qtag.Value)
+ IIF(ISNOTHING(Fields!QSerial.Value),"", vbCrLf + Fields!QSerial.Value)
+ IIF(ISNOTHING(Fields!QCategory.Value),"", vbCrLf + Fields!QCategory.Value)
+ IIF(ISNOTHING(Fields!QType.Value),"", vbCrLf + Fields!QType.Value)
+ IIF(ISNOTHING(Fields!QItem.Value),"", vbCrLf + Fields!QItem.Value)
+ IIF(ISNOTHING(Fields!QManu.Value),"", vbCrLf + Fields!QManu.Value)
+ IIF(ISNOTHING(Fields!QModel.Value),"", vbCrLf + Fields!QModel.Value)
+ IIF(ISNOTHING(Fields!QVersion.Value),"", vbCrLf + Fields!QVersion.Value)
Instead of concatenating all the 'Q' columns into a single string keep them as separate fields. Then create individual placeholders in a single cell, one for each field. You can do this quite quickly by clicking into the cell (which is rich TextBox) and typing the field name (as it appears in the DataSet) enclosed by square brackets
eg:
[QName]
[QHostname]
[Qtag]