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

У меня есть строка макросов, которые обращаются друг к другу и ссылаются на книги A и B. Я хочу, чтобы первый макрос предлагал пользователю выбрать документы A и B, а эти выборки – это переменные книги A и B, на которые я ссылаюсь в различные macros.

Как сделать выбранные документы привязаны к переменной во всех макросах?

Заранее спасибо!

Объявите их вне подпрограмм, например:

Public wbA as Workbook Public wbB as Workbook Sub MySubRoutine() Set wbA = Workbooks.Open("C:\file.xlsx") Set wbB = Workbooks.Open("C:\file2.xlsx") OtherSubRoutine End Sub Sub OtherSubRoutine() MsgBox wbA.Name, vbInformation End Sub 

Кроме того, вы можете передавать переменные между подпрограммами:

 Sub MySubRoutine() Dim wbA as Workbook Dim wbB as Workbook Set wbA = Workbooks.Open("C:\file.xlsx") Set wbB = Workbooks.Open("C:\file2.xlsx") OtherSubRoutine wbA, wbB End Sub Sub OtherSubRoutine(wb1 as Workbook, wb2 as Workbook) MsgBox wb1.Name, vbInformation MsgBox wb2.Name, vbInformation End Sub 

Или используйте Functions для возврата значений :

 Sub MySubroutine() Dim i as Long i = MyFunction() MsgBox i End Sub Function MyFunction() 'Lots of code that does something Dim x As Integer, y as Double For x = 1 to 1000 'Lots of code that does something Next MyFunction = y End Function 

Во втором методе, в рамках OtherSubRoutine вы ссылаетесь на них по именам параметров wb1 и wb2 . Переданным переменным не нужно использовать одни и те же имена, одни и те же типы переменных. Это позволяет вам немного свободы, например, у вас есть цикл над несколькими книгами, и вы можете отправлять каждую книгу в подпрограмму для выполнения некоторых действий в этой книге, не делая все (или любые) из переменных общедоступными в области.

Примечание о пользовательских формах

Лично я бы рекомендовал сохранить Option Explicit во всех ваших модулях и формах (это не позволяет вам создавать экземпляры переменных с опечатками в их именах, например lCoutn когда вы имели в виду lCount и т. Д., Среди других причин).

Если вы используете Option Explicit (что вам нужно ), тогда вы должны квалифицировать переменные с модульной областью для стиля и избегать двусмысленности, и вы должны квалифицировать пользовательские формы переменных Public , поскольку они не являются «общедоступными» в том же смысле , Например, i не определено, хотя это Public в области UserForm1 :

введите описание изображения здесь

Вы можете ссылаться на него как UserForm1.i чтобы избежать ошибки компиляции, или поскольку формы являются New -able, вы можете создать объект переменной, содержащий ссылку на вашу форму, и ссылаться на него следующим образом:

введите описание изображения здесь

NB: В приведенных выше скриншотах x объявляется Public x as Long в другом стандартном модуле кода и не будет поднимать ошибку компиляции. Может быть предпочтительнее ссылаться на это как на Module2.x чтобы избежать двусмысленности и возможного затенения в случае повторного использования имен переменных …

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

Для получения дополнительной информации о Scope of variables см. Эту ссылку

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

Вот какой код

  • Подпрограмма образца устанавливает путь к папке и позже путь к файлу. Просьба установить их соответственно, прежде чем запускать код.

  • Я добавил функцию IsWorkBookOpen, чтобы проверить, была ли рабочая книга уже установлена ​​переменная рабочей книги, имя книги также открывает книгу, которая будет соответственно назначена переменной рабочей книги.

Dim wbA As Workbook
Dim wbB As Workbook

 Sub MySubRoutine() Dim folderPath As String, fileNm1 As String, fileNm2 As String, filePath1 As String, filePath2 As String folderPath = ThisWorkbook.Path & "\" fileNm1 = "file1.xlsx" fileNm2 = "file2.xlsx" filePath1 = folderPath & fileNm1 filePath2 = folderPath & fileNm2 If IsWorkBookOpen(filePath1) Then Set wbA = Workbooks(fileNm1) Else Set wbA = Workbooks.Open(filePath1) End If If IsWorkBookOpen(filePath2) Then Set wbB = Workbooks.Open(fileNm2) Else Set wbB = Workbooks.Open(filePath2) End If ' your code here End Sub Function IsWorkBookOpen(FileName As String) Dim ff As Long, ErrNo As Long On Error Resume Next ff = FreeFile() Open FileName For Input Lock Read As #ff Close ff ErrNo = Err On Error GoTo 0 Select Case ErrNo Case 0: IsWorkBookOpen = False Case 70: IsWorkBookOpen = True Case Else: Error ErrNo End Select End Function 

Использование команды «Подсказка» для выбора файла используется ниже кода.

 Dim wbA As Workbook Dim wbB As Workbook Sub MySubRoutine() Dim folderPath As String, fileNm1 As String, fileNm2 As String, filePath1 As String, filePath2 As String Dim filePath As String cmdBrowse_Click filePath, 1 filePath1 = filePath 'reset the variable filePath = vbNullString cmdBrowse_Click filePath, 2 filePath2 = filePath fileNm1 = GetFileName(filePath1, "\") fileNm2 = GetFileName(filePath2, "\") If IsWorkBookOpen(filePath1) Then Set wbA = Workbooks(fileNm1) Else Set wbA = Workbooks.Open(filePath1) End If If IsWorkBookOpen(filePath2) Then Set wbB = Workbooks.Open(fileNm2) Else Set wbB = Workbooks.Open(filePath2) End If ' your code here End Sub Function IsWorkBookOpen(FileName As String) Dim ff As Long, ErrNo As Long On Error Resume Next ff = FreeFile() Open FileName For Input Lock Read As #ff Close ff ErrNo = Err On Error GoTo 0 Select Case ErrNo Case 0: IsWorkBookOpen = False Case 70: IsWorkBookOpen = True Case Else: Error ErrNo End Select End Function Private Sub cmdBrowse_Click(ByRef filePath As String, num As Integer) Dim fd As FileDialog Set fd = Application.FileDialog(msoFileDialogFilePicker) fd.AllowMultiSelect = False fd.Title = "Select workbook " & num fd.InitialView = msoFileDialogViewSmallIcons Dim FileChosen As Integer FileChosen = fd.Show fd.Filters.Clear fd.Filters.Add "Excel macros", "*.xlsx" fd.FilterIndex = 1 If FileChosen <> -1 Then MsgBox "You chose cancel" filePath = "" Else filePath = fd.SelectedItems(1) End If End Sub Function GetFileName(fullName As String, pathSeparator As String) As String Dim i As Integer Dim iFNLenght As Integer iFNLenght = Len(fullName) For i = iFNLenght To 1 Step -1 If Mid(fullName, i, 1) = pathSeparator Then Exit For Next GetFileName = Right(fullName, iFNLenght - i) End Function 

Создайте объект «module» и объявите здесь переменные. В отличие от объектов classа, которые должны быть созданы каждый раз, объекты модуля всегда доступны. Таким образом, общедоступная переменная, функция или свойство в «модуле» будут доступны для всех других объектов проекта VBA, макроса, формулы Excel или даже в рамках запроса MS Access JET-SQL.

  • Подождите, пока ActiveWorkbook.RefreshAll закончит - VBA
  • Используйте автофильтр по более чем 2 критериям
  • Как оптимизировать vlookup для высокого количества поиска? (альтернативы VLOOKUP)
  • Excel VBA Copy Вставить только значения (xlPasteValues)
  • Ошибка времени выполнения '1004': метод 'Range' объекта'_Global 'не выполнен
  • VBA Shell и подождите с кодом выхода
  • Выберите первую пустую ячейку в столбце F, начиная с строки 1. (без использования смещения)
  • Excel макрос, чтобы сохранить книгу на другом сеансе Excel
  • Как объединить значения из нескольких строк в одну строку в Excel?
  • Что делает ключевое слово Set в VBA?
  • Сохранить текстовый файл UTF-8, закодированный с помощью VBA
  • Давайте будем гением компьютера.