How to check if a cell value is Chinese text in Excel - vba

I have a list of cells which contain the first name of users: Amy, Jim, 梅, 明, ธนกาญจน์, Андрей, etc. From the name, I would like to determine if a user is Chinese.
Does anyone know if there is any formula or VBA method to determine this?

Since the question is to check based on Chinese text I would prefer using AscW function like below
Function DetectChineseText(cel As Range) As Boolean
DetectChineseText = True
For i = 1 To Len(cel.Value)
MidChar = Mid(cel.Value, i, 1)
If Not (AscW(MidChar) >= 19968 And AscW(MidChar) <= 25343) Then
DetectChineseText = False
Exit For
End If
Next i
End Function
But as per this link there are 89,602 codepoints assigned in Unicode character set for chinese characters we need to mention every range we needed to detect in the data. For now I just used only one range (19968 to 25343) as per a wikipedia article.
You could add the range as per your requirement.

Related

Checking the data type (integer or string) in a word table

I am trying to do some conditional formatting in word table based on the value in a specific cell.
If the value is <1 set the background to green; if the value is between 1 and 10, format the background yellow and if the value is above 10 format the background red.
I am able to loop through a table and debug.print the content of each cell but am struggling with checking for the datatype in the correspoding cell.
I tried IsNumeric, Int, Fix but none work
`
Sub ConditionalFormat()
Dim tbl As Table, r As Long, c As Long
Set tbl = ActiveDocument.Tables(1)
For r = 1 To tbl.Rows.Count
For c = 1 To tbl.Columns.Count
If tbl.Cell(r, c) = Int(tbl.Cell(r, c)) Then
tbl.Cell(r, c).Shading.BackgroundPatternColor = wdColorBlueGray
End If
Next c
Next r
End Sub
where am i going wrong?
`
Word tables have "end of cell" characters that can get in the way when you process a cell's content.
In your case,
Int(tbl.Cell(r,c))
won't work because tbl.Cell(r,c) returns the Cell, not its value or content. To get its content, you really need
tbl.Cell(r.c).Range
But even that just specifies a block of material in the cell, so it might contain text, images etc. What you are typically looking for is the plain text of the cell, which is really
tbl.Cell(r.c).Range.Text
So you might hope that, for example, if your cell contained the text "42" the expression
IsNumber(tbl.Cell(r.c).Range.Text)
would return True. But it doesn't, because each Word table cell has an end-of-cell character that is returned at the end of the .Range.Text, and that means VBA does not recognise the text as Numeric. To deal with that, you can use
Dim rng As Word.Range
Set rng = tbl.Cell(r.c).Range
rng.End = rng.End - 1
Debug.Print IsNumber(rng.Text)
Set rng = Nothing
SOme VBA functions will ignore the end-of-cell marker anyway as they are intended to be reasonably flexible about how to recognise a number, e.g. you should be able to use
Val(tbl.Cell(r,c).Range.Text)
without running into problems.
As for which functions to use to test/convert the value, that really depends on how much you can assume about your data, how much validation you need to do and what you need to do with your data.
In a nutshell, Val looks for "bare numbers", e.g. 123, 123.45, and numbers in scientific notation. If it finds something non-numeric it will return 0. AFAICR Int and Fix work in similar ways but modify the number in different ways. IsNumeric, CInt, CDbl and so on recognise numbers taking account of the Regional Settings in your OS (e.g. Windows) and accepts/ignores grouping digits (e.g. so they might recognize 1,234,567.89 and even 1,,234,567.89 as 1234567.89 on a typical US system and 1.234.567,89 as the "same number" on a German system). CInt etc. will raise an error if they don't recognise a number.
Anything more than that and you'll probably have to find or write a piece of code that does exactly what you need. I expect there are thousands of such routines out there.
Probably worth noting that the Range objects in Excel and Word have different members. Excel has a Range.Value property but Word does not.
Try:
Sub ConditionalFormat()
Dim r As Long, c As Long
With ActiveDocument.Tables(1)
For r = 1 To .Rows.Count
For c = 1 To .Columns.Count
With .Cell(r, c)
Select Case Val(Split(.Range.Text, vbCr)(0))
Case Is < 1: .Shading.BackgroundPatternColor = wdColorGreen
Case Is > 10: .Shading.BackgroundPatternColor = wdColorRed
Case Else: .Shading.BackgroundPatternColor = wdColorYellow
End Select
End With
Next c
Next r
End With
End Sub

extract airlines from flight numbers strings in excel

I have problem of extracting two-character code from the string format like:
"VA198-VA200-VA197"
I just want to get the string:
"VA-VA-VA"
Also the data I have are not just in one format, some data is like:
"DL123-DL245"
or
"DL123-VA345-HU12-OZ123"
Does anyone know how to do it fast in excel? Thanks.
With data in A1, in B1 enter the array formula:
=TEXTJOIN("",TRUE,IF(ISERR(MID(A1,ROW(INDIRECT("1:100")),1)+0),MID(A1,ROW(INDIRECT("1:100")),1),""))
NOTE:
The formula strips out all numeric characters, leaving only the alphas and the dash.
Array formulas must be entered with Ctrl + Shift + Enter rather than just the Enter key. If this is done correctly, the formula will appear with curly braces around it in the Formula Bar.
There are a couple of ways you can approach this depending on how many possible segments their are in your string. If we assume your flight number is in A1:
First Segment: =LEFT(A1,2)
Second Segment: =MID(A1,FIND("-",A1)+1,2)
Third Segment: =MID(A1,FIND("-",A1,FIND("-",A1)+1)+1,2)
You could then concatenate the three expressions together and add a fourth with some conditionals. The problem is that based on your information you can have anywhere from 1 to 4 (at least) names which means you'll need a conditional:
Second Segment: =IF(ISERR(FIND("-",A1)),"",MID(A1,FIND("-",A1)+1,2))
Adding in the separators we end up with something like this for up to four segements:
=CONCATENATE(LEFT(A1,2),IF(ISERR(FIND("-",A1)),"",CONCATENATE("-",MID(A1,FIND("-",A1)+1,2))),IF(ISERR(FIND("-",A1,FIND("-",A1)+1)),"",CONCATENATE("-",MID(A1,FIND("-",A1,FIND("-",A1)+1)+1,2))),IF(ISERR(FIND("-",A1,FIND("-",A1,FIND("-",A1)+1)+1)),"",CONCATENATE("-",MID(A1,FIND("-",A1,FIND("-",A1,FIND("-",A1)+1)+1)+1,2))))
This will give you everything in one field.
Here is a VBA type answer.Assuming all strings are structured in the same way. Meaning Two letters followed by numbers and separated with "-". If one such string is A1, and you want to write the result to B1:
Sub BreakStrings()
d = Split(Range("A1"), "-")
For i = LBound(d) To UBound(d)
d(i) = Left(d(i), 2)
Next i
strg = Join(d, "-")
Range("B1") = strg
End Sub
User-defined function (UDF):
Function GetVal(cell)
With CreateObject("VBScript.RegExp")
.Global = True: .Pattern = "(\w{2})(.+?)(?=-|$)"
GetVal = .Replace(cell, "$1")
End With
End Function

Detect text language in VBA

I have a textbox in PowerPoint which I store into an array with Split.
Is there any way to detect what language the text is in VBA?
There will actually only be English or Chinese text, so I guess an alternative solution would be to detect if the text is not English, or is/isn't Unicode?
It should be possible by checking that one of the characters is Chinese:
Function IsChiness(text As String) As Boolean
Dim c&, i&
For i = 1 To Len(text)
c = AscW(Mid$(text, i, 1))
If c >= &H4E00& And c <= &H9FFF& Then
IsChiness = True
Exit Function
End If
Next
End Function
The shape's .TextFrame.TextRange.LanguageID will tell you what language the text is set to. US English is 1033, for example. There's a list of language IDs here (use the Decimal LCID, right-hand column in this case):
https://msdn.microsoft.com/en-us/goglobal/bb964664.aspx?f=255&MSPPError=-2147217396
It's worth looking at the hex values as well. The rightmost two digits give you the main language code (Chinese is 04, for example) and the leftmost two digits identify the specific locale (PRC, Singapore, Taiwan, etc).
If you're likely to have mixed language text in a single text box, look at the LanguageID property of each .Run of text. For example, with a shape selected, try this:
Dim oRng As TextRange
Dim x As Long
With ActiveWindow.Selection.ShapeRange(1).TextFrame.TextRange
For x = 1 To .Runs.Count
Debug.Print .Runs(x).LanguageID
Next
End With

Macro query spread over multiple-sheets

Wording my question is slightly tricky so I've included screen-shots to make this easier. I have 2 separate spreadsheets which are currently not linked together in anyway. What I've been asked to do is:
For the drop-downs which have a * next to them, have this * drop-down get converted into a acronym (I.e. If it's Home Visit *, then this will be converted to HV), and have it automatically entered into Cell Position X. Please refer to Image 1 then Image 2)
So the user would click on Sheet one, select the relevant drop-down field and then assign how much time that task took. The second sheet would then update itself with this information - it would insert the users name, program and activities. This is where it gets very tricky. Based off the drop-down selection, if it is asterisked (*), then based off the field-type it will convert it into a set acronym which would then be placed in one of the data fields based off the entry date that has been provided.
I designed both spread-sheets and they have macros in the background, but I can't seem to work out how to best perform this. Would you suggest a transpose function which checks firstly the date criteria and then an INDEX(MATCH) function to match the criteria against a pre-defined name-range which converts Home Visit etc. to HV automatically? I'm also unsure of how to insert delimiters for each new entry that is read. If anyone can provide help I would be very grateful.
I'm not 100% sure I understand your question, but here goes:
What about adding a Worksheet_Change event to look for changes in the drop-down's cell, and then converting it to an acronym?
Place the following code inside the sheet of interest:
Private Sub Worksheet_Change(ByVal Target As Range)
'If Cell A1 is changed, put the acronym into A2
If Target.Row = 1 And Target.Column = 1 Then
Cells(2, 1) = GetAcronym(Target.Value)
End If
End Sub
Function GetAcronym(TheText As String) As String
Dim result As String
Dim x As Long
'Always grab the first letter
result = Mid(TheText, 1, 1)
'Get the other letters
For x = 2 To Len(TheText) - 1
If Mid(TheText, x, 1) = " " Then result = result & Mid(TheText, x + 1, 1)
Next x
GetAcronym = UCase(result)
End Function

Search through column in excel for specific strings where the string is random in each cell

I am working in excel with a datasheet that is 1000 rows and 15 columns. Currently, in one of the columns, I have a lot of data mixed in with people names (see below for an example). I want to see how many times each person's name appears in the datasheet, so I can use it in a pivot table. There is no particular format or order to the way names appear. It is random. Is there a way to code in excel to search through that whole column and give me a count of the amount of times each person's name appears?
Column D
21421Adam14234
2323xxx Bob 66
23 asjdxx Jacob 665
43 Tim 5935539
2394Bob 88
After some trial and error, I can generate a list of names, one per row and place them in a different column for comparison sake, if that makes it easier.
I know you have got your answer but why not use COUNTIF with Wild Cards? You don't need VBA for this :)
See this example
=COUNTIF($A$1:$A$5,"*"&C1&"*")
SNAPSHOT
You don't have VBA tagged, but I don't know if there is a way to do this without it. I've built a custom function below. To implement it, take the following steps.
1) List desired names starting at column E1.
2) Insert this function into VBA Editor
A) Presss Alt + F11
B) Click Insert > Module from menu bar
C) Copy this code into Module
Option Explicit
Function findString(rngString As Range, rngSearch As Range) As Long
Dim cel As Range
Dim i As Integer
i = 0
For Each cel In rngSearch
If InStr(1, cel.Text, rngString.Value) > 0 Then
cel.offset(,-1) = rngString.Value 'places the name in cell to right of search range
i = i + 1
End If
Next
findString = i
End Function
3) In F1 type the following formula
=findstring(E1,$D$1:$D$5)
4) Run the formula down column F to get the count of each desired name.