2015-04-06 2 views
2

Есть несколько очень хорошей ansewers на механике с использованием классов smple в VBA: When to use a Class in VBA? и What are the benefits of using Classes in VBA?с использованием классов для работы с несколькими диапазонами в Excel VBA

Как кто-то relativley новой ООП и классы, это трудно знать, как их реализовать, или что действительно возможно.

Например, я должен иметь дело с большими диапазонами в нескольких листах, и мне нужно получить множество разных подмножеств данных. «агенты, которые делают x» и «клиенты, у которых есть» ... и т. д. Вот я к югу, вместе взятым, чтобы в числе агентов, которые имеют более чем 2 клиентов:

Sub agent_subset(output_sheet As String, _ 
            Input_sheet_name As String, _ 
            email_col As Integer, _ 
            vendor_count_col As Integer, _ 
            client_count_col As Integer, _ 
            modified_col As Integer, _ 
            num_of_clients As Integer) 
' get a list of all agents with 2 or more clients and put them into a sheet 

    Application.DisplayStatusBar = True 

    Dim sheet_rows As Long 
    sheet_rows = Worksheets(Input_sheet_name).Cells(rows.Count, 1).End(xlUp).Row 

    Dim email_range As Range ' range of agent emails 
    Dim client_count_range As Range ' range of client count 
    Dim vendor_count_range As Range ' range of vendor count 
    Dim modified_range As Range ' range of modified at 

    With Worksheets(Input_sheet_name) 
     Set email_range = .Range(.Cells(2, email_col), .Cells(sheet_rows, email_col)) 
     Set client_count_range = .Range(.Cells(2, client_count_col), .Cells(sheet_rows, client_count_col)) 
     Set vendor_count_range = .Range(.Cells(2, vendor_count_col), .Cells(sheet_rows, vendor_count_col)) 
     Set modified_range = .Range(.Cells(2, modified_col), .Cells(sheet_rows, modified_col)) 
    End With 

    Dim n As Long 
    Dim counter As Long 
    counter = 0 

    Dim modified_array() As String 

    For n = 2 To sheet_rows 
     If client_count_range(n, 1).Value > num_of_clients Then 
      counter = counter + 1 
      Worksheets(output_sheet).Cells(counter + 1, 1).Value = email_range(n, 1).Value 
      Worksheets(output_sheet).Cells(counter + 1, 2).Value = client_count_range(n, 1).Value 
      Worksheets(output_sheet).Cells(counter + 1, 3).Value = vendor_count_range(n, 1).Value 
       modified_array() = Split(modified_range(n, 1).Value, "T") 
      Worksheets(output_sheet).Cells(counter + 1, 4).Value = modified_array(0) 
     End If 

     Application.StatusBar = "Loop status: " & n & "of " & sheet_rows 

    Next n 

Worksheets(output_sheet).Cells(counter + 3, 1).Value = "Last run was " & Now() 

Application.StatusBar = False 

End Sub 

Он прекрасно работает, но теперь я хочу, чтобы получить еще меньшее подмножество агентов и клиентов на основе других критериев , Итак, я собираюсь написать аналогичную функцию, манипулируя подобными данными. Моя кишка говорит мне, что использование классов облегчит мне жизнь, но я не знаю, как разбить задачи.

Должен ли быть класс агента, который имеет всю информацию об агентах? и/или класса клиента? Или, если классы предназначены для просмотра целых диапазонов или листов?

Я не ищу конкретный код, а методологию о том, как сломать вещи.

ответ

1

мне приходится иметь дело с большими диапазонами в нескольких листах

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

У меня был бы агент класса, который обладал бы всеми свойствами агента. У меня был бы класс коллекции агентов, в котором были бы все классы агента. Затем в классе «Агенты» у меня были бы методы «Фильтр», возвращающие подмножества класса «Агенты».

Вот пример: у меня есть клиенты. Клиенты могут быть активными или нет. У клиентов также есть шаблон, который я использую, когда я отправляю им по электронной почте определенную информацию. Когда я хочу отправить активных клиентов, которые используют шаблон Table1, это выглядит, как этот

Set clsCustomersToEmail = clsCustomers.FilterOnActive(True).FilterOnTemplate("Table1") 
For Each clsCustomer in clsCustomersToEmail 
    'Do stuff 
Next clsCustomer` 

В моем классе коллекции CCustomers, у меня есть несколько свойств, которые возвращают класс CCustomers с несколькими клиентами, чем большой класс CCustomers (называемые clsCustomers)

Public Property Get FilterOnActive() As CCustomers 

    Dim clsReturn As CCustomers 
    Dim clsCustomer As CCustomer 

    Set clsReturn = New CCustomers 

    For Each clsCustomer In Me 
     If clsCustomer.Active Then 
      clsReturn.Add clsCustomer 
     End If 
    Next clsCustomer 

    Set FilterOnActive = clsReturn 

End Property 
Public Property Get FilterOnTemplate(ByVal sTemplate As String) As CCustomers 

    Dim clsReturn As CCustomers 
    Dim clsCustomer As CCustomer 

    Set clsReturn = New CCustomers 

    For Each clsCustomer In Me 
     If clsCustomer.Template.TemplateName = sTemplate Then 
      clsReturn.Add clsCustomer 
     End If 
    Next clsCustomer 

    Set FilterOnTemplate = clsReturn 

End Property 

Когда я хочу, чтобы делать такие вещи, как написать кучу данных о клиентах в диапазоне, я делаю свойство, которое возвращает массив и записать массив в диапазон.

Set clsCustomersPastDue = clsCustomers.FilterOnActive(True).FilterOnPastDue(True) 
vaWrite = clsCsutomerPastDue.AgingReport 
rCell.Resize(UBound(vaWrite,1),UBound(vaWrite,2)).Value = vaWrite 

Я склонен думать, какие физические вещи я кодирую. Они не должны быть осязаемыми вещами, но если вы можете вернуть их к чему-то ощутимому, это может быть полезно.

Сделка - вещь. Но если эта транзакция представляет собой счет-фактуру, теперь определить, какие свойства этого объекта становятся легкими. Во-первых, вы можете просто взглянуть на бумажный счет-фактуру и посмотреть, что это за свойства.

Следующий уровень отношений. У каждого класса Агента есть клиенты. Таким образом, ваш объект Agent должен иметь свойство Customers, которое возвращает класс CCustomers.Или, если он не структурирован так сильно в реальной жизни, возможно, ваш класс CCustomers имеет свойство FilterOnAgent, которое возвращает подмножество клиентов, которые вы ищете.

+0

Это превосходно! Очень полезно! Помимо прочего, я не был уверен, что коллекция объектов класса имеет смысл, то есть имеет класс агента, а затем свертывается в коллекцию. Огромное спасибо! – dwstein

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