我在LDAP方面的最初目的是返回当前为活跃员工的指定组的所有活动成员。
我来到这个解决方案:
Public Const ADConString = "Provider=ADsDSOObject;
Encrypt Password=False;
Integrated Security=SSPI;
Data Source=
LDAP://Domain:Numbers/DC=ROOT,
DC=Someplace,OU=SomePlace;
Mode=Read
Bind Flags=0;ADSI Flag=-2147483648"
Public Function getActiveDirectoryGroup(groupName As String)
Dim cmd As ADODB.Command
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim test As Variant
Set cmd = CreateObject("ADODB.Command")
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open ADConString
cmd.CommandText =
"SELECT sn,adspath,cn,givenname,userAccountControl
FROM 'LDAP://RootPlace _
"WHERE MemberOf='cn=" & groupName &
",CN=SomePlace,DC=KMC,DC=SomePlace' " & _
"AND userAccountControl<>514
AND sn <>'name1' AND sn <>'name2'
AND sn <>'name3' " & _
"ORDER BY givenname"
Debug.Print cmd.CommandText
cmd.ActiveConnection = cn
Set rs = cmd.execute
groupPath = rs.Fields("adspath").Value
Do While Not rs.EOF
'Debug.Print rs.Fields("adspath").Value
Debug.Print rs.Fields("givenname").Value & " "
& rs.Fields("sn").Value & " "
& rs.Fields("userAccountControl")
'Debug.Print rs.Fields("cn").Value
rs.MoveNext
Loop
End Function
现在,如果你把它传给一个组,这个解决方案是有效的,但我想扩展它,这样有人只能抓住活跃成员或摆脱sn <>'name1' AND sn <>'name2' AND sn<>'name3'
条件。
到目前为止,我已经构建了这个类
Option Compare Database
Option Explicit
Private pADConnectionString As String
Private pRootLocation As String
Private pGroupName As String
Private Sub class_Initialize()
pADConnectionString = "Provider=ADsDSOObject;
Encrypt Password=False;
Integrated Security=SSPI;
Data Source=
LDAP://Domain:Numbers/DC=ROOT,
DC=Someplace,OU=SomePlace;
Mode=Read
Bind Flags=0;ADSI Flag=-2147483648"
pRootLocation = getNC()
End Sub
Sub retreiveUsers()
End Sub
Public Property Get ADConnectionString() As Double
ADConnectionString = pADConnectionString
End Property
Public Property Let ADConnectionString(connectionString As Double)
pADConnectionString = connectionString
End Property
Function getNC()
Set objRoot = GetObject("LDAP://RootDSE")
getNC = objRoot.Get("defaultNamingContext")
End Function
Public Property Get groupName() As String
groupName = pGroupName
End Property
Public Property Let groupName(group As String)
pGroupName = group
End Property
我对课程有点生疏,我不太确定如何在这个课程中引入动态WHERE
语句。那么,我是否应继续沿着这条道路前进,如果是这样,我可以考虑采用哪种解决方案来处理WHERE
条款?
我正在考虑使用一些草率的内容,例如将用户发送的内容附加到已应用于新whereStatement
私有变量的内容的setter,这样它可以继续附加到WHERE
条款。我担心的是,如果没有完全清楚,我就无法删除sn<>'Name1'
答案 0 :(得分:1)
你可以overload
这个功能
也许你正在寻找这样的东西:
Function getActiveDirectoryGroup(Optional groupName as string)
Dim sQuery as string
if LenB(groupname) = 0 then
sQuery = "<general sql statement>"
else
sQuery = "<sql statement with conditions>"
end if
End Function
修改
在VBA中,无法在更广泛的OOP语言(例如C ++,C#和Java)中找到函数重载。
但是,使用Optional参数可以模拟行为。
答案 1 :(得分:1)
VBA中的类提供的优势远远超过标准模块,特别是对于您尝试在此处执行的操作。在VBA中,我认为类是将密切相关的函数/方法和属性组合成可重用的“容器”的一种方式。在我的大多数课程中,我开始在标准模块中获得我需要的东西然后在事后将其变成一个类。使用类,您可以设置一组属性,然后运行其中一个方法,而使用模块,您需要将所有属性作为参数传入,或者使用全局变量或自定义类型或类来保存属性。所以是的,类在那里有一个小优势,但主要是程序员。在您的情况下,类不提供标准模块不提供的任何功能。
如果继续你的课堂观念肯定是一个可接受的主张,我认为你应该真正推进你在问题结尾时提出的“草率”想法。我认为这可以称为“谓词构建器”方法/函数。如果您希望能够在不清除整个内容的情况下删除特定条件,则必须自行构建。使用谓词构建器函数添加条件时,只需将每个附加条件放入某种容器对象中,如制作的ADO Recordset,Dictionary对象或Array。这样,您始终可以查看结构/容器并添加,编辑或删除条目。然后你需要一个小函数来遍历你的容器并构造完整的WHERE语句。
但请记住,在这种情况下,一堂课对你来说很少。是的,它将允许您封装和隐藏一些基础机制。例如,当您添加条件时,它将附加到您的调用代码不必了解的某种私有容器/结构/变量。然后,当您再次调用Get方法时,您的调用代码不应该知道标准是如何存储,制作等的。但是您应该能够在没有类的情况下完成所有这些工作,尽管它将更加“宽松”,当然还不够理想。
答案 2 :(得分:0)
还有一件我不确定你知道的事情,但对你来说这可能也很有用;也许它甚至可能是你最终要找的东西。
确实,为此使用类模块并不是非常有用,因为在创建此对象的多个实例时没有实际用途。
但是,您可以使标准模块的行为类似于它们在C#中所谓的“静态类”,尽管VBA没有实现静态类的概念。
考虑一下C#中静态类的定义:
静态类与非静态类基本相同,但有一个区别:静态类无法实例化。在 换句话说,您不能使用new关键字来创建变量 类类型。因为没有实例变量,所以您可以访问 通过使用类名本身的静态类的成员。例如, 如果你有一个名为UtilityClass的静态类,它有一个 名为MethodA的公共方法,您调用方法如图所示 以下示例:
C# UtilityClass.MethodA();
作为这个概念的证明,请尝试以下事项:
将相同的代码放入两个标准模块中,并将其称为m_Class
和m_Class2
:
Option Explicit
Private m_Number As Long
Public Function store_number(value As Long)
m_Number = value
End Function
Public Function get_number()
get_number = m_Number
End Function
现在,创建第三个存储以下两个子标准的标准模块:
Sub test()
m_Class.store_number (10)
m_Class2.store_number (5)
End Sub
Sub test_2()
MsgBox (m_Class.get_number)
MsgBox (m_Class2.get_number)
End Sub
我想用这个测试表明,两个标准模块实际上是两个独立的实例,每个实例都有自己的私有属性,每个实现相同的功能。
所以你会注意到标准模块的行为非常类似于静态类(尽管它的内部底层机制并不相同)。
我建议你创建一个标准模块并实现这个逻辑 我认为创建这样一个'静态'类很有用,因为正如你所提到的,你会重复使用它,而你不需要多个类的实例。