Форма показана модально, поэтому ActiveCell
не изменится на вас и должна быть безопасной для использования в коде формы.
Проблема в том, что вы теперь привязали форму к ActiveSheet
/ ActiveCell
, а теперь, чтобы протестировать все, что вам нужно, Select
или Activate
в ячейке.
Если код формы должен знать только о Address
ячейки, то ему не следует давать Range
(присвойте ему Range
, и он может получить доступ к любой ячейке на любом листе в любой книге в Application
экземпляр) - это принцип наименьшего знания в игре. Но это, очевидно, пример кода, поэтому давайте рассмотрим Range
:
Option Explicit
Private internalWorkingCell As Range
Public Property Get WorkingCell() As Range
Set WorkingCell = internalWorkingCell
End Property
Public Property Set WorkingCell(ByVal value As Range)
Set internalWorkingCell = value
End Property
Теперь ваш код формы может использовать WorkingCell
или internalWorkingCell
для своей работы, и никакой глобальной переменной не нужно плавать;
With New UserForm1 ' Initialize handler runs here
Set .WorkingCell = Target
.Show ' Activate handler runs here
End With
WorkingCell
принадлежит к форме - он не имеет бизнеса в глобальном масштабе.
Осторожнее с обработчиком Initialize
в формах - , особенно , когда вы используете его экземпляр по умолчанию (т.е. когда вы не New
его запускаете): вы не делаете контролировать, когда запускается этот обработчик, исполняется среда VBA; UserForm_Initialize
будет запущен в первый раз, когда экземпляр формы будет ссылаться на (в вашем случае, непосредственно перед вызовом .Show
), и никогда больше, если экземпляр не будет уничтожен (нажатие красной кнопки X сделает что).
Вызов MsgBox
в обработчике Initialize
будет выполнен до того, как отобразится форма; Возможно, вы захотите переместить этот код в обработчик Activate
, прежде чем он вызовет проблемы.