LDAP - 活动目录 - 我可以/应该使用A类吗?

时间:2013-10-24 18:10:10

标签: class vba ms-access active-directory ldap

我在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'

等个别条件语句。

3 个答案:

答案 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_Classm_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

我想用这个测试表明,两个标准模块实际上是两个独立的实例,每个实例都有自己的私有属性,每个实现相同的功能。
所以你会注意到标准模块的行为非常类似于静态类(尽管它的内部底层机制并不相同)。

我建议你创建一个标准模块并实现这个逻辑 我认为创建这样一个'静态'类很有用,因为正如你所提到的,你会重复使用它,而你不需要多个类的实例。