Использование UDF в Excel для обновления листа

52

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

На SO (и на многих других форумах) было много вопросов по принципу "что не так с моей пользовательской функцией", где ответ был "вы не можете обновить листок из UDF" - это ограничение, описанное здесь:

Описание ограничений пользовательских функций в Excel

Существует несколько способов, которые были описаны для преодоления этого, например, см. здесь (https://sites.google.com/site/e90e50/excel-formula-to-change-the-value-of-another-cell), но я не думаю, что мой точный подход среди них.

Смотрите также: изменение комментариев ячейки из UDF

  • 1
    Очень интересно ....... когда я пытался перейти с красного на желтый, я получил Excel, чтобы рухнуть !!
Теги:
excel-vba
excel

2 ответа

49
Лучший ответ

Отправка ответа, чтобы я мог отметить свой "вопрос" как ответ.

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

Sub ChangeIt(c1 As Range, c2 As Range)
    c1.Value = c2.Value
    c1.Interior.Color = IIf(c1.Value > 10, vbRed, vbYellow)
End Sub


'########  run as a UDF, this actually changes the sheet ##############
' changing value in c2 updates c1...
Function SetIt(src, dest)

    dest.Parent.Evaluate "Changeit(" & dest.Address(False, False) & "," _
                        & src.Address(False, False) & ")"

    SetIt = "Changed sheet!" 'or whatever return value is useful...

End Function

Пожалуйста, напишите дополнительные ответы, если у вас есть интересные приложения для этого, которые вы хотели бы поделиться.

Примечание: Неподтверждено в каком-либо реальном приложении для производства.

  • 7
    Кто-нибудь знает, почему это работает? Я имею в виду серьезно, это колдовство.
  • 0
    Я протестировал его на Win 7 HB, Excel 2003, значения изменились нормально, но цветное форматирование не работает .. Также есть еще один обходной путь - см. Часть 2 ответа http://stackoverflow.com/a / 23232311/2165759
Показать ещё 5 комментариев
12

Недопустимый MSDN KB.

В нем говорится

Пользовательская функция, вызываемая формулой в ячейке рабочего листа, не может изменить среду Microsoft Excel. Это означает, что такая функция не может выполнять одно из следующих действий:

  • Вставить, удалить или форматировать ячейки в электронной таблице.
  • Изменить другое значение ячейки.
  • Перемещение, переименование, удаление или добавление листов в книгу.
  • Измените любые параметры среды, такие как режим расчета или виды экрана.
  • Добавить имена в книгу.
  • Установить свойства или выполнить большинство методов.

В приведенном ниже коде вы можете легко увидеть точки 1, 2,4 и 5.

Function SetIt(RefCell)
    RefCell.Parent.Evaluate "SetColor(" & RefCell.Address(False, False) & ")"
    RefCell.Parent.Evaluate "SetValue(" & RefCell.Address(False, False) & ")"
    RefCell.Parent.Evaluate "AddName(" & RefCell.Address(False, False) & ")"

    MsgBox Application.EnableEvents
    RefCell.Parent.Evaluate "ChangeEvents(" & RefCell.Address(False, False) & ")"
    MsgBox Application.EnableEvents

    SetIt = ""
End Function

'~~> Format cells on the spreadsheet.
Sub SetColor(RefCell As Range)
    RefCell.Interior.ColorIndex = 3 '<~~ Change color to red
End Sub

'~~> Change another cell value.
Sub SetValue(RefCell As Range)
   RefCell.Offset(, 1).Value = "Sid"
End Sub

'~~> Add names to a workbook.
Sub AddName(RefCell As Range)
   RefCell.Name = "Sid"
End Sub

'~~> Change events
Sub ChangeEvents(RefCell As Range)
    Application.EnableEvents = False
End Sub

Изображение 3746

  • 1
    Просто ради спора - можно ли утверждать, что КБ верен, поскольку UDF оценивает / вызывает Sub, который на самом деле делает изменения ...?
  • 1
    Тогда для обсуждения: P KB должен сказать, что ясно. However the above/below can be achieved using Evalute/Calling a Sub вместо того, чтобы выдавать However the above/below can be achieved using Evalute/Calling a Sub утверждение, that such a function cannot do any of the following.... @ MacRoman
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню