2013-10-24 3 views
0

Моя первоначальная цель с LDAP состояла в том, чтобы вернуть всех активных членов указанной группы, которая в настоящее время является активным сотрудником.LDAP - Active Directory - может/должен использовать класс?

Я пришел к этому решению:

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, таким образом, что он может продолжать добавлять в предложение WHERE. Мое беспокойство заключается в том, что, если не считать полной ясности, я не смогу удалить отдельные условные заявления, такие как sn<>'Name1'

ответ

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 

Редактировать

Функция перегрузки, как вы найдете его в более обширных языках объектно-ориентированного программирования, таких как C++, C# и Java не представляется возможным в VBA.
Однако, используя необязательный параметр, вы можете имитировать поведение.

+0

Моя цель состояла в том, чтобы динамически изменять то, что получили пользователи. Иногда я хотел бы, чтобы группа возвращалась с неактивными пользователями, у которых есть слова abc там, но в других случаях я хотел бы сделать что-то совершенно другое. Моя цель в классе заключалась в том, чтобы позволить пользователю динамически создавать то, что они хотели с легкостью. Проблема с этим решением заключается в том, что в конечном итоге это приведет к очень вложенному дереву операторов if и большому количеству дополнительных значений. – Elias

+0

Vba не поддерживает наследование, поэтому вы не можете сделать один базовый класс унаследованным от него количеством настраиваемых классов.Единственный способ, по которому я вижу возможность создания повторно используемого класса без настройки, - передать всю строку запроса методу класса и составить строку запроса в функциях callibg. И/или, как вы упомянули, передайте предложение where в качестве параметра. – Trace

+0

Таким образом, вы все равно можете использовать предоставленный мной код. Метод класса может стандартно предоставить вам весь набор результатов, причем предложение where является необязательным параметром. Таким образом, у вас не будет много условий. – Trace

1

Классы в VBA предлагают очень мало преимуществ перед стандартными модулями, особенно для того, что вы пытаетесь сделать здесь. В VBA я считаю классы как способ группировки тесно связанных функций/методов и свойств в многоразовый «контейнер». С большинством моих классов я начинаю получать то, что мне нужно в стандартном модуле, а затем превращаю его в класс после факта. С помощью класса вы можете установить набор свойств, а затем запустить один из методов, тогда как с модулями вам необходимо передать все свойства в качестве аргументов или использовать глобальные переменные или, возможно, настраиваемый тип или класс, просто чтобы сохранить свойства. Так что да, классы имеют небольшое преимущество, но в основном для программиста. В вашем случае класс не предоставляет никаких функций, которые стандартный модуль не предоставляет.

Если вы продолжите свою идею класса, которая, безусловно, является приемлемым предложением, я думаю, вам стоит перейти к «неряшливой» идее, которую вы представили в конце своего вопроса. Я думаю, что это можно было бы назвать методом/функцией «предикат-строитель». Если вы хотите удалить определенные критерии, не очищая все это, вам придется строить это самостоятельно. Когда вы добавляете критерии с помощью функции построителя предикатов, просто поместите каждый дополнительный критерий в какой-то контейнерный объект, например, с помощью созданного набора записей ADO, объекта Dictionary или Array. Таким образом, вы всегда можете просмотреть структуру/контейнер и добавить, отредактировать или удалить записи. Тогда вам понадобится небольшая функция, чтобы прокрутить контейнер и построить полный оператор WHERE.

Но помните, что в этом случае класс будет очень мало для вас. Да, это позволит вам инкапсулировать и скрыть некоторые из основных механизмов.Например, когда вы добавляете критерии, он будет добавлен в какой-то частный контейнер/структуру/переменную, о которой ваш код вызова не должен знать. И затем, когда вы вызываете метод Get, еще раз, ваш код вызова не должен знать, как критерии хранятся, сфабрикованы и т. Д. Но вы должны иметь возможность сделать всю эту работу без класса, хотя это будет намного более «рыхлым» и, конечно, менее идеальным.

+0

Мне нравится ваше представление об объекте контейнера и хранении ГДЕ в нем, не могли бы вы рассказать о том, как это будет работать с частной переменной внутри класса? Таким образом, немного легче манипулировать в функции 'execute', которая будет строить все и выполнять. Этот модуль будет (надеюсь, будет скопирован во многие программы в будущем, и, следовательно, мое желание упростить его с помощью объекта> getter/setter. Таким образом, программисты не вынуждены изучать работу LDAP-запросов и способы их управления. – Elias

0

Есть еще одна вещь, о которой я не уверен, что вы знаете, но которая может быть очень полезной для вас; возможно, это может быть даже то, что вы ищете в конце.

Это правда, что для этого не очень полезно использовать модуль класса, поскольку нет реального использования при создании нескольких экземпляров этого объекта.
Однако вы можете сделать стандартный модуль, как эквивалент того, что они называют «статическим классом» на C#, хотя VBA не реализует концепцию статических классов.

Задумайтесь на минуту это определение для статического класса C#:

Статический класс в основном такой же, как нестатической класса, но есть одна разница: статический класс не может быть создан. В другими словами, вы не можете использовать новое ключевое слово для создания переменной типа . Поскольку нет переменной экземпляра, вы получаете доступ к членам статического класса с использованием самого имени класса. Например, если у вас есть статический класс, который называется 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 

То, что я хотел бы указать, с этим тестом, является то, что как стандартные модули на самом деле два отдельных экземпляра с их собственной частной собственностью, каждый реализующие такой же функция.
Итак, вы заметите, что стандартный модуль ведет себя очень похоже на статический класс (хотя его внутренняя лежащая в основе механика не то же самое).

Я бы посоветовал вам создать стандартный модуль и реализовать эту логику.
Я считаю, что полезно создать такой «статический» класс, поскольку, как вы упомянули, вы будете многократно использовать его, в то время как вам не понадобятся несколько экземпляров класса.

Смежные вопросы