|
本帖最后由 weiyingde 于 2020-2-14 21:18 编辑
怪哉,怪种的Replace函数——求开塞!
这两天,与我交往几年了的Replace竟然这样折腾我!不知是我的蠢笨,还是它的狡猾,Replace对我来说,竟是这样的熟悉和陌生!!由此推之,在整个Office家族中,该有多少个“Replace”的存在!!!2010年,开启了我与Excel、Word和PowerPoint的摸爬滚打;而今,十年过去了……而我,我对它还是如此的无知,想想真令人汗颜和后怕!!尽管如此,问题如鲠在喉,只好厚着脸皮,仍旧发这个低级和幼稚的求助,愿过路人,搭手施援,排忧解惑,老朽先谢了。
问题是这样的。
“EnToCh”是YZC51发的一个帖子中的中英文互译的函数,帖子见http://club.excelhome.net/thread-1508743-1-1.html五楼,代码如下:
Public Function EnToCh(rng As String)
Dim xml
Dim URL$, EngSentence$
Set xml = CreateObject("MSXML2.XMLHTTP")
Debug.Print Asc(rng)
aasc = Asc(rng)
If aasc > 64 And aasc < 123 Then
URL = "https://translate.google.cn/m?hl=en&sl=enN&tl=zh-CN&ie=UTF-8&prev=_m&q=" & rng
Else
URL = "https://translate.google.cn/m?hl=en&sl=zh-CN&tl=enN&ie=UTF-8&prev=_m&q=" & GetURL(rng) '在这个地方引用
End If
With xml
.Open "GET", URL, False
.send
If InStr(.responseText, "<div dir=""ltr"" class=""t0"">") > 0 Then
EnToCh = Split(Split(.responseText, "<div dir=""ltr"" class=""t0"">")(1), "</div><")(0)
End If
End With
End Function
Function GetURL$(txt$) '
For i = 1 To Len(txt)
txt1 = Mid(txt, i, 1)
If Abs(Asc(txt1)) < 128 Then
GetURL = GetURL & txt1
Else
GetURL1 = Application.Hex2Bin(Left(Hex(AscW(txt1)), 2), 8)
GetURL1 = GetURL1 & Application.Hex2Bin(Right(Hex(AscW(txt1)), 2), 8)
GetURL1 = Application.Replace(Application.Replace(GetURL1, 11, , 10), 5, , 10)
GetURL2 = "%E" & Application.Bin2Hex(Left(GetURL1, 4))
GetURL2 = GetURL2 & "%" & Application.Bin2Hex(Mid$(GetURL1, 5, 8))
GetURL2 = GetURL2 & "%" & Application.Bin2Hex(Mid$(GetURL1, 13, 8))
GetURL = GetURL & GetURL2
End If
Next
End Function
主函数“EnToCh”包含一个名为“GetURL”,为了将“EnToCh”推荐给Excel VBA的两兄弟——Word VBA 和PowerPoint VBA,需要对其子函数“GetURL”进行改造,否则将会导致它在新环境中调皮捣蛋,于是不得不对其中使用的“Replace”动动手术,手术很小很快,自认为很成功,看不出有什么问题:
Function GetURLA$(txt$) '……………
For i = 1 To Len(txt)
txt1 = Mid(txt, i, 1)
If Abs(Asc(txt1)) < 128 Then
GetURL = GetURL & txt1
Else
With Application.WorksheetFunction
'Application在VBA代码中等同于Application.WorksheetFunction吧?将源代码对应的地方改一下,
'应该没问题吧,可是,你试一试,在“EnToCh”函数引用“GetURL”改为“GetURLA”,试一试,保证运行不了。
'郁闷呀…………………………
'此处不能运行,下面的函数“GetURLX”是对应在Word中的函数,仍然不能运行。
GetURL1 = .Hex2Bin(Left(Hex(AscW(txt1)), 2), 8)
GetURL1 = GetURL1 & .Hex2Bin(Right(Hex(AscW(txt1)), 2), 8)
GetURL1 = .Replace(.Replace(GetURL1, 11, , 10), 5, , 10)
GetURL2 = "%E" & .Bin2Hex(Left(GetURL1, 4))
GetURL2 = GetURL2 & "%" & .Bin2Hex(Mid$(GetURL1, 5, 8))
GetURL2 = GetURL2 & "%" & .Bin2Hex(Mid$(GetURL1, 13, 8))
GetURLA = GetURLA & GetURL2
End With
End If
Next
End Function
出乎意料,弹出“参数不可选”对话框,“GetURLA”函数居然罢工了!!
看看元凶:
Application.Replace(Application.Replace(GetURL1, 11, , 10), 5, , 10)
“Replace”在其中捣鬼!!
“Replace”,熟悉的Replace,我还不认识你吗?!
我知道,在Excel中,有两处Replace函数的存在:
1、一个是VBA工程函数:Repalce。它在VBA代码中有两种写法:
⑴直接使用:sr=replace("中华人民共和国公民", "人民共和国公民", "老百姓")。
⑵加个VBA:sr = VBA.replace("中华人民共和国公民", "人民共和国公民", "老百姓")。
2、另一个是WorksheetFunction中的replace工作表函数。在Excel VBA中使用该函数也有两种写法:
⑴sr = Application.WorksheetFunction.replaceApplication.Replace("中华人民国共和国公民", 3, 7, "老百姓")
⑵sr = Application.Replace("中华人民国共和国公民", 3, 7, "老百姓")
结论:
⑴在Excel中确有两个Replace函数:一个是VBA工程函数,一个是Excel工作表函数,且两个函数在VBA代码中的写法不一样。
⑵两个函数的参数个数类型不一样:工程函数Replace有三个参数,都是字符串类型;工作表函数Replace四个函数:一、四时字符串,二、三两个参数是integer类型的,是数字。
⑶根据你在Excel代码中的写法,推断这个Replace应该是工作表函数。
试验:
试验一:在Excel VBA环境下。
用两个例子进行测试:sr1=“Yes” sr2=“很好”
主函数“EnToCh”分别调用子函数“GetRUL”“GetRULA”的结果如下:
甲、测试参数:sr1
调用“GetRUL” msgbox EnToCh(sr1)——“是”,运行正常;
调用“GetRULA” msgbox EnToCh(sr1)——“是”,运行正常;
乙、测试参数:sr2
调用“GetRUL” msgbox EnToCh(sr1)——“是”,运行正常;
调用“GetRULA” msgbox EnToCh(sr1)——不能运行,弹出“参数不可选”。
试验二:在Word VBA环境下,效果如同Excel环境一样。
结论:参数为英文,实现英文转中文,两个子程序都能运行。说明“GetRULA”中的Replace是工作表函数。
试验三:保持子函数中文如sr1=“很好”参数不变,分别以“GetRUL”“GetRULA”再试验。
甲、在Excel VBA中:
With Application.WorksheetFunction
……
GetURL1 = VBA.Replace(VBA.Replace(GetURL1, 11, 10), 5, 10)
……
end with
……结果虽是乱码,可能是查找和替换的地方不对,但Replace能出结果,运行正常,按写法,毋庸置疑Replace是VBA工程函数。
乙、在Word VBA中。
With Excel. Application.WorksheetFunction
……
⑴GetURL1 = .Replace(.Replace(GetURL1, 11, , 10), 5, , 10)
⑵GetURL1 = VBA.Replace(VBA.Replace(GetURL1, 11, , 10), 5, , 10)
⑶GetURL1 = VBA.Replace(VBA.Replace(GetURL1, 11, 10), 5, 10)
……
end with
实验结果和推断:
⑴弹出“要求对象”对话框,说明“Repalce”的父对象不是“Excel. Application.WorksheetFunction”,简言之,“Replace”不是Excel工作表函数。
⑵弹出“参数不可选”对话框,说明“Repalce”。在Office家族的“三剑客”Excel、Word和PPT VBA中有工程函数VBA,是处理字符串的好手,在正则、Word替换和查找中经常用到。它有三个参数,如 ReplaceApplication.Replace("中华人民国共和国公民", “公民”, "老百姓")=“中华人民国共和国老百姓”,此例可以看出,三个参数都是字符串;而Excel工作表函数Replace,如 Application.WorksheetFunction.replaceApplication.Replace("中华人民国共和国公民", 3, 7, "老百姓")=“中华人民国共和国老百姓”,有四个参数,一、四两个是字符串式参数,二、三两个是数值型参数。参看原表达式:Replace(GetURL1, 11, , 10), 5, , 10),基本都是数值,特别是二、三(第三个没有?省略了?)两个,尽管第三没有了,所以肯定地说它是Excel工作表函数的可能性很大。
⑶尽管是VBA工程函数的可能性不是很大,试一试,擦掉一个空参数(也就是抹掉一个蛮有参数的英文逗号)结果弹出“运行时错误,要求对象”……说明也不是参数的问题……
反复试验, Replace,仿佛是一个顽劣的,始终不肯应允,不肯放行……
呜呼哀哉!!多重验证,花了我两天的时间,始终没看懂你这个Replace的真容!
你这个挠心烧脑的Replace,你到底何路神仙,那方妖孽?
期盼E友、老师、大侠借我一双慧眼,将你辨识!!
在线^^^^^^^^^
盼你回音^^^^^^ |
|