Ошибки в полях со списком ActiveX в Excel?

Я заметил, что получаю всевозможные досадные ошибки, когда:

  • У меня есть поля со списком ActiveX на листе (не в форме Excel)
  • Комбинированные списки имеют связанный с ними код события (например, события onchange).
  • Я использую их свойства listfillrange или connectedcell (очистка этих свойств, похоже, решает множество проблем)
  • (Не уверен, что это связано), но есть проверка данных на целевой связанной ячейке.

Я программирую довольно сложное приложение Excel, которое выполняет множество операций по обработке событий и использует множество элементов управления. В течение нескольких месяцев я пытался исправить множество ошибок, связанных с этими полями со списком. Я не могу вспомнить все детали каждого экземпляра сейчас, но эти ошибки, как правило, связаны с указанием свойств listfillrange и connectedcell в именованных диапазонах и часто связаны с событиями поля со списком, запускаемыми в неподходящее время (например, когда application.enableevents = ложь). Эти проблемы, казалось, стали еще больше в Excel 2007, поэтому мне пришлось полностью отказаться от этих полей со списком (теперь я использую поля со списком, содержащиеся в пользовательских формах, а не непосредственно на листах).

Кто-нибудь еще видел подобные проблемы? Если да, то было ли изящное решение? Я поискал в Google и до сих пор не нашел никого с подобными проблемами.

Вот некоторые из симптомов, которые я вижу:

  • Сбой Excel при запуске (включает combobox_onchange, listfillrange-> именованный диапазон на другом листе и взаимодействия workbook_open). (обратите внимание, у меня также была некоторая проверка данных в связанных ячейках на случай, если пользователь отредактировал их напрямую.)
  • Ошибки рендеринга в Excel (обычно при изменении поля со списком некоторые ячейки из другого листа случайным образом отображаются поверх текущего листа) Иногда это связано с тем, что экран полностью мигает на другой лист на мгновение.
  • Excel теряет рассудок (точнее, стек вызовов) (относящийся к первому пункту маркера). Иногда, когда функция изменяет свойство полей со списком, возникает событие onchange со списком, но оно никогда не возвращает управление функции, которая изначально вызвала изменение. События combobox_onchange запускаются, даже если application.enableevents = false.
  • События срабатывают, когда они не должны (я опубликовал еще один вопрос о переполнении стека, связанный с этим).

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


person Kimball Robinson    schedule 25.02.2010    source источник
comment
Разве это не ошибка в вашем коде, а не в Excel?   -  person Mitch Wheat    schedule 25.02.2010
comment
Митч: Я тщательно выполнил код. Это определенно проблемы Excel. Когда я сказал, что Excel отбрасывает стек функций, я действительно не могу объяснить это по-другому. И Excel не должен давать сбоев, как бы плохо ни работали чьи-то макросы.   -  person Kimball Robinson    schedule 25.02.2010
comment
Митч, если вы хотите увидеть один из примеров ошибки, которую я гораздо более тщательно документировал и виню в Excel, см. stackoverflow.com/questions/1263394/ - я не вдавался в подробности подробнее здесь, потому что я подозреваю, что есть более общая проблема с выпадающими списками activex.   -  person Kimball Robinson    schedule 25.02.2010


Ответы (5)


У меня нет для вас окончательного ответа, но могу сказать, что я прекратил использовать ListFillRange и LinkedCell для элементов управления ActiveX около 10 лет назад. Не помню, с какими именно проблемами я столкнулся. Я просто помню, как пришел к выводу, что то небольшое время, которое они сэкономили мне, не стоит того, чтобы ломать голову над попытками выследить ошибки. Итак, теперь я заполняю элементы управления с помощью кода и обрабатываю вывод событий.

person Dick Kusleika    schedule 25.02.2010

Мое поле со списком active-x отлично работает, когда мой Dell подключен к док-станции, но меняет размер на более крупный шрифт каждый раз, когда он щелкает, когда Dell отстыкован - очень странно. Я добавил код изменения размера, который работает при отстыковке, но и .height, и .scaleheight не работают при стыковке и при программном запуске (что еще более странно).

        Sheet2.Shapes("cb_SelectSKU").Select
        Selection.ShapeRange.Height = 40
        Selection.ShapeRange.ScaleHeight 0.8, msoFalse, msoScaleFromTopLeft

Затем я добавил свой собственный переключатель, похожий на enableevents, чтобы изменение размера происходило только тогда, когда пользователь выбирает значение поля со списком, а не когда что-либо затрагивается во время выполнения макроса.

Select Case strHoldEvents
    Case Is = "N"                                                   'Combobox resizing fails with error when triggered programatically (from SaveData)

        Call ShowLoadShts

        Sheet2.Shapes("cb_SelectSKU").Select
        Selection.ShapeRange.Height = 40
        Selection.ShapeRange.ScaleHeight 0.8, msoFalse, msoScaleFromTopLeft


    Case Else
End Select

Наконец, кажется, что это работает, будь то пристыковка или отстыковка, запускаемая пользователем или во время процедуры. Посмотрим, держится ли ...

person mike    schedule 30.11.2010

У меня есть частичный ответ для пользователей Dell и вашей проблемы с форматированием

Проблема форматирования и отображения - еще одна известная, но недокументированная проблема в Excel.

Многие плоские мониторы (включая дисплеи ноутбуков) не могут правильно отображать шрифты в элементах управления текстовыми полями в электронной таблице Excel: у вас есть умеренная версия этой проблемы.

Наша компания недавно перешла на новые (и намного более крупные!) Мониторы, и я могу наконец использовать текстовые поля, метки и поля со списком на листах. На наших старых экранах Samsung текстовые элементы управления отображались правильно, но любые обновления, выполняемые вручную или с помощью VBA, приводили к неразборчивому набору перекрывающихся символов.

У списков нет проблемы: проблема есть в части «текстового поля» вашего поля со списком. Попробуйте управлять списком в процедурах обработки событий VBA: это кладж, но он работает.

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

Иногда проблема решается (но никогда полностью не решается) с помощью шрифтов терминала или системы в элементе управления Active-X.

Иногда проблема решается (но никогда полностью не решается) с помощью события VBA для смещения или изменения размера элемента управления Active-X на 0,75 мм.

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

... И это все, что я знаю о проблеме рендеринга шрифтов. Если Майк (со своим ноутбуком Dell) читает это: удачи с этими обходными путями - насколько мне известно, настоящего «исправления» нет.

Проблема стабильности была для меня большой головной болью, пока не вышел Excel 2003: использование любого элемента управления Active-X на листе было источником нестабильности. Жюри по-прежнему не рассматривает элементы управления Listbox, встроенные в лист, даже в Excel 2003: я все еще избегаю их использования.

person Nigel Heffernan    schedule 02.12.2010

Итак, я столкнулся с теми же проблемами. У меня был файл с раскрывающимися списками, на который я наложил поле со списком, чтобы решить проблему неразборчивости при слишком большом уменьшении масштаба. Вот как мой код выглядел ПЕРВОНАЧАЛЬНО:

'=========================================
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim str As String
Dim cboTemp As OLEObject
Dim ws As Worksheet
Set ws = ActiveSheet
On Error GoTo errHandler

If Target.Count > 1 Then GoTo exitHandler

Set cboTemp = ws.OLEObjects("ComboBox1")
  On Error Resume Next
If cboTemp.Visible = True Then
  With cboTemp
    .Top = 10
    .Left = 10
    .ListFillRange = "Treatment"
    .LinkedCell = Target.Address
    .Visible = False
    .Value = ""
  End With
End If



  On Error GoTo errHandler
  If Target.Validation.Type = 3 Then
    'if the cell contains a data validation list
    Application.EnableEvents = False
    'get the data validation formula
    str = Target.Validation.Formula1
    str = Right(str, Len(str) - 1)
    With cboTemp
      'show the combobox with the list
      .Visible = True
      .Left = Target.Left
      .Top = Target.Top
      .Width = Target.Width + 15
      .Height = Target.Height + 5
      .ListFillRange = ws.Range(str).Address
      .LinkedCell = Target.Address
    End With
    cboTemp.Activate
    'open the drop down list automatically
    Me.ComboBox1.DropDown
  End If

exitHandler:
  Application.ScreenUpdating = True
  Application.EnableEvents = True
  Exit Sub
errHandler:
  Resume exitHandler

End Sub
'====================================
'Optional code to move to next cell if Tab or Enter are pressed
'from code by Ted Lanham
'***NOTE: if KeyDown causes problems, change to KeyUp
'Table with numbers for other keys such as Right Arrow (39)
'https://msdn.microsoft.com/en-us/library/aa243025%28v=vs.60%29.aspx

Private Sub ComboBox1_KeyDown(ByVal _
        KeyCode As MSForms.ReturnInteger, _
        ByVal Shift As Integer)
    Select Case KeyCode
        Case 9 'Tab
            ActiveCell.Offset(0, 1).Activate
        Case 13 'Enter
            ActiveCell.Offset(1, 0).Activate
        Case Else
            'do nothing
    End Select
End Sub
'====================================

Я столкнулся со всевозможными проблемами, но, как в первую очередь упоминалось в этой теме, проблема LinkedCell была самой большой. Мой выбор из раскрывающегося меню будет идти туда, где на листе, который я щелкнул последним, вместо ячейки, из которой я выбрал раскрывающийся список, и в процессе, также нарушая код того места, где будет происходить выбор. Я использовал простой код ОДНОЙ СТРОКИ, чтобы убедиться, что моя программа в ActiveX запускается только в раскрывающемся меню. Я использовал это до запуска команды LinkedCell:

If Target.Validation.Type = 3 Then
'... all the normal code here...
End If

Итак, мой код теперь выглядит так:

'... Code as before

If Target.Validation.Type = 3 Then
' NEW CODE LINE ABOVE
 If Target.Count > 1 Then GoTo exitHandler

Set cboTemp = ws.OLEObjects("ComboBox1")
  On Error Resume Next
If cboTemp.Visible = True Then
  With cboTemp
    .Top = 10
    .Left = 10
    .ListFillRange = "Treatment"
    .LinkedCell = Target.Address
    .Visible = False
    .Value = ""
  End With
End If
End If
' End of the new If

Невероятно, но это сработало. И теперь моя таблица Excel больше не ведет себя плохо. Надеюсь это поможет.

person Sampat Kedarisetty    schedule 01.12.2017

По этой причине я использую ячейки со списками проверки данных при добавлении полей со списком в электронную таблицу.

person guitarthrower    schedule 25.02.2010
comment
Я хотел избежать списков проверки данных, потому что шрифт часто слишком мал для большинства пользователей, чтобы хорошо видеть, и они не могут отображать несколько столбцов (что необходимо в этом случае). - person Kimball Robinson; 27.02.2010
comment
Верно для нескольких столбцов. Что касается размера текста, он может быть довольно маленьким, но, по крайней мере, он масштабируется до размера увеличения. Время от времени у меня были проблемы с Active X, потому что раскрывающийся текст не масштабируется с увеличением, и пользователи жаловались. - person guitarthrower; 27.02.2010