Определенно в модулях.
Поскольку инструментальные средства настолько плохи в примитивных системах, как Excel VBA, важны передовой опыт, навязчивая гигиена кода и религиозное следование конвенциям, особенно если вы пытаетесь сделать с ним что-то отдаленно сложное.
Эта статья объясняет предполагаемое использование различных типов контейнеров кода. Это не определяет , почему следует проводить эти различия, но я считаю, что большинство разработчиков, пытающихся разработать серьезные приложения на платформе Excel, следуют им.
Также есть список соглашений о кодировании VBA , которые я нашел полезными, хотя они не имеют прямого отношения к Excel VBA. Пожалуйста, не обращайте внимания на сумасшедшие соглашения об именах, которые у них есть на этом сайте, это все сумасшедший венгерский .
Я бы предложил разделить ваш код на основе функциональности и цели, специфичной для каждого листа или модуля. Таким образом, вы будете размещать код, относящийся к пользовательскому интерфейсу листа, только внутри модуля листа, а код, относящийся к модулям, только в соответствующих модулях. Кроме того, используйте отдельные модули для инкапсуляции кода, который используется совместно или повторно в нескольких различных листах.
Например, допустим, у вас есть несколько листов, которые отвечают за отображение данных из базы данных особым образом. Какие виды функциональности мы имеем в этой ситуации? У нас есть функциональность, связанная с каждым конкретным листом, задачи, связанные с получением данных из базы данных, и задачи, связанные с заполнением листа данными. В этом случае я мог бы начать с модуля для доступа к данным, модуля для заполнения листа данными, а внутри каждого листа у меня будет код для доступа к коду в этих модулях.
Это может выглядеть следующим образом.
Модуль: DataAccess:
Function GetData(strTableName As String, strCondition1 As String) As Recordset
'Code Related to getting data from the database'
End Function
Module: PopulateSheet:
Sub PopulateASheet(wsSheet As Worksheet, rs As Recordset)
'Code to populate a worksheet '
End Function
Sheet: Sheet1 Code:
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
По моему опыту, лучше всего помещать как можно больше кода в модули с хорошо названными именами и помещать столько кода, сколько вам нужно, в фактические объекты рабочего листа.
Пример: любой код, который использует события рабочего листа, такие как Worksheet_SelectionChange или Worksheet_Calculate.