Можно ли объявить общедоступную переменную в vba и присвоить значение по умолчанию?

Я хочу это сделать, но он не компилируется:

Public MyVariable as Integer = 123

Как лучше всего этого добиться?


person David    schedule 05.05.2011    source источник
comment
Где запускается этот VBA? Excel, Access, Word ...   -  person Duncan Howe    schedule 05.05.2011
comment
@DuncanHowe Я надеялся на универсальное решение vba.   -  person David    schedule 05.05.2011
comment
Глобальные переменные больше не считаются злом? В мае я отсутствовал на пару недель, так что, возможно, я что-то пропустил.   -  person Jean-François Corbett    schedule 04.07.2011
comment


Ответы (8)


.NET нас испортил :) Ваше заявление не подходит для VBA.

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

Public Const APOSTROPHE_KEYCODE = 222

Вот пример объявления из одного из моих проектов vba:

Постоянное изображение VBA

Если вы ищете что-то, где вы объявляете общедоступную переменную, а затем хотите инициализировать ее значение, вам необходимо создать подпрограмму Workbook_Open и выполнить там свою инициализацию. Пример:

Private Sub Workbook_Open()
  Dim iAnswer As Integer

  InitializeListSheetDataColumns_S
  HideAllMonths_S

  If sheetSetupInfo.Range("D6").Value = "Enter Facility Name" Then
    iAnswer = MsgBox("It appears you have not yet set up this workbook.  Would you like to do so now?", vbYesNo)
    If iAnswer = vbYes Then
      sheetSetupInfo.Activate
      sheetSetupInfo.Range("D6").Select
      Exit Sub
    End If
  End If

  Application.Calculation = xlCalculationAutomatic
  sheetGeneralInfo.Activate
  Load frmInfoSheet
  frmInfoSheet.Show


End Sub

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

person ray    schedule 05.05.2011

Просто чтобы предложить вам другой угол -

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

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

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

person Alain    schedule 05.05.2011

Конечно, вы знаете, но если это константа, тогда const MyVariable as Integer = 123, иначе вам не повезло; переменной должно быть присвоено начальное значение в другом месте.

Вы могли:

public property get myIntegerThing() as integer
    myIntegerThing= 123
end property

Затем создайте его в модуле класса глобально;

public cMyStuff as new MyStuffClass

Итак, cMyStuff.myIntegerThing доступен немедленно.

person Alex K.    schedule 05.05.2011
comment
Лучше было бы добавить модуль и определить эти свойства внутри этого модуля. Я создаю модуль с именем Globals и определяю Property Get внутри этого модуля, и он работает как шарм. Свойство Получить PSIStartRow () как целое число PSIStartRow = Sheets (FOB Цены) .Range (F1) .Value Конечное свойство Свойство Получить PSIStartCell () как строку PSIStartCell = B & PSIStartRow End Property - person Achilles; 11.07.2016
comment
Код был искажен в приведенном выше комментарии. Я выложу это ниже. - person Achilles; 11.07.2016

Малоизвестный факт:
Именованный диапазон может ссылаться на значение, а не на определенные ячейки.

Это можно использовать, чтобы действовать как глобальная переменная, плюс вы можете ссылаться на значение из VBA и в ячейке листа, и назначенное значение будет даже сохраняться после закрытия и повторного открытия книги!


  • Чтобы объявить имя myVariable и присвоить ему значение 123:

    ThisWorkbook.Names.Add "myVariable", 123
    
  • Чтобы получить значение (например, чтобы отобразить значение в MsgBox):

      MsgBox [myVariable]
    
  • В качестве альтернативы вы можете ссылаться на имя с помощью строки: (результат идентичен квадратным скобкам)

    MsgBox Evaluate("myVariable")
    
  • Чтобы использовать значение на листе, просто используйте его имя в формуле как есть:

    =myVariable
    
  • Фактически вы даже можете хранить выражения функций: (вроде как в JavaScript)
    (По общему признанию, я не могу представить себе ситуацию, в которой это было бы полезно, но я не использую их в JS тоже.)

    ThisWorkbook.Names.Add "myDay", "=if(isodd(day(today())),""on day"",""off day"")"
    

Квадратные скобки - это просто ярлык для метода Evaluate. Я слышал, что их использование считается беспорядочным или взломанным, но у меня не было проблем, и их использование в Excel - это поддерживается Microsoft.

Вероятно, также есть способ использовать Range, чтобы ссылаться на эти имена, но я не вижу никаких преимуществ, поэтому я не стал вдаваться в подробности.


Больше информации:

person ashleedawg    schedule 14.07.2020

Как было сказано выше, чтобы объявить глобальные доступные переменные, вы можете сделать это вне функций, которым предшествует ключевое слово public.

И, поскольку воздействие НЕ РАЗРЕШЕНО вне процедур, вы можете, например, создать подпрограмму с именем InitGlobals, которая инициализирует ваши общедоступные переменные, тогда вы просто вызываете эту подпрограмму в начале ваших операторов.

Вот пример этого:

Public Coordinates(3) as Double
Public Heat as double
Public Weight as double

Sub InitGlobals()
    Coordinates(1)=10.5
    Coordinates(2)=22.54
    Coordinates(3)=-100.5
    Heat=25.5
    Weight=70
End Sub

Sub MyWorkSGoesHere()
    Call InitGlobals
    'Now you can do your work using your global variables initialized as you wanted them to be.
End Sub
person Mohamed YOUNES    schedule 11.08.2015

Вот что я делаю, когда мне нужны инициализированные глобальные константы:
1. Добавьте модуль с именем Globals
2. Добавьте такие свойства в модуль Globals:

Property Get PSIStartRow() As Integer  
    PSIStartRow = Sheets("FOB Prices").Range("F1").Value  
End Property  
Property Get PSIStartCell() As String  
    PSIStartCell = "B" & PSIStartRow  
End Property
person Achilles    schedule 11.07.2016

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

В качестве альтернативы вы можете создать себе класс с соответствующими свойствами и инициализировать их в методе Initialise.

person Duncan Howe    schedule 05.05.2011

Прошло довольно много времени, но это может вас удовлетворить:

Public MyVariable as Integer: MyVariable = 123

Это немного некрасиво, так как вам нужно повторно ввести имя переменной, но оно находится в одной строке.

person Lucas B.    schedule 29.10.2013
comment
Выдает ошибку компиляции: недопустимый за пределами процедуры - person manpreet singh; 15.09.2015