Ascw returns "Cannot convert to 'Integer'." in Watch or Immediate - vb.net

I have following sample code
Dim q As Char = "a"
Dim res As String = CStr(AscW(q))
res contains correctly "97" but when I use AscW(q) in watch or immediate it returns message: Cannot convert to 'Integer'.
Is it a bug or Visual Studio or am I doing something not correctly?
How can I see a character code in Immediate.
Note
The code presented is just an example. I found the problem when trying to see Character code in the Watch Window.

For a workaround, how about the command
? System.Text.Encoding.Unicode.GetBytes(q)
I personally believe that any acceptable VB.Net code should be acceptable in the Immediate window and really don't understand why AscW is causing errors when VB.Net offers no equivalent (e.g. in C#, but not VB.Net, you can cast a Char variable to an Integer to get the character code).

You are doing everything right (and the outputs will be OK in any case), although you are using old VB code. If you need functionalities like AscW (, Asc, ChrW, etc.), you would have to rely on this "old code" to get what you want (directly or via Microsoft.VisualBasic.Strings which, btw, does not show a different behaviour). But, in any other case, you should avoid the utilisation of this old code.
Test these two lines in the Immediate Window:
Dim res As String = CStr(5)
res = 5.ToString()
As you can see, you get an "error" (VS 2010, right-click on the line and select "QuickWatch") in the first line (old version), but not in the second one (.NET version).
Thus, the behaviour you observed can be considered as an inoffensive bug (no real effects in the execution) more or less understandable if you analyse the situation (you are asking a certain language (VB.NET) to support all its own features and the ones from an old language (VB); with the old one, some secondary functionalities might not be perfect).

Related

MS Project equivalent to "xlAnd". Enumeration for logical operators

I'm trying to write a language independent filter for MS Project in VBA. I'm using the syntax:
FilterEdit (Name, Taskfilter, Create, Fieldname, Test, Value, Operation...)
I have managed to get the Fieldnames and Tests to be language independent, but I struggle with the Operation:= expression. For an English locale one would write: Operation:="and" but that doesnt work for other locales.
Is there a way to write the logical operator (and/or) as an enumeration? (not as a string?)
For Excel one could write xlAnd, and Project has a lot of enumerations starting with Pj, ie. PjTaskStart. I also know there's a Filter.LogicalOperationType, but I haven't managed to figure out if this could work for me or not. I have also experimented with FieldConstantToFieldName, but I reckon there's no fieldname for the logical operator?
I know I could use If LocaleID = xxxx Then..., but I'd like to not assume what locales will be in use.
Edit: I solved the first part of my problem!
By leaving it blank Operation:="", Project returns "And". But I haven't figured out yet how to return "Or"...
Operation:="" works for FilterEdit, but not for SetAutoFilter.
So I ended up using the dreaded If LocaleID.
Teaching moment:
I found out most operators can be language independent, except for:
And, Or, Contains and Does Not Contain.
These needs to be translated for each locale. I'll get to those in a minute. First I'll list all the language independent operators:
< Less than <= Less than or equal to > Greater than >= Greater than or equal to = Equal to <> Not equal to
My trick for finding the translations I need for the language dependent operators is the following MS Office Support page.
Notice the category named "Filter for specific text" in the English support page. Here we can read all the "words" we need. Now go to the bottom of the web page and change the language:
This opens up a new page listing all the different languages (not locale specific). Remembering where you found the word for Contains in English, then changing the language to for instance "Magyar (Magyarorzág)", we can now see that Contains = "Tartalmazza" in Magyar.
Next step is to google "Magyar languge" and learn that this actually equals Hungarian. So now you can go to this MSDN web page to see that Hungarian = LocaleID: 1038.
Putting all this together inside VBA makes you have to write the following code:
Dim LocalContains As String
If LocaleID = 1038 Then
LocalContains = "Tartalmazza" 'Hungarian
ElseIf LocaleID = 1044 Then
LocalContains = "inneholder" 'Norwegian
Else
LocalContains = "contains" 'English
End If

Alt-Code Characters in F#

Edit/Update:
Thank you all for responding. I understand I was being too vague, but wasn't sure if posting naked lines of code would be useful in this case.
In my .vb file I have a pulldown control with its validation values as:
TempUnit.DataSource = {"°C", "°F", "°R", "K"}
...which is stored in a variable:
Dim unit As String = TempUnit.SelectedItem.ToString
...which gets passed into a function along with other variables:
Function xxx(..., ByVal unitT As String) As Double
... which finally calls the .fs file and gets evaluated using:
let tempConv t u =
match u with
|"°C" -> t * 9.0 / 5.0 + 32.0
|"°R" -> t - 459.67
|"K" -> t * 9.0 / 5.0 - 459.67
|_ -> t
If any temperature unit other than Kelvin is selected, the match fails and defaults to the else case (which is Fahrenheit in this context). I ended up bypassing the degree symbol entirely by evaluating the substring instead:
Dim unit As String = TempUnit.SelectedItem.ToString.Substring(1)
The program is working again, but I have no idea what I changed, if anything, to make the string match stop working. The first thing I tried was to copy/paste from one file to other to ensure they were identical strings, in addition to trying other symbols, but to no avail. The degree symbol is what caught my attention, but then I checked the pressure units and found the exact same issue with the micro prefix.
Thank you, Hans Passant, I had unicode in mind as a possible solution, but it didn't seem like an easy fix in the heat of the moment. I appreciate your link.
Original Post:
I have a VB program referencing a function stored in an F# library file whose arguments include unit of measure strings containing special characters (e.g. "°C" "µBar").
The strings are identical in the .vb and .fs files; and there was no issue until the F# library file stopped recognizing the Alt-Code characters for reasons unbeknownst to me.
The program works as intended if I remove the offending Alt-Code character from the string definitions in the F# and VB files.
What would cause a match to fail between two identical strings that happen to contain an Alt-Code character?
What is the proper way to handle Alt-Code characters in F# (and VB for that matter)?
The µ glyph is a bit infamous. Unicode has two codepoints that look like that: U+03BC = "Greek small letter Mu" and U+00B5 = "Micro sign". One is a letter in the Greek alphabet, the other is a symbol that often appears in math and units.
Compare μ and µ. Looks almost identical in most fonts (you can see the difference with Segoe UI) and very easily fools the human eye. Typographers insist they are not the same, particularly if they are Greek I'd imagine. Nor does a computer, the problem you are surely dealing with.
Copy/paste or re-type to fix. The Charmap.exe applet in Windows is very handy to get this right.

Why does casting to double using "String * 1" fail? Will CDbl(String) work on all systems?

I have an application which contains the line below to assign a parsed XML value to a variant array.
V(2) = latNode.Text * 1
This works fine on my system (Windows 7, Excel 2010) but doesn't work on some other system or systems - and I've not been able to get a response from the user who reported the problem.
I've switched out the offending line for:
V(2) = CDbl(latNode.Text)
This still works on my system, but then I had no problem in the first place. The question is on what systems does the first approach fail and why, and will the second method always work? I'm sure I've used the "String * 1" trick elsewhere before and would like to know how concerned I should be about tracking down other occurrences.
Thanks.
Maybe it's related to thousands separator and decimal mark. Office VBA uses cultural settings even in CDbl, in my German Excel version, it's reversed compared to English, CDbl("123.4") is parsed to 1234, CDbl("123,4") to 123.4.
Val(x) will always parse the dot as decimal mark.

Casting or Parsing of Text in vb.net

in vb, you can use text which is in textbox instead of numerical expressions. I mean, if I write 50 in textbox1 and also I can write like that code:
Dim result As Double = TextBox1.Text + 0.4
as you see, I didnt convert any type but it works in vb.net
But I want to learn what are disadvantages of this using?
(I am just talking about arithmetic operations)
Under the hood VB.net is doing an implicit narrowing conversion of TextBox1.Text (i.e. CType(TextBox1.Text, Double)) to make that work. This means you have Option Strictoff. Probably the biggest disadvantage to doing this is you would be going against the best practice of having Option Strict On.
By having Option Strict off you are preventing the compiler from enforcing type checking. This allows you to code in a more VB6 way. So implicit conversions of narrowing scope are allowed. If you had turned it on, only widening conversions (which don't have the potential of negative side affects) are allowed.
While in this specific scenario, it may not seem to be a big deal, but leaving it off for your whole codebase likely will result in subtle bugs creeping in.
I'd suggest reading about Widening and Narrowing Conversions (Visual Basic) on MSDN.
In VB.NET you will only get away with this if you have OPTION STRICT turned off - otherwise, you'll generate an error.
In programmming, you should always try to be as precise as possible with your data types. So you could write your line of code as:
Dim result as Double = Convert.ToDouble(TextBox1.Text) + 0.4
Alternatively, you could do some error trapping:
Dim Result as Double
Try
Result = Convert.ToDouble(TextBox1.Text) + 0.4
Catch
Result = 0
End Try
There are a lot of other things you can use, include TryParse. You can even use VBA functions like CDbl too.
If you rely on what is called implicit type conversion, VB.NET will attempt to convert the data type for you. The disadvantage of this approach is that it makes for lazy programming. On this occasion you want VB.NET to be fault-tolerant, but how about when you don't? If you allow it to correct your errors, you'll eventually get the situation where you generate bugs because your code isn't enforcing the correct data type.
Right - that's the party line over. Personally, I quite like the way VBA casts data types behind the scenes for me!

Asc(Chr(254)) returns 116 in .Net 1.1 when language is Hungarian

I set the culture to Hungarian language, and Chr() seems to be broken.
System.Threading.Thread.CurrentThread.CurrentCulture = "hu-US"
System.Threading.Thread.CurrentThread.CurrentUICulture = "hu-US"
Chr(254)
This returns "ţ" when it should be "þ"
However, Asc("ţ") returns 116.
This: Asc(Chr(254)) returns 116.
Why would Asc() and Chr() be different?
I checked and the 'wide' functions do work correctly: ascw(chrw(254)) = 254
Chr(254) interprets the argument in a system dependent way, by looking at the System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage property. See the MSDN article about Chr. You can check whether that value is what you expect. "hu-US" (the hungarian locale as used in the US) might do something strange there.
As a side-note, Asc() has no promise about the used codepage in its current documentation (it was there until 3.0).
Generally I would stick to the unicode variants (ending on -W) if at all possible or use the Encoding class to explicitly specify the conversions.
My best guess is that your Windows tries to represent Chr(254)="ţ" as a combined letter, where the first letter is Chr(116)="t" and the second ("¸" or something like that) cannot be returned because Chr() only returns one letter.
Unicode text should not be handled character-by-character.
It sounds like you need to set the code page for the current thread -- the current culture shouldn't have any effect on Asc and Chr.
Both the Chr docs and the Asc docs have this line:
The returned character depends on the code page for the current thread, which is contained in the ANSICodePage property of the TextInfo class. TextInfo.ANSICodePage can be obtained by specifying System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage.
I have seen several problems in VBA on the Mac where characters over 127 and some control characters are not treated properly.
This includes paragraph marks (especially in text copied from the internet or scanned), "¥", and "Ω".
They cannot always be searched for, cannot be used in file names - though they could in the past, and when tested, come up as another ascii number. I have had to write algorithms to change these when files open, as they often look like they are the right character, but then crash some of my macros when they act strangely. The character will look and act right when I save the file, but may be changed when it is reopened.
I will eventually try to switch to unicode, but I am not sure if that will help this issue.
This may not be the issue that you are observing, but I would not rule out isolated problems with certain characters like this. I have sent notes to MS about this in the past but have received no joy.
If you cannot find another solution and the character looks correct when you type it in, then I recommend using a macro snippet like the one below, which I run when updating tables. You of course have to setup theRange as the area you are looking at. A whole file can take a while.
For aChar = 1 To theRange.Characters.count
theRange.Characters(aChar).Select
If Asc(Selection.Text) = 95 And Selection.Text <> "_" Then Selection.TypeText "Ω"
Next aChar