spa*_*sen 10 excel vba substring ldap excel-vba
我正在编写一个宏,它采用LDAP格式的名称列表将它们转换为First,Last(region).对于那些不知道LDAP是什么样的人,它在下面:
CN=John Smith (region),OU=Legal,DC=example,DC=comand
Run Code Online (Sandbox Code Playgroud)
在Excel VBA中,我似乎无法使用string.substring(start,end).对Google的搜索似乎表明,Mid(字符串,开头,结尾)是最好的选择.问题是:在Mid中,end的整数是从开始的距离,而不是字符的实际索引位置.这意味着不同的名称大小将具有不同的结束位置,并且我不能使用索引")"来查找区域的结尾.由于所有名称都以CN =开头,我可以正确找到第一个子字符串的结尾,但我找不到")"因为名称长度不同.
我在下面有一些代码:
mgrSub1 = Mid(mgrVal, InStr(1, mgrVal, "=") + 1, InStr(1, mgrVal, "\") - 4)
mgrSub2 = Mid(mgrVal, InStr(1, mgrVal, ","), InStr(1, mgrVal, ")") - 10)
manager = mgrSub1 & mgrSub2
Run Code Online (Sandbox Code Playgroud)
有没有人知道一种实际使用设定终点的方法,而不是一个距离一开始就有这么多值的终点?
gbi*_*chi 12
这是vba ..没有string.substring;)
这更像是VB 6(或下面的任何一个)..所以你被mid,instr,len(为了得到一个字符串的总len)所困扰..我认为你错过了len来获得一个字符串中的字符总数?如果您需要澄清,请发表评论.
编辑:
另一个快速破解..
Dim t As String
t = "CN=Smith, John (region),OU=Legal,DC=example,DC=comand"
Dim s1 As String
Dim textstart As Integer
Dim textend As Integer
textstart = InStr(1, t, "CN=", vbTextCompare) + 3
textend = InStr(1, t, "(", vbTextCompare)
s1 = Mid(t, textstart, textend - textstart)
MsgBox s1
textstart = InStr(1, t, "(", vbTextCompare) + 1
textend = InStr(1, t, ")", vbTextCompare)
s2 = Mid(t, textstart, textend - textstart)
MsgBox s2
Run Code Online (Sandbox Code Playgroud)
显然你的问题是,因为你需要第二个参数的差异,你应该总是做一些数学...
我不确定我的问题是否正确,但这是我(希望)你想要的实现:
Function GetName(arg As String) As String
parts = Split(arg, ",")
For Each p In parts
kv = Split(p, "=")
Key = kv(0)
Value = kv(1)
If Key = "CN" Then
commonName = Value
End If
Next p
regIndex = InStr(1, commonName, "(")
region = Mid(commonName, regIndex, Len(commonName) - regIndex + 1)
parts = Split(commonName, " ")
first = parts(0)
last = parts(1)
GetName = first & ", " & last & " " & region
End Function
Sub test()
'Prints "John, Smith (region)"
Debug.Print GetName("CN=John Smith (region),OU=Legal,DC=example,DC=comand")
End Sub
Run Code Online (Sandbox Code Playgroud)
它说明了使用Split和Mid功能。
这是一个快速而肮脏的实现,仅用于说明目的。要在实际代码中使用它,您需要添加几个检查(例如,kv和parts集合至少包含两个元素)。
UPD:要覆盖CN域的两种可能的格式,分别是"last\, first (region)"和"first last (region)"使事情少一点凌乱我会采取正则表达式的办法。
Function GetName(arg As String) As String
Dim RE As Object, REMatches As Object
Set RE = CreateObject("vbscript.regexp")
With RE
.MultiLine = False
.Global = False
.IgnoreCase = True
.Pattern = "CN=(\w+)\s*?(\\,)?.*?,"
End With
Set REMatches = RE.Execute(arg)
If REMatches.Count < 1 Then
GetName = ""
Return
End If
cn = REMatches(0).Value
withComma = (InStr(1, cn, "\,") > 0)
If withComma Then
lastIndex = 0
firstIndex = 2
regionIndex = 3
patt = "(\w+)\s*?(\\,)?\s*?(\w+)\s*(\(.*?\))"
Else
lastIndex = 1
firstIndex = 0
regionIndex = 2
patt = "(\w+)\s*?(\w+)\s*(\(.*?\))"
End If
Set RE = CreateObject("vbscript.regexp")
With RE
.MultiLine = False
.Global = False
.IgnoreCase = True
.Pattern = patt
End With
Set REMatches = RE.Execute(arg)
If REMatches.Count < 1 Then
GetName = ""
Return
End If
Set m = REMatches(0)
first = m.SubMatches(firstIndex)
last = m.SubMatches(lastIndex)
region = m.SubMatches(regionIndex)
GetName = first & ", " & last & " " & region
End Function
Sub test()
' Prints "first, last (AAA-somewhere)" two times.
Debug.Print GetName("CN=last\, first (AAA-somewhere),OU=IT,OU=Users,OU=somewhere - aaa,OU=place,DC=aaa,DC=com")
Debug.Print GetName("CN=first last (AAA-somewhere),OU=IT,OU=Users,OU=somewhere - aaa,OU=place,DC=aaa,DC=com")
End Sub
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
55879 次 |
| 最近记录: |