Google Translate Macro Function - How to rafear to Cell and/or Text in Quotes?

DrHacker

New Member
Joined
Jun 4, 2018
Messages
33
Hello experts, i modify actual script to create a function in Excel to translate from Google Translator with formula.

In order to work, you need to add Reference "Microsoft Internet Controls" (Tools>References)

I create it referring to a cell range value with syntax =GoogleTranslate(A1,”en”,”es”)

Is there a way to use, as well, Cell Range and/or Quoted Text? I mean, both with same formula function. I mean, use any of these two ways of syntax:

=GoogleTranslate(A1,”en”,”es”)

OR

=GoogleTranslate(“Specific Text in Quotes”,”en”,”es”)


Here is the VBA code for this function (Add as Module):

VBA Code:
'***Google Translation Custom Function START ***

'Google Language Codes List:

    'Auto Detect = 0   Bulgarian = bg    Finnish = fi         Hungarian = hu    Latvian = lv        Russian = ru      Turkish = tr
'English = en Catalan = ca French = fr Icelandic = is Lithuanian = lt Serbian = sr Ukrainian = uk
'Afrikaans = af Chinese = zh Galician = gl Indonesian = id Macedonian = mk Slovak = sk Urdu = ur
'Albanian = sq Croatian = hr Georgian = ka Irish = ga Malay = ms Slovenian = sl Vietnamese = vi
'Arabic = ar Czech = cs German = de Italian = it Maltese = mt Spanish = es Welsh = cy
'Armenian = hy Danish = da Greek = el Japanese = ja Norwegian = no Swahili = sw Yiddish = yi
'Azerbaijani = az Dutch = nl Gujarati = gu Kannada = kn Persian = fa Swedish = sv
'Basque = eu Esperanto = eo Haitian_Creole = ht Korean = ko Polish = pl Tamil = ta
'Belarusian = be Estonian = et Hebrew = iw Lao = lo Portuguese = pt-PT Telugu = te
    'Bengali = bn      Filipino = tl     Hindi = hi           Latin = la        Romanian = ro       Thai = th

    Function ConvertToGet(val As String)

val = Replace(val, " ", "+")
val = Replace(val, vbNewLine, "+")
val = Replace(val, "(", "%28")
val = Replace(val, ")", "%29")
ConvertToGet = val

End Function

Function Clean(val As String)

val = Replace(val, """, """")
val = Replace(val, "%2C", ",")
val = Replace(val, "'", "'")
Clean = val

End Function
Public Function RegexExecute(str As String, reg As String, Optional matchIndex As Long, Optional subMatchIndex As Long) As String

        Dim RegEx, match, Matches

        On Error GoTo ErrorHandler

Set RegEx = CreateObject("VBScript.RegExp"): RegEx.Pattern = reg
RegEx.Global = Not (matchIndex = 0 And subMatchIndex = 0)
If RegEx.Test(str) Then

Set Matches = RegEx.Execute(str)
RegexExecute = Matches(matchIndex).SubMatches(subMatchIndex)
Exit Function

End If

ErrorHandler:

RegexExecute = CVErr(xlErrValue)

End Function

Public Function GoogleTranslate(rng As Range, Optional translateFrom As String = "en", Optional translateTo As String = "es")

Dim getParam As String, trans As String, objHTTP As Object, URL As String

Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")

getParam = ConvertToGet(rng.Value)

URL = "https://translate.google.pl/m?hl=" & translateFrom & "&sl=" & translateFrom & "&tl=" & translateTo & "&ie=UTF-8&prev=_m&q=" & getParam

objHTTP.Open "GET", URL, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.Send ("")

If InStr(objHTTP.responseText, "div dir=""ltr""") > 0 Then
trans = RegexExecute(objHTTP.responseText, "div[^""]*?""ltr"".*?>(.+?)</div>")
GoogleTranslate = Clean(trans)

Else

GoogleTranslate = CVErr(xlErrValue)

End If

End Function

Sub RegisterGoogleTranslatorFunction()

Dim strFunc As String 'name of the function you want to register
Dim strDesc As String 'description of the function itself
Dim strArgs() As String 'description of function arguments

ReDim strArgs(1 To 3) 'The upper bound is the number of arguments in your function
strFunc = "GoogleTranslate"
strDesc = "Google Translator Custom function: " & vbNewLine & vbNewLine & _
"Formula Syntaxis =TRANSLATE(''A1'',''en'',''es'')" & vbNewLine & _
"To autodetect language use 0. Instead of ''en''" & vbNewLine & vbNewLine & _
"For additional languages visit: https://cloud.google.com/translate/docs/languages/"

strArgs(1) = "Select Cell value to Translate"
strArgs(2) = "Tranlate FROM Language"
strArgs(3) = "Tranlate TO Language"

Application.MacroOptions Macro:=strFunc, Description:=strDesc, ArgumentDescriptions:=strArgs, Category:="Custom Category"

    End Sub

'***Google Translation Custom Function FINISH ***
 
As you thought, the regex needs changing to treat line breaks the same as any character.

Old regex: div[^"]*?"result-container".*?>(.+?)</div>

New regex: div[^"]*?"result-container".*?>([\s\S]+?)</div>

Latest GoogleTranslate function, supporting functions and Test routine. Regex changed to handle line breaks in the text to be translated and preserve them in the translation.

VBA Code:
Option Explicit


#If VBA7 Then
    Private Declare PtrSafe Function MessageBoxW Lib "user32" (ByVal hWnd As LongPtr, ByVal lpText As LongPtr, ByVal lpCaption As LongPtr, ByVal uType As Long) As Long
#Else
    Private Declare Function MessageBoxW Lib "user32" (ByVal hWnd As Long, ByVal lpText As Long, ByVal lpCaption As Long, ByVal uType As Long) As Long
#End If


Public Sub Test()
 
    Dim inputText As String, translation As String
 
    inputText = InputBox("Enter English text to translate to Spanish")
    If inputText <> "" Then
        translation = GoogleTranslate(inputText, "en", "es")   'English to Spanish
        Range("A1").Value = inputText
        Range("A2").Value = translation
        MsgBoxW inputText & vbCrLf & translation
    End If
     
End Sub


'Google Language Codes - full list at https://cloud.google.com/translate/docs/languages/

'Auto Detect = 0 Bulgarian = bg Finnish = fi Hungarian = hu Latvian = lv Russian = ru Turkish = tr
'English = en  Catalan = ca  French = fr  Icelandic = is Lithuanian = lt Serbian = sr Ukrainian = uk
'Afrikaans = af Chinese = zh Galician = gl Indonesian = id Macedonian = mk Slovak = sk Urdu = ur
'Albanian = sq Croatian = hr Georgian = ka Irish = ga Malay = ms Slovenian = sl Vietnamese = vi
'Arabic = ar Czech = cs German = de Italian = it Maltese = mt Spanish = es Welsh = cy
'Armenian = hy Danish = da Greek = el Japanese = ja Norwegian = no Swahili = sw Yiddish = yi
'Azerbaijani = az Dutch = nl Gujarati = gu Kannada = kn Persian = fa Swedish = sv
'Basque = eu Esperanto = eo Haitian_Creole = ht Korean = ko Polish = pl Tamil = ta
'Belarusian = be Estonian = et Hebrew = iw Lao = lo Portuguese = pt Telugu = te
'Bengali = bn Filipino = tl Hindi = hi Latin = la Romanian = ro Thai = th

Public Function GoogleTranslate(text As String, Optional fromLanguage As String = "en", Optional toLanguage As String = "es") As String

    Static objHTTP As Object
    Dim URL As String
 
    If objHTTP Is Nothing Then Set objHTTP = CreateObject("MSXML2.XMLHTTP")
 
    If Val(Application.Version) >= 15 Then
        'Excel 2013 and later versions - encode the Google Translate URL using the WorksheetFunction.EncodeURL function
        URL = "https://translate.google.com/m?hl=" & LCase(fromLanguage) & "&sl=" & LCase(fromLanguage) & "&tl=" & LCase(toLanguage) & "&ie=UTF-8&prev=_m&q=" & WorksheetFunction.EncodeURL(text)
    Else
        'Excel 2010 and earlier versions - encode the Google Translate URL using our own function
        URL = "https://translate.google.com/m?hl=" & LCase(fromLanguage) & "&sl=" & LCase(fromLanguage) & "&tl=" & LCase(toLanguage) & "&ie=UTF-8&prev=_m&q=" & URLEncode(text)
    End If
 
    With objHTTP
        .Open "GET", URL, False
        .setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
        .Send ("")
        If InStr(.responseText, "<div class=""result-container""") > 0 Then
            'OLD GoogleTranslate = Clean(RegexExecute(.responseText, "div[^""]*?""result-container"".*?>(.+?)</div>"))
            GoogleTranslate = Clean(RegexExecute(.responseText, "div[^""]*?""result-container"".*?>([\s\S]+?)</div>"))
        Else
            GoogleTranslate = CVErr(xlErrValue)
        End If
    End With

End Function


Private Function Clean(Val As String) As String

    Val = Replace(Val, "&quot;", """")
    Val = Replace(Val, "%2C", ",")
    Val = Replace(Val, "&#39;", "'")
    Clean = Val

End Function


Private Function RegexExecute(str As String, reg As String, Optional matchIndex As Long, Optional subMatchIndex As Long) As String

    Static RegEx As Object
    Dim matches As Object

    On Error GoTo ErrorHandler

    If RegEx Is Nothing Then Set RegEx = CreateObject("VBScript.RegExp")
    RegEx.Pattern = reg
    RegEx.Global = Not (matchIndex = 0 And subMatchIndex = 0)
    If RegEx.Test(str) Then
        Set matches = RegEx.Execute(str)
        RegexExecute = matches(matchIndex).SubMatches(subMatchIndex)
        Exit Function
    End If
 
ErrorHandler:
    RegexExecute = CVErr(xlErrValue)

End Function


Private Function MsgBoxW(Prompt As String, Optional Buttons As VbMsgBoxStyle = vbOKOnly, Optional Title As String = "Microsoft Excel") As VbMsgBoxResult
    Prompt = Prompt & vbNullChar 'Add null terminators
    Title = Title & vbNullChar
    MsgBoxW = MessageBoxW(Application.hWnd, StrPtr(Prompt), StrPtr(Title), Buttons)
End Function


'VBA function to URL-encode a string because WorksheetFunction.EncodeURL is only available in Excel 2013 and later
'https://stackoverflow.com/a/218199
'with late binding of Microsoft ActiveX Data Objects, so no VBA project reference is required

Public Function URLEncode(ByVal StringVal As String, Optional SpaceAsPlus As Boolean = False) As String

    Dim bytes() As Byte, b As Byte, i As Integer, space As String
 
    Const adTypeBinary = 1
    Const adTypeText = 2
    Const adModeReadWrite = 3

    If SpaceAsPlus Then space = "+" Else space = "%20"
 
    If Len(StringVal) > 0 Then
        With CreateObject("ADODB.Stream") 'New ADODB.Stream
            .Mode = adModeReadWrite
            .Type = adTypeText
            .Charset = "UTF-8"
            .Open
            .WriteText StringVal
            .Position = 0
            .Type = adTypeBinary
            .Position = 3 ' skip BOM
            bytes = .Read
        End With
     
        ReDim result(UBound(bytes)) As String
     
        For i = UBound(bytes) To 0 Step -1
            b = bytes(i)
            Select Case b
                Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
                    result(i) = Chr(b)
                Case 32
                    result(i) = space
                Case 0 To 15
                    result(i) = "%0" & Hex(b)
                Case Else
                    result(i) = "%" & Hex(b)
            End Select
        Next i
     
        URLEncode = Join(result, "")
    End If
 
End Function


Public Sub RegisterGoogleTranslateFunction()

    Dim strFunc As String 'name of the function you want to register
    Dim strDesc As String 'description of the function itself
    Dim strArgs() As String 'description of function arguments
 
    ReDim strArgs(1 To 3) 'The upper bound is the number of arguments in your function
    strFunc = "GoogleTranslate"
    strDesc = "Translates a text string from the specified language (default English) to another language. Language codes are listed at https://cloud.google.com/translate/docs/languages/"
    strArgs(1) = "Text string to translate."
    strArgs(2) = "Translate FROM language code.  Default ""en"" (English); use ""0"" to automatically detect the language."
    strArgs(3) = "Translate TO language code.  Default ""es"" (Spanish)."
 
    'Application.MacroOptions arguments: [Macro], [Description], [HasMenu], [MenuText], [HasShortcutKey], [ShortcutKey], [Category], [StatusBar], [HelpContextID], [HelpFile], [ArgumentDescriptions]
    'https://stackoverflow.com/questions/27962808/excel-user-defined-functions-cant-use-argumentdescriptions-in-excel-2007-im-t
 
    #If VBA7 Then
        'Excel 2010 and later - ArgumentDescriptions argument is supported
        Application.MacroOptions Macro:=strFunc, Description:=strDesc, Category:="User Defined", ArgumentDescriptions:=strArgs
    #Else
        'Excel 2007 and earlier - ArgumentDescriptions argument is not supported
        Application.MacroOptions Macro:=strFunc, Description:=strDesc, Category:="User Defined"
    #End If
     
End Sub


Public Sub DeregisterGoogleTranslateFunction()

    Dim strFunc As String 'name of the function you want to deregister
 
    strFunc = "GoogleTranslate"
    Application.MacroOptions Macro:=strFunc, Description:=Empty, Category:=Empty
 
End Sub
Thank you so much, this works flawlessly. I tried to get into the RegEx but I was stuck.

I added
Code:
If text <> "" Then
before
Code:
If objHTTP Is Nothing Then Set objHTTP = CreateObject("MSXML2.XMLHTTP")

and
Code:
end if
after the
Code:
end with
within the GoogleTranslate function.
That helped a bit with empty cells, so that I don't need to use the ISBLANK function in the formula per cell.

Also I think I found 1 issue when the cell contains a lot of text and the output is larger than certain number (5000 characters?)
Not sure where the limitation comes from as I can't reproduce it if I manually enter all the text in google translate.

You can test it by putting the below quote all in 1 cell.


Morwenna Blast had always loved derelict Exeter with its dripping, defeated ditches. It was a place where she felt afraid.

She was an articulate, cowardly, whiskey drinker with greasy fingers and wide arms. Her friends saw her as a jittery, jealous juggler. Once, she had even made a cup of tea for a friendly baby flamingo. That's the sort of woman he was.

Morwenna walked over to the window and reflected on her quiet surroundings. The sleet rained like hopping donkeys.

Then she saw something in the distance, or rather someone. It was the figure of Sally Russell. Sally was a remarkable queen with ugly fingers and ginger arms.

Morwenna gulped. She was not prepared for Sally.

As Morwenna stepped outside and Sally came closer, she could see the wrong glint in her eye.

Sally gazed with the affection of 3034 incredible mammoth mice. She said, in hushed tones, "I love you and I want love."

Morwenna looked back, even more sleepy and still fingering the bendy guillotine. "Sally, oh my God they killed Kenny," she replied.

They looked at each other with jumpy feelings, like two hard, helpless horses loving at a very generous disco, which had reggae music playing in the background and two intelligent uncles drinking to the beat.

Morwenna regarded Sally's ugly fingers and ginger arms. "I feel the same way!" revealed Morwenna with a delighted grin.

Sally looked puzzled, her emotions blushing like a super, scary sausage.

Then Sally came inside for a nice glass of whiskey.



Gemma Gloop was thinking about Wenna Cox again. Wenna was a snotty deity with feathery abs and fluffy arms.

Gemma walked over to the window and reflected on her rural surroundings. She had always loved sunny Exeter with its kind, knotty kettles. It was a place that encouraged her tendency to feel fuzzy.

Then she saw something in the distance, or rather someone. It was the a snotty figure of Wenna Cox.

Gemma gulped. She glanced at her own reflection. She was a cold-blooded, hopeful, beer drinker with greasy abs and vast arms. Her friends saw her as a heavy, harsh hero. Once, she had even rescued a drab old lady from a burning building.

But not even a cold-blooded person who had once rescued a drab old lady from a burning building, was prepared for what Wenna had in store today.

The drizzle rained like hopping rats, making Gemma happy. Gemma grabbed a damp rock that had been strewn nearby; she massaged it with her fingers.

As Gemma stepped outside and Wenna came closer, she could see the great glint in her eye.

"Look Gemma," growled Wenna, with a spiteful glare that reminded Gemma of snotty mice. "It's not that I don't love you, but I want some more Facebook friends. You owe me 4384 dollars."

Gemma looked back, even more happy and still fingering the damp rock. "Wenna, I just don't need you in my life any more," she replied.

They looked at each other with surprised feelings, like two hungry, hissing hamsters jumping at a very predatory funeral, which had orchestral music playing in the background and two rude uncles swimming to the beat.

Suddenly, Wenna lunged forward and tried to punch Gemma in the face. Quickly, Gemma grabbed the damp rock and brought it down on Wenna's skull.

Wenna's feathery abs trembled and her fluffy arms wobbled. She looked cross, her wallet raw like a repulsive, rabblesnatching ruler.

Then she let out an agonising groan and collapsed onto the ground. Moments later Wenna Cox was dead.

Gemma Gloop went back inside and made herself a nice drink of beer.

Rob Wishmonger looked at the squidgy hawk in his hands and felt surprised.

He walked over to the window and reflected on his noisy surroundings. He had always loved deserted Sludgeside with its blue-eyed, blue beaches. It was a place that encouraged his tendency to feel surprised.

Then he saw something in the distance, or rather someone. It was the figure of Harry Giantbulb. Harry was a proud gamer with sticky eyes and slimy hands.

Rob gulped. He glanced at his own reflection. He was a virtuous, snotty, brandy drinker with wide eyes and sloppy hands. His friends saw him as an annoying, agreeable academic. Once, he had even brought a jealous baby bird back from the brink of death.

But not even a virtuous person who had once brought a jealous baby bird back from the brink of death, was prepared for what Harry had in store today.

The clouds danced like shouting toads, making Rob relaxed.

As Rob stepped outside and Harry came closer, he could see the loud glint in his eye.

"I am here because I want a wifi code," Harry bellowed, in an understanding tone. He slammed his fist against Rob's chest, with the force of 9278 pigeons. "I frigging love you, Rob Wishmonger."

Rob looked back, even more relaxed and still fingering the squidgy hawk. "Harry, eat my shorts," he replied.

They looked at each other with active feelings, like two funny, fair foxes drinking at a very charming holiday, which had drum and bass music playing in the background and two cowardly uncles jumping to the beat.

Rob studied Harry's sticky eyes and slimy hands. Eventually, he took a deep breath. "I'm sorry, but I can't give you a wifi code," he explained, in pitying tones.

Harry looked stressed, his body raw like a kaleidoscopic, keen kettle.

Rob could actually hear Harry's body shatter into 7879 pieces. Then the proud gamer hurried away into the distance.

Not even a glass of brandy would calm Rob's nerves tonight.
 
Last edited by a moderator:
Upvote 0

Excel Facts

Save Often
If you start asking yourself if now is a good time to save your Excel workbook, the answer is Yes

Forum statistics

Threads
1,224,820
Messages
6,181,160
Members
453,021
Latest member
Justyna P

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top