Объект класса Excel VBA становится неопределенным - PullRequest
0 голосов
/ 22 февраля 2019

Я централизовал обработку всех событий в моей книге Excel в одном классе под названием «Компоненты».Класс перемещается в отдельный файл "xlam", а этот файл "xlam" упоминается в книге Excel.

Класс "Компонент" определяется следующим образом:

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "Components"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False

Public WithEvents WorkbookSD As Workbook, _
       WithEvents SheetConfig As Worksheet, _
       TableConfig As ListObject, _
       TableVerValues1 As ListObject, _
       TableVerValues2 As ListObject, _
       TableDValues As ListObject, _
       TableIGRValues As ListObject
...

Private Sub Class_Initialize()
  On Error GoTo ErrorHandling
  ToggleAppUpdate False
  Set WorkbookSD = ActiveWorkbook
  Set SheetConfig = WorkbookSD.Worksheets(SHEET_CONFIG)
  Set TableConfig = SheetConfig.ListObjects(TABLE_CONFIG)
...

Private Sub SheetConfig_Activate()
  On Error GoTo ErrorHandling
  ...
ErrorHandling:
  If Err.Number <> 0 Then
    ReportError
  End If
End Sub

Обратите внимание, что "Атрибут VB_PredeclaredId = True ", чтобы гарантировать, что объект класса объявлен.Вроде как как это делает Form.

Поэтому я объявляю все объекты, для которых я хочу обрабатывать события в этом классе и WithEvents.«Компонент» инициализируется в событии «Class_Initialize».

Я ссылаюсь на объекты и методы из этого класса с помощью «Component.XXXX» в другом месте кода.Вот пример из другого модуля в файле "xlam":

Public Function FindCnfg(pTerm As String, pSearchBy As SearchBy) As Range
  Dim lTable As ListObject, _
      lRow As Range, _
      lCol As Long
  On Error GoTo ErrorHandling
  Set FindCnfg = Nothing
  Set lTable = Components.TableConfig  
  If lTable.DataBodyRange Is Nothing Then
    Exit Function
  End If
  Select Case pSearchBy
    Case SearchBy.ID
      lCol = 1
    Case SearchBy.Key
      lCol = 2
    Case Else
      RaiseError ErrorCode.INVALID_PARAM
  End Select
  Set lRow = lTable.DataBodyRange.Columns(lCol).Find(What:=pTerm, LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows)
  If Not lRow Is Nothing Then
    Set lRow = lRow.EntireRow
    Set FindCnfg = lRow
  End If
ErrorHandling:
  Set lTable = Nothing
  Set lRow = Nothing
  If Err.Number <> 0 Then
    RaiseError Err.Number, "FindCnfg", Err.Description
  End If
End Function

Я везде ловлю ошибки, используя "On Error GoTo X".

Все работает хорошо при нормальных обстоятельствах и событияхобрабатываются.

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

Он снова работает, еслиЯ вручную захожу в инструмент разработчика и запускаю метод, который ссылается на «Компонент».

Я подозреваю, что проблема связана с инициализацией предварительно объявленного объекта «Компонент».

Кто-нибудь есть идеи о том, как предотвратить эти спорадические нестабильности?Возможно, другой подход, который гарантирует, что объект «Компонент» всегда доступен.

1 Ответ

0 голосов
/ 19 марта 2019

Кажется, проблема связана с несколькими основными причинами.1- Глобальные переменные становятся неопределенными.2- В Office 2016 есть несколько ошибок, в том числе в Workbooks.Open (который я использую в своем коде).

Чтобы разрешить 1, я заменяю глобальную переменную функцией, которая возвращает переменную, и использую эту функцию вместоглобальная переменная:

Private lComponents As Components

Function MyComponents() As Components
  If lComponents Is Nothing Then
    Set lComponents = New Components
  End If
  Set MyComponents = lComponents
End Function

Для разрешения 2 не присваивайте возвращаемое значение Workbooks.Open какой-либо переменной.Вместо этого вызовите Workbooks.Open, а затем назначьте переменную для Workbooks (nameOfWB):

Workbooks.Open Filename:=lPath
Set WB = Workbooks(nameOfWB) 

Эти два изменения значительно улучшили стабильность.У меня больше нет случайных ошибок из-за неопределенных переменных.

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