2015-01-12 2 views
3

У меня есть 2 листа с 3 UDF в первом и 2 во втором.UDF на разных листах, вызывающих ошибку возврата друг друга 2015

  • лист 1 представляет собой ежемесячную матрицу с 1 столбиком на каждый день, когда люди кладут в свои часы по рядам внизу. В 3 определенных строках есть UDF, которые объединяют данные в столбце выше, ссылаясь на строку в качестве аргумента. Я вызов функции, как показано ниже, чтобы избежать того, чтобы сделать ОДС энергозависимого (что продлевает время вычисления значительно, если у меня), поэтому обновление результатов ОДСА, когда какие-либо изменения в колонке R:

    calculateOvertime(R:R) 
    
  • На листе 2, дни месяца находятся в строках (а не в столбцах), где можно подробно рассказать о своем дне, если бы они делали сверхурочную работу. Это обнаруживается один из ОДС в листе 1, так что 2 ОДС здесь требуются данные, рассчитанные с помощью UDF в листе 1

У меня есть некоторые странные проблемы с этой установкой:

  • Для по какой-то причине, когда я переключаю вкладки, все ячейки, содержащие любую из этих функций, отображаются как #VALUE !. Я должен добавить «Application.CalculateFull» в обработчик событий, который выстреливает всякий раз, когда вкладка активирована: «! 2015»

    Private Sub Worksheet_activate() 
        Application.CalculateFull 
    End Sub 
    
  • ОДС о том, что ссылки на ячейку, содержащую другой UDF на вкладке другой, всегда будет получать в качестве значения, ссылаясь на ошибку 2015 (ошибку значения, потому что ячейка содержит #VALUE! когда лист не активен)

Очевидно, что эти 2 проблем связаны, потому что, когда я переложить листы, ОДС рассчитанные значения в неактивном листе как-то теряются.

Мой метод получения значения из ячейки заключается в следующем. Я выяснить, на какой строке метка в столбце А с помощью функции

Dim compensationRowIndex As Integer 
compensationRowIndex = CInt(othersheet.Range("A1:A250").Find("COMPENSATION").Row) 

Find(), то я получить значение и привести его к одному

Dim compensation As Single 
compensation = CSng(othersheet.Cells(compensationRowIndex , columnIndex).Value) 

в «компенсации» переменной имеет место ценность 2015 всегда.

Есть ли способ обойти это? Также, когда я хочу распечатать листы, все ячейки, содержащие UDF, заполняются #VALUE !. Мое предположение: если я могу сделать проблему 1 уйти, то выйдет 2.

ЛЮБАЯ помощь в этом очень ценится. Я пытался устранить эту проблему почти целый день и не нашел решения, которое искал симптомы.

+2

'#######' означает, что в ячейке недостаточно места для отображения. Попытайтесь увеличить размер столбца, чтобы он исчез. – Chrismas007

+0

Ваши * UDFs * ** Летучие ** ** –

+0

@ Gary'sStudent ссылается на http://www.mrexcel.com/forum/excel-questions/271165-udf-volatile-vs-not.html – Chrismas007

ответ

0

Проблема решена!

«ActiveSheet» внутри UDF не означает «Лист, содержащий ячейку, содержащую UDF». Это буквально означает «активный лист».

При обращении к UDF на листе анотера все идет ужасно неправильно. Все дело в замене ActiveSheet на переменную, установленную в инструкции If, которая решает, откуда вызывается UDF. В моем случае второй лист всегда имеет в нем слово «Информация».Когда на этом листе, вы должны пойти на один лист влево:

Dim ws As Worksheet 

If InStr(ActiveSheet.Name, "Info") = 0 Then 
    Set ws = ActiveSheet 
Else 
    Set ws = Worksheets(ActiveSheet.Index - 1) 
End If 

Не на 100% водонепроницаемый раствор (например, что если кто-то перестраивает листы), но для моих целей это достаточно близко.

0

Следующий фрагмент кода (используется в ОДС) должны делать то, что вы хотите:

Dim ws As Worksheet 

If TypeOf Application.Caller Is Range Then 
    Set ws = Application.Caller.Parent 
End If 

Caller свойство Application объекта указывает на Range покрытия ячейки (ов), где UDF был вызван из , Затем ws укажет на содержащий лист.
Предложение If TypeOf позволяет избежать ошибок в случае, если функция была вызвана чем-то другим, чем UDF (например, другая процедура VBA), где Caller не может указывать на объект Range. В этом случае ws остается неназначенным (Nothing).