Unicode string literals in VBA - excel

I would like to declare (in a VBA class module) some private constant strings that contain Japanese characters. Is there a way to construct String literals (or combining literals in a way) that may be accepted as initializers in a Const declaration? i.e. something like:
Private Const MY_CONST = ...
or
Private Const MY_CONST As String = ...
I use MS Excel v14.0.6112.5000 (MS Office Professional Plus 2010).
What won't work:
Pasting the Japanese chars directly in a string literal (e.g. ... = "変数") because the VBA editor will mess with the chars;
Using ChrW() or ChrW$() (e.g. ... = ChrW$(22793) & ChrW$(25968)), because function calls are not allowed in Const initializers.
What I wouldn't like:
Faking the Const by creating Private Property Get returning the string, because the string will be recreated every time I access the property (plus, is confusing and ugly... but, okay, the last two things are rather a matter of taste).

Faking the Const by creating Private Property Get returning the string, because the string will be recreated every time I access the property (plus, is confusing and ugly... but, okay, the last two things are rather a matter of taste).
You need not recreate the string each time you access the property.
While this is still ugly as a matter of taste, make a read-only property (essentially Const, since it doesn't have a Property Let procedure), and construct the string in the Class_Initialize event:
'## CLASS MODULE
Private pUnicodeString As String
Sub Class_Initialize()
pUnicodeString = ChrW(22793) & ChrW(25968)
End Sub
Property Get UnicodeString() As String
UnicodeString = pUnicodeString
End Property
And then invoke it like:
'## STANDARD MODULE
Sub Test()
Dim c As myClass
Set c = New myClass
[A1].Value = c.UnicodeString
End Sub

The encoding of VBA source file is Windows-1252, which does not support Japanese.
You cannot change the encoding of the source file, so you have to write its binary equivalent and then convert it before using it
Const str = vbTab & "Ype" ' I use vbTab because the VBA editor replaces tabulation with spaces
'...
ustr = StrConv(str, vbFromUnicode)
'ustr value is now "変数"
Use notepad to convert the string: copy-paste the unicode string, save the file as unicode (not utf-8) and open it as ANSI, then copy-paste it into the VBA editor without the first two characters (ÿþ), which is the BOM marker
Explanation
変数 is U+5909 U+6570 in unicode which is 0x09 0x59 0x70 0x65 in UTF-16LE (Windows unicode encoding), and this sequence corresponds to <tab>Ype in Windows-1252

Another approach is to use an Enum in combination with a function to provide VBA autocomplete based on friendly names. I prefer this method because it keeps all the Unicode definitions in one place, and uses the readable names throughout the rest of my project.
' List friendly names of Unicode characters
Public Enum eUnicodeConst
RightArrow
LeftArrow
Clock2
End Enum
'---------------------------------------------------------------------------------------
' Procedure : UniConst
' Author : Adam Waller
' Date : 7/7/2020
' Purpose : Search for characters: https://emojipedia.org/
' : Look up UTF-16 Decimal value(s) from the following site:
' : http://www.fileformat.info/info/unicode/char/search.htm
'---------------------------------------------------------------------------------------
'
Public Function UniConst(Text As eUnicodeConst) As String
Select Case Text
Case LeftArrow: UniConst = ChrW(8592)
Case RightArrow: UniConst = ChrW(8594)
Case Clock2: UniConst = ChrW(55357) & ChrW(56657)
End Select
End Function
Now in my code, I can just use the UniConst function anytime I need a Unicode character or snippet without having to look character codes. 😄

Related

Check if cell is only a-z excel

I would like to be sure that all my cell contain only characters (A-Z/a-z). I want to be sure there isn't any symbol, number or anything else. Any tips?
For example I have this "Š".
As a VBA function, the following should work:
Option Compare Binary
Function LettersOnly(S As String) As Boolean
LettersOnly = Not S Like "*[!A-Za-z]*" And S <> ""
End Function
In using the function, S can be either an actual string, or a reference to the cell of concern.
EDIT: Also, you want to be certain you have not set Option Compare Text in your code. The default is Option Compare Binary which is what you want for this type of comparison. I have added that to the code for completeness.
Open the VBA editor (Alt+F11) and create a new module.
Add a reference to "Microsoft VBScript Regular Expressions 5.5" (Tools -> References).
In your new module, create a new function like this:
Function IsAToZOnly(inputStr As String) As Boolean
Dim pattern As String: pattern = "^[A-Za-z]*$"
Dim regEx As New RegExp
regEx.pattern = pattern
IsAToZOnly = regEx.Test(inputStr)
End Function
Use the new function in your worksheet:
=IsAToZOnly(A1)

VBA Special characters U+2264 and U+2265

I have a frustrating problem. I have a string containg other characters that are not in this list (check link). My string represents a SQL Query.
This is an example of what my string can contain: INSERT INTO test (description) VALUES ('≤ ≥ >= <=')
When I check the database, the row is inserted successfully, but the characters "≤" and "≥" are replaced with "=" character.
In the database the string in description column looks like "= = >= <=".
For the most characters I can get a character code. I googled a character code for those two symbols, but I didn't find one. My goal is to check if my string contains this two characters , and afterwards replace them with ">=" and "<="
===Later Edit===
I have tried to check every character in a for loop;
tmp = Mid$(str, i, 1)
tmp will have the value "=" when my for loop reaches the "≤" character, so Excel cannot read this "≤" character in a VB string, then when I'm checking for character code I get the code for "=" (Chr(61))
Are you able to figure out what the character codes for both "≤" and "≥" in your database character set are? if so then maybe try replacing both characters in your query string with chrw(character_code).
I have just tested something along the lines of what you are trying to do using Excel as my database - and it looks to work fine.
Edit: assuming you are still stuck and looking for assistance here - could you confirm what database you are working with, and any type information setting for the "description" field you are looking to insert your string into?
Edit2: I am not familiar with SQL server, but isn't your "description" field set up to be of a certain data type? if so what is it and does it support unicode characters? ncharvar, nchar seem to be examples of sql server data types that support Unicode.
It sounds like you may also want to try and add an "N" prefix to the value in your query string - see
Do I have use the prefix N in the "insert into" statement for unicode? &
how to insert unicode text to SQL Server from query window
Edit3: varchar won't qualify for proper rendering of Unicode - see here What is the difference between varchar and nvarchar?. Can you switch to nvarchar? as mentionned above, you may also want to prefix the values in your query string with 'N' for full effect
Edit4: I can't speak much more about sqlserver, but what you are looking at here is how VBA displays the character, not at how it actually stores it in memory - which is the bottom line. VBA won't display "≤" properly since it doesn't support the Unicode character set. However, it may - and it does - store the binary representation correctly.
For any evidence of this, just try and paste back the character to another cell in Excel from VBA, and you will retrieve the original character - or look at the binary representation in VBA:
Sub test()
Dim s As String
Dim B() As Byte
'8804 is "≤" character in Excel character set
s = ChrW(8804)
'Assign memory representation of s to byte array B
B = s
'This loop prints "100" and "34", respectively the low and high bytes of s coding in memory
'representing binary value 0010 0010 0110 0100 ie 8804
For i = LBound(B) To UBound(B)
Debug.Print B(i)
Next i
'This prints "=" because VBA can not render character code 8804 properly
Debug.Print s
End Sub
If I copy your text INSERT INTO test (description) VALUES ('≤ ≥ >= <=') and paste it into the VBA editor, it becomes INSERT INTO test (description) VALUES ('= = >= <=').
If I paste that text into a Excel cell or an Access table's text field, it pastes "correctly".
This seems to be a matter of character code supported, and I suggest you have a look at this SO question.
But where in you program does that string come from, since it cannot be typed in VBA ??
Edit: I jus gave it a try with the below code, and it works like a charm for transferring your exotic characters from the worksheet to a table !
Sub test1()
Dim db As Object, rs As Object, cn As Object
Set cn = CreateObject("DAO.DBEngine.120")
Set db = cn.OpenDatabase("P:\Database1.accdb")
Set rs = db.OpenRecordset("table1")
With rs
.addnew
.Fields(0) = Range("d5").Value
.Update
End With
End Sub

declaring a unicode string in vba in excel [duplicate]

This question already has answers here:
How to type Unicode currency character in Visual Basic Editor
(2 answers)
Closed 3 years ago.
I am trying to create a substitute() that will convert greek characters to latin.
The problem is that after declaring
Dim Source As String
Source = "αβγδεζηικλμνξοπρστθφω"
Source is interpreted as "áâãäåæçéêëìíîïðñóôõöù"
is there any way use unicode at declaration level?
You can try StrConv:
StrConv("αβγδεζηικλμνξοπρστθφω", vbUnicode)
Source : http://www.techonthenet.com/excel/formulas/strconv.php
[EDIT] Another solution:
You can get every greek character (lower and upper case) thanks to this procedure:
Sub x()
Dim i As Long
For i = 913 To 969
With Cells(i - 912, 1)
.Formula = "=dec2hex(" & i & ")"
.Offset(, 1).Value = ChrW$(i)
End With
Next i
End Sub
You can create an array to find the char for instance.
Source: http://www.excelforum.com/excel-programming/636544-adding-greek-letters.html
[EDIT 2] Here is a sub to build the string you wanted:
Sub greekAlpha()
Dim sAlpha As String
Dim lLetter As Long
For lLetter = &H3B1 To &H3C9
sAlpha = sAlpha & ChrW(lLetter)
Next
End Sub
As previously mentioned, VBA does support unicode strings, however you cannot write unicode strings inside your code, because the VBA editor only allows VBA files to be encoded in the 8-bit codepage Windows-1252.
You can however convert a binary equivalent of the unicode string you wish to have:
str = StrConv("±²³´µ¶·¹º»¼½¾¿ÀÁÃĸÆÉ", vbFromUnicode)
'str value is now "αβγδεζηικλμνξοπρστθφω"
Use notepad to convert the string: copy-paste the unicode string, save the file as unicode (not utf-8) and open it as ASCII (which is in fact Windows-1252), then copy-paste it into the VBA editor without the first two characters (ÿþ), which is the BOM marker
You say that your source is interpreted as "áâãäåæçéêëìíîïðñóôõöù".
Note that the Visual Basic Editor doesn't display Unicode, but it does support manipulating Unicode strings:
Dim strValue As String
strValue = Range("A1").Value
Range("B1").Value = Mid(strValue, 3)
Range("C1").Value = StrReverse(strValue)
If A1 contains Greek characters, B1 and C1 will contain Greek characters too after running this code.
You just can't view the values properly in the Immediate window, or in a MsgBox.

Converting html special character in excel

Could anyone please suggest a function/formula used in worksheet to convert html special character to HTML entity, thanks
E.g.
™ to ™
® to ®
The answer to this question is a two part.
Do you only need to convert a certain set of these special chars?
Do you need to convert All supported?
Answer 1:
Public Function ConvertHTMLTag(data As String) As String
data = Replace(data, "™", "™")
data = Replace(data, "®", "®")
ConvertHTMLTag = data
End Function
Answer 2:
Repeat for all chars in http://www.webmonkey.com/2010/02/special_characters/
To make this a bit easier, I would try to put this list in to an Excel sheet with in two columns. One for the special tag and the other with it's evaluated char.
Write a formula in a 3rd column to create your code for you...
="data = Replace(data, "&Char(34)&A1&Char(34)&", "&Char(34)&A2&Char(34)&")"
Once you have your VBA code you've created in Excel, a simple copy and paste in to the function above will do the trick.
Use this function to encode from html special character to string
Function HTMLToCharCodes(ByVal s As String) As String
With New MSXML2.DOMDocument60
.LoadXML "<p>" & s & "</p>"
HTMLToCharCodes = .SelectSingleNode("p").nodeTypedValue
End With
End Function
Input: &, return: &

Stack overflow when replacing ' with '' in VB 6.0

I'm looking into some legacy VB 6.0 code (an Access XP application) to solve a problem with a SQL statement by the Access app. I need to use replace single quotes with 2 single quotes for cases where a customer name has an apostrophe in the name (e.g. "Doctor's Surgery":
Replace(customerName, "'", "''")
Which will escape the single quote, so I get the valid SQL:
SELECT blah FROM blah WHERE customer = 'Doctor''s Surgery'
Unfortunately the Replace function causes an infinite loop and stack overflow, presumably because it replace function recursively converts each added quote with another 2 quotes. E.g. one quote is replaced by two, then that second quote is also replaced by two, and so on...
----------------EDIT---------------
I have noticed (thanks to posters) that the replace function used in this project is custom-written:
Public Function replace(ByVal StringToSearch As String, ByVal ToLookFor As String,
ByVal ToReplaceWith As String) As String
Dim found As Boolean
Dim position As Integer
Dim result As String
position = 0
position = InStr(StringToSearch, ToLookFor)
If position = 0 Then
found = False
replace = StringToSearch
Exit Function
Else
result = Left(StringToSearch, position - 1)
result = result & ToReplaceWith
result = result & Right(StringToSearch, Len(StringToSearch) - position - Len(ToLookFor) + 1)
result = replace(result, ToLookFor, ToReplaceWith)
End If
replace = result
End Function
Apparently, VB didn't always have a replace function of it's own. This implementation must be flawed. An going to follow folk's advice and remove it in favour of VB 6's implementation - if this doesn't work, I will write my own which works. Thanks everyone for your input!
Are you sure that it's not a proprietary implementation of the Replace function?
If so it can just be replaced by VB6's Replace.
I can't remember which version it appeared in (it wasn't in Vb3, but was in VB6) so if the original code base was vb3/4 it could be a hand coded version.
EDIT
I just saw your edit, I was Right!
Yes, you should be able to just remove that function, it'll then use the in build VB6 replace function.
We use an VB6 application that has the option of replacing ' with ` or removing them completely.
You could also walk through the letters, building a second string and inserting each ' as ''.
I just tried this in Access and it works fine (no stackoverflow):
Public Function ReplaceSingleQuote(tst As String) As String
ReplaceSingleQuote = Replace(tst, "'", "''")
End Function
Public Sub TestReplaceSingleQuote()
Debug.Print ReplaceSingleQuote("Doctor's Surgery")
End Sub

Resources