Каковы преимущества использования Классов в VBA?

Я делаю некоторый VBA, программирующий в Excel 2007, и имею одну рабочую книгу, где все таблицы данных должны быть скопированы с в другой лист. Новый лист будет иметь несколько строк заголовков, и я хотел бы отслеживать то, где они расположены так, я не должен находить слова в них постоянно.

Самая простая вещь состоит в том, чтобы использовать классы и поддерживать в рабочем состоянии их, в то время как документ Excel открыт? Или это сделает это тяжелым и твердым обработать, и я должен продолжать работать с подпрограммами? Каковы преимущества с использованием классов? Это не похоже, у меня есть несколько объектов, только листы и проверка на столбцах.

31
задан SandPiper 12 January 2019 в 18:15
поделиться

2 ответа

Если есть много подпрограмм или подпрограмм очень длинных, то структурирование кода по классам может помочь. Если есть только пара подпрограмм, скажем, каждая из которых состоит всего из 10 строк кода, то это означает, что все кончено. Преимущество структурирования кода по классам заключается в том, что его легче читать и менять, когда вы возвращаетесь к нему вниз по строке. Таким образом, еще одна причина структурирования кода в классы - это если код, скорее всего, будет нуждаться в изменении вниз по строке

.
6
ответ дан 27 November 2019 в 21:40
поделиться

Не использовать @ ModelAttribute . Сохраните пользователей в ModelMap явным образом. Ты в любом случае делаешь столько же с объектом команды.

@RequestMapping(method=RequestMethod.GET)
    public String setupForm(ModelMap model){

        // Set up command object
        Intake intake = new Intake();
        intake.setIntakeDate(new Date());
        model.addAttribute("intake", intake);

        model.addAttribute("users", users);

        return "addIntake";
    }

Недостаток этого состоит в том, что ошибка проверки имеет место в addIncompose () . Если требуется просто вернуть логическое имя формы, необходимо также не забывать повторно заполнить модель пользователями, в противном случае форма не будет правильно настроена.

-121--987675-

Я получаю то же самое при установке на iPod Touch. Я не могу связать для симулятора (по другим причинам), поэтому не могу сказать, возникает ли там проблема.

Да, восстановление или удаление приложения с устройства позволяет мне установить его снова. Ни то, ни другое не является желательным, итеративным решением!

Минимальная «уборка», с которой я столкнулся в процессе работы, - это удаление Foo.app вручную в каталоге build/Debug-iphoneos.

-121--1130123-

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

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

Я скопировал объяснение классов из одного из моих предыдущих ответов Stack Overflow :


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

В редакторе VBA выберите Insert > Class Module . В окне Properties (по умолчанию в левой нижней части экрана) измените имя модуля на WorkLogItem . Добавьте в класс следующий код:

Option Explicit

Private pTaskID As Long
Private pPersonName As String
Private pHoursWorked As Double

Public Property Get TaskID() As Long
    TaskID = pTaskID
End Property

Public Property Let TaskID(lTaskID As Long)
    pTaskID = lTaskID
End Property

Public Property Get PersonName() As String
    PersonName = pPersonName
End Property

Public Property Let PersonName(lPersonName As String)
    pPersonName = lPersonName
End Property

Public Property Get HoursWorked() As Double
    HoursWorked = pHoursWorked
End Property

Public Property Let HoursWorked(lHoursWorked As Double)
    pHoursWorked = lHoursWorked
End Property

Приведенный выше код даст нам строго типизированный объект, специфичный для данных, с которыми мы работаем. При использовании многомерных массивов для хранения данных код напоминает следующий: arr (1,1) - идентификатор, arr (1,2) - PersonName, а arr (1,3) - HourWorked. Используя этот синтаксис, трудно понять, что именно. Предположим, что объекты по-прежнему загружаются в массив, но вместо этого используется созданный выше WorkLogItem . Это имя позволяет выполнить arr (1) .PersonName для получения имени пользователя. Это значительно облегчает чтение кода.

Продолжим этот пример. Вместо сохранения объектов в массиве мы попытаемся использовать коллекцию .

Затем добавьте новый модуль класса и вызовите его ProcessWorkLog . Поместите туда следующий код:

Option Explicit

Private pWorkLogItems As Collection

Public Property Get WorkLogItems() As Collection
    Set WorkLogItems = pWorkLogItems
End Property

Public Property Set WorkLogItems(lWorkLogItem As Collection)
    Set pWorkLogItems = lWorkLogItem
End Property

Function GetHoursWorked(strPersonName As String) As Double
    On Error GoTo Handle_Errors
    Dim wli As WorkLogItem
    Dim doubleTotal As Double
    doubleTotal = 0
    For Each wli In WorkLogItems
        If strPersonName = wli.PersonName Then
            doubleTotal = doubleTotal + wli.HoursWorked
        End If
    Next wli

Exit_Here:
    GetHoursWorked = doubleTotal
        Exit Function

Handle_Errors:
        'You will probably want to catch the error that will '
        'occur if WorkLogItems has not been set '
        Resume Exit_Here


End Function

Приведенный выше класс будет использоваться для того, чтобы «сделать что-то» с коллекцией WorkLogItem . Изначально,мы просто настроили его для подсчета общего количества отработанных часов. Давайте проверим код, который мы написали. Создайте новый модуль (не модуль класса на этот раз; просто «обычный» модуль). Вставьте в модуль следующий код:

Option Explicit

Function PopulateArray() As Collection
    Dim clnWlis As Collection
    Dim wli As WorkLogItem
    'Put some data in the collection'
    Set clnWlis = New Collection

    Set wli = New WorkLogItem
    wli.TaskID = 1
    wli.PersonName = "Fred"
    wli.HoursWorked = 4.5
    clnWlis.Add wli

    Set wli = New WorkLogItem
    wli.TaskID = 2
    wli.PersonName = "Sally"
    wli.HoursWorked = 3
    clnWlis.Add wli

    Set wli = New WorkLogItem
    wli.TaskID = 3
    wli.PersonName = "Fred"
    wli.HoursWorked = 2.5
    clnWlis.Add wli

    Set PopulateArray = clnWlis
End Function

Sub TestGetHoursWorked()
    Dim pwl As ProcessWorkLog
    Dim arrWli() As WorkLogItem
    Set pwl = New ProcessWorkLog
    Set pwl.WorkLogItems = PopulateArray()
    Debug.Print pwl.GetHoursWorked("Fred")

End Sub

В приведенном выше коде PopulateArray () просто создает коллекцию WorkLogItem . В реальном коде можно создать класс для анализа листов Excel или объектов данных для заполнения коллекции или массива.

Код StartGetHoursWorked () просто демонстрирует, как использовались классы. Обратите внимание, что ProcessWorkLog создан как объект. После создания экземпляра коллекция WorkLogItem становится частью объекта pwl . Вы заметили это в строке Set pwl. WorkLogItems = PopulateArray () . Далее просто вызовем написанную функцию, которая действует на коллекцию WorkLogItems .

Почему это полезно?

Предположим, ваши данные изменяются, и вы хотите добавить новый метод. Предположим, что WorkLogItem теперь содержит поле для HoursOnBreak и требуется добавить новый метод для вычисления этого значения.

Все, что вам нужно сделать, это добавить свойство в WorkLogItem так:

Private pHoursOnBreak As Double

Public Property Get HoursOnBreak() As Double
    HoursOnBreak = pHoursOnBreak
End Property

Public Property Let HoursOnBreak(lHoursOnBreak As Double)
    pHoursOnBreak = lHoursOnBreak
End Property

Конечно, вам нужно будет изменить метод заполнения коллекции (пример метода, который я использовал, был PopulateArray () , но вы, вероятно, должны иметь отдельный класс только для этого). Затем просто добавьте новый метод в класс ProcessWorkLog :

Function GetHoursOnBreak(strPersonName As String) As Double
     'Code to get hours on break
End Function

Теперь, если бы мы хотели обновить наш метод StartGetHoursWorked () , чтобы вернуть результат GetHoursOnBreak , нам пришлось бы добавить следующую строку:

    Debug.Print pwl.GetHoursOnBreak("Fred")

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

Для дальнейшего чтения настоятельно рекомендую получить копию VBA Developer's Handbook, 2-е издание . Книга полна прекрасных примеров и лучших практик, а также множества образцов кода. Если вы вкладываете много времени в VBA для серьезного проекта, стоит, чтобы вы заглянули в эту книгу.

76
ответ дан 27 November 2019 в 21:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: