Поместить код Excel-VBA в модуль или лист?

31

Что такое хорошая практика и хорошая гигиена кода? Ввод кода в модули или таблицы?

У меня есть эта книга Excel с пользовательскими интерфейсами на каждом листе. Каждый лист в рабочей книге выполняет другую часть некоторой общей задачи. Должен ли я помещать код, соответствующий каждому листу внутри объектов "Лист" или в Модулях? Группировать в один модуль или отдельные модули?

Я использую Excel 2003.

Теги:
excel-vba

3 ответа

40
Лучший ответ

Определенно в модулях.

  • Листы могут быть удалены, скопированы и перемещены с удивительными результатами.
  • Вы не можете вызывать код в листе "code-behind" из других модулей без полной квалификации ссылки. Это приведет к соединению листа и кода в других модулях/листах.
  • Модули можно экспортировать и импортировать в другие книги, а также поставить под контролем версий
  • Код, разделенный логически на модули (доступ к данным, утилиты, форматирование электронных таблиц и т.д.), может быть повторно использован как единицы и легче управлять, если ваши макросы становятся большими.

Поскольку инструментальная система настолько бедна в примитивных системах, таких как Excel VBA, важны лучшие практики, навязчивая гигиена кода и религиозное следование соглашениям, особенно если вы пытаетесь сделать с ней что-то отдаленно сложное.

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

Там также есть список Соглашения о кодировании VBA. Я нашел полезным, хотя они напрямую не связаны с Excel VBA. Пожалуйста, игнорируйте сумасшедшие соглашения об именах, которые они имеют на этом сайте, все это безумно венгерское.

  • 1
    Венгерская нотация, реализованная в Соглашении об именовании Reddick, более или менее была стандартом именования переменных для Visual Basic для приложений и VB6. Хотя я бы, конечно, избегал его использования в .NET, где инструментарий очень силен, его использование в VBA, где инструментарий более старый, не повредит.
  • 0
    @Ben - «Сумасшедший венгерский» был произнесен насмешливо :) В то время как венгерский язык помогает с отсутствием статической типизации и инструментария «что это снова», я думаю, что это не очень хорошо, когда вы больше ориентируетесь на объектно-ориентированный VBA и начать создавать свои собственные доменные объекты. Моя самая большая жалоба, однако, состоит в том, что венгерский язык действительно портит поток фактического чтения кода. Хотя для каждого свое, для меня это не религиозный вопрос. Но если кто-то спросит, я не буду рекомендовать это.
Показать ещё 2 комментария
9

По моему опыту, лучше всего поместить столько кода, сколько вы можете, в хорошо названные модули, и поместите столько кода, сколько потребуется, в реальные объекты рабочего листа.

Пример: Любой код, который использует события рабочего листа, такие как Worksheet_SelectionChange или Worksheet_Calculate.

  • 0
    Это моя общая политика.
9

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

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

Это может быть сделано так.

Модуль: DataAccess:

Function GetData(strTableName As String, strCondition1 As String) As Recordset
    'Code Related to getting data from the database'
End Function

Модуль: PopulateSheet:

Sub PopulateASheet(wsSheet As Worksheet, rs As Recordset)
    'Code to populate a worksheet '
End Function

Лист: Код Sheet1:

Sub GetDataAndPopulate()
    'Sample Code'
     Dim rs As New Recordset
     Dim ws As Worksheet
     Dim strParam As String
     Set ws = ActiveSheet
     strParam = ws.Range("A1").Value

     Set rs = GetData("Orders",strParam)

     PopulateASheet ws, rs
End Sub

Sub Button1_Click()
    Call GetDataAndPopulate
End Sub

Ещё вопросы

Сообщество Overcoder
Наверх
Меню