LDAP形式の名前のリストを取得して、それらをFirst、Last(地域)に変換するマクロを作成しています。 LDAPの外観がわからない場合のために、以下に示します。
CN=John Smith (region),OU=Legal,DC=example,DC=comand
Excel VBAでは、string.substring(start、end)を使用できないようです。 Googleを検索すると、Mid(string、start、end)が最適なオプションであることがわかります。問題はこれです: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
開始から非常に多くの値があるエンドポイントの代わりに、設定されたエンドポイントを実際に使用する方法を誰かが知っていますか?
これは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
明らかにあなたの問題は、2番目のパラメーターの差分が必要なため、常にいくつかの計算を行う必要があるということです...
私はあなたの質問が正しかったかわかりませんが、ここにあなたが望むものの(うまくいけば)私の実装があります:
_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
_
Split
関数とMid
関数の使用法を示しています。
これは、説明のみを目的とした迅速でダーティな実装です。実際のコードで使用するには、いくつかのチェックを追加する必要があります(たとえば、kv
およびparts
コレクションに少なくとも2つの要素が含まれていること)。
PD: CNフィールドの2つの可能な形式、つまり"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
_
InStrを使用して、値を区切る3つの文字の位置を見つけてから、それらに左/右を使用します。
これは私が一緒にハッキングしたものです:
Dim tmp, new_string, first, last, region As String
tmp = "CN=John Smith (region),OU=Legal,DC=example,DC=comand"
new_string = Right(tmp, Len(tmp) - 3)
' John Smith (region),OU=Legal,DC=example,DC=comand
new_string = Left(new_string, (InStr(1, new_string, ",") - 2))
' John Smith (region)
region = Right(new_string, Len(new_string) - InStr(1, new_string, "("))
' region
new_string = Left(new_string, (InStr(1, new_string, "(") - 2))
' John Smith
last = Right(new_string, Len(new_string) - InStr(1, new_string, " "))
' Smith
first = Left(new_string, (InStr(1, new_string, " ") - 1))
' John
次に、それらを連結して、必要な文字列出力を取得します。
これで始めれば、姓名のビットは簡単です。
MsgBox Split(Mid$(sLDAP, 4), ")")(0) & ")"