Можете ли вы вызвать модуль из пользовательской формы, чья переменная объявлена ​​из поля со списком? - PullRequest
0 голосов
/ 20 февраля 2020

Я создал подпрограмму пользовательской формы, которая позволит пользователю выбирать из открытой рабочей книги для использования в качестве справочной рабочей книги с помощью поля со списком. Мой текущий скрипт возвращает ошибку, что workbooks(wb) не определен - я предполагаю, что это потому, что переменная определена в двух разных модулях, а поле со списком не находится в вызываемом модуле. В идеале хотелось бы использовать форму пользователя ниже

Private Sub Go_Click()

 If ComboBox1.ListIndex = -1 Then
        MsgBox "Please select a workbook name and try again"
        Exit Sub
    End If

  Dim wb As Variant

  wb = ComboBox1.List(ComboBox1.ListIndex)

  Call GenerateReportUserForm

End Sub

Для вызова этого подпункта:

Sub newMacro()

Dim copyNames As Range, pasteNames As Range, copyAmounts As Range, pasteAmounts As Range, copyDates As Range, pasteDates As Range, _
copyPayment As Range, pastePayment As Range

'   For cheques only

Set copyNames = Workbooks(wb).Worksheets(2).Columns("F")
Set copyAmounts = Workbooks(wb).Worksheets(2).Columns("AR")
Set copyDates = Workbooks(wb).Worksheets(2).Columns("AI")
Set copyPayment = Workbooks(wb).Worksheets(2).Columns("AJ")

Set pasteNames = Workbooks("VBA Workbook.xlsm").Worksheets(1).Columns("A")
Set pasteAmounts = Workbooks("VBA Workbook.xlsm").Worksheets(1).Columns("C")
Set pasteDates = Workbooks("VBA Workbook.xlsm").Worksheets(1).Columns("D")
Set pastePayment = Workbooks("VBA Workbook.xlsm").Worksheets(1).Columns("E")

copyNames.Copy Destination:=pasteNames
copyAmounts.Copy Destination:=pasteAmounts
copyDates.Copy Destination:=pasteDates
copyPayment.Copy Destination:=pastePayment

End sub

Спасибо!

1 Ответ

3 голосов
/ 20 февраля 2020

wb явно хочет быть String, представляющим название рабочей книги. Объявите это так.

Dim wbName As String
wbName = ComboBox1.List(ComboBox1.ListIndex)

Примечание, имя ваши элементы управления. AvailableFilesBox говорит гораздо больше, чем ComboBox1.

Теперь вам нужно передать эту переменную в качестве аргумента; не используйте глобальную переменную , если вы абсолютно НЕ ДОЛЖНЫ.

Call GenerateReportUserForm

Не уверен, что это должно делать, но он не вызывает newMacro. Если вы хотите, чтобы он вызывал newMacro, то измените его на:

NewMacro wbName

Или если вы действительно хотите сохранить это избыточное и отвлекающее ключевое слово Call:

Call NewMacro(wbName)

Примечание: дайте этому макросу осмысленное имя, которое описывает, что делает макрос. «новый макрос» может быть понятен сейчас , но не так много раз, когда в этом проекте есть 4-5 новых макросов - и newMacro2 НЕ вариант!

Теперь по порядку чтобы передать wbName в качестве аргумента, процедуре необходимо объявить, что она принимает параметр - например, так:

Public Sub NewMacro(ByVal wbName As String)

Внутри этой области действия процедуры вам не нужно постоянно разыменовывать объект Workbook , Сделайте это один раз , сохраните ссылку на объект в локальной переменной, затем используйте эту переменную:

Dim wb As Workbook
Set wb = Workbooks(wbName)

Оказывается, этот макрос на самом деле не заботится об имени книги; что он на самом деле хочет, так это Workbook объект. Итак, давайте возьмем на себя ответственность вызывающего абонента за предоставление Workbook.

Сначала мы изменим подпись, чтобы принять параметр Workbook:

Public Sub NewMacro(ByVal wb As Workbook)

Затем мы изменим код формы на поставьте его:

Dim wb As Workbook
Set wb = Workbooks(ComboBox1.List(ComboBox1.ListIndex))

NewMacro wb ' or: Call NewMacro(wb)

Не забудьте всегда ставить Option Explicit вверху каждого модуля; Rubberduck может помочь вам найти и исправить это, а также другие проблемы в вашем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...